void cy_as_hal_sleep(uint32_t ms)
{
	cy_as_hal_sleep_channel channel;

	cy_as_hal_create_sleep_channel(&channel) ;
	cy_as_hal_sleep_on(&channel, ms) ;
	cy_as_hal_destroy_sleep_channel(&channel) ;
}
Ejemplo n.º 2
0
/* west bridge device driver main init */
static int cyasdevice_initialize(void)
{
    cyasdevice *cy_as_dev = 0;
    int		 ret	= 0;
    int		 retval = 0;
    cy_as_device_config config;
    cy_as_hal_sleep_channel channel;
    cy_as_get_firmware_version_data ver_data = {0};
    const char *str = "";
    int spin_lim;
    const struct firmware *fw_entry;

    cy_as_device_init_done = 0;

    cy_as_misc_set_log_level(8);

    cy_as_hal_print_message("<1>_cy_as_device initialize called\n");

    if (cy_as_device_controller != 0) {
        cy_as_hal_print_message("<1>_cy_as_device: the device "
                                "has already been initilaized. ignoring\n");
        return -EBUSY;
    }

    /* cy_as_dev = CyAsHalAlloc (sizeof(cyasdevice), SLAB_KERNEL); */
    cy_as_dev = cy_as_hal_alloc(sizeof(cyasdevice));
    if (cy_as_dev == NULL) {
        cy_as_hal_print_message("<1>_cy_as_device: "
                                "memory allocation failed\n");
        return -ENOMEM;
    }
    memset(cy_as_dev, 0, sizeof(cyasdevice));


    /* Init the HAL & CyAsDeviceHandle */

#ifdef CONFIG_MACH_OMAP3_WESTBRIDGE_AST_PNAND_HAL
    /* start OMAP HAL init instsnce */

    if (!start_o_m_a_p_kernel(dev_handle_name,
                              &(cy_as_dev->hal_tag), cy_false)) {

        cy_as_hal_print_message(
            "<1>_cy_as_device: start OMAP34xx HAL failed\n");
        goto done;
    }
#endif

    /* Now create the device */
    if (cy_as_misc_create_device(&(cy_as_dev->dev_handle),
                                 cy_as_dev->hal_tag) != CY_AS_ERROR_SUCCESS) {

        cy_as_hal_print_message(
            "<1>_cy_as_device: create device failed\n");
        goto done;
    }

    memset(&config, 0, sizeof(config));
    config.dmaintr = cy_true;

    ret = cy_as_misc_configure_device(cy_as_dev->dev_handle, &config);
    if (ret != CY_AS_ERROR_SUCCESS) {

        cy_as_hal_print_message(
            "<1>_cy_as_device: configure device "
            "failed. reason code: %d\n", ret);
        goto done;
    }

    ret = cy_as_misc_register_callback(cy_as_dev->dev_handle,
                                       cy_misc_callback);
    if (ret != CY_AS_ERROR_SUCCESS) {
        cy_as_hal_print_message("<1>_cy_as_device: "
                                "cy_as_misc_register_callback failed. "
                                "reason code: %d\n", ret);
        goto done;
    }

    ret = platform_driver_register(&west_bridge_driver);
    if (unlikely(ret < 0))
        return ret;
    westbridge_pd = platform_device_register_simple(
                        "west_bridge_dev", -1, NULL, 0);

    if (IS_ERR(westbridge_pd)) {
        platform_driver_unregister(&west_bridge_driver);
        return PTR_ERR(westbridge_pd);
    }
    /* Load the firmware */
    ret = request_firmware(&fw_entry,
                           "west bridge fw", &westbridge_pd->dev);
    if (ret) {
        cy_as_hal_print_message("cy_as_device: "
                                "request_firmware failed return val = %d\n", ret);
    } else {
        cy_as_hal_print_message("cy_as_device: "
                                "got the firmware %d size=0x%x\n", ret, fw_entry->size);

        ret = cy_as_misc_download_firmware(
                  cy_as_dev->dev_handle,
                  fw_entry->data,
                  fw_entry->size ,
                  0, 0);
    }

    if (ret != CY_AS_ERROR_SUCCESS) {
        cy_as_hal_print_message("<1>_cy_as_device: cannot download "
                                "firmware. reason code: %d\n", ret);
        goto done;
    }

    /* spin until the device init is completed */
    /* 50 -MAX wait time for the FW load & init
     * to complete is 5sec*/
    spin_lim = 50;

    cy_as_hal_create_sleep_channel(&channel);
    while (!cy_as_device_init_done) {

        cy_as_hal_sleep_on(&channel, 100);

        if (spin_lim-- <= 0) {
            cy_as_hal_print_message(
                "<1>\n_e_r_r_o_r!: "
                "wait for FW init has timed out !!!");
            break;
        }
    }
    cy_as_hal_destroy_sleep_channel(&channel);

    if (spin_lim > 0)
        cy_as_hal_print_message(
            "cy_as_device: astoria firmware is loaded\n");

    ret = cy_as_misc_get_firmware_version(cy_as_dev->dev_handle,
                                          &ver_data, 0, 0);
    if (ret != CY_AS_ERROR_SUCCESS) {
        cy_as_hal_print_message("<1>_cy_as_device: cannot get firmware "
                                "version. reason code: %d\n", ret);
        goto done;
    }

    if ((ver_data.media_type & 0x01) && (ver_data.media_type & 0x06))
        str = "nand and SD/MMC.";
    else if ((ver_data.media_type & 0x01) && (ver_data.media_type & 0x08))
        str = "nand and CEATA.";
    else if (ver_data.media_type & 0x01)
        str = "nand.";
    else if (ver_data.media_type & 0x08)
        str = "CEATA.";
    else
        str = "SD/MMC.";

    cy_as_hal_print_message("<1> cy_as_device:_firmware version: %s "
                            "major=%d minor=%d build=%d,\n_media types supported:%s\n",
                            ((ver_data.is_debug_mode) ? "debug" : "release"),
                            ver_data.major, ver_data.minor, ver_data.build, str);

    spin_lock_init(&cy_as_dev->common_lock);

    /* done now */
    cy_as_device_controller = cy_as_dev;

    return 0;

done:
    if (cy_as_dev)
        cyasdevice_deinit(cy_as_dev);

    return -EINVAL;
}
Ejemplo n.º 3
0
/*
* Wait for all entries in the DMA queue associated
* the given endpoint to be drained.  This function
* will not return until all the DMA data has been
* transferred.
*/
cy_as_return_status_t
cy_as_dma_drain_queue(cy_as_device *dev_p,
	cy_as_end_point_number_t ep, cy_bool kickstart)
{
	cy_as_dma_end_point *ep_p ;
	int loopcount = 200 ;
	uint32_t mask ;

	/*
	* make sure the endpoint is valid
	*/
	if (ep >= sizeof(dev_p->endp)/sizeof(dev_p->endp[0]))
		return CY_AS_ERROR_INVALID_ENDPOINT ;

	/* Get the endpoint pointer based on the endpoint number */
	ep_p = CY_AS_NUM_EP(dev_p, ep) ;

	/*
	* if the endpoint is empty of traffic, we return
	* with success immediately
	*/
	mask = cy_as_hal_disable_interrupts() ;
	if (ep_p->queue_p == 0) {
		cy_as_hal_enable_interrupts(mask) ;
		return CY_AS_ERROR_SUCCESS ;
	} else {
		/*
		 * add 10 seconds to the time out value for each 64 KB segment
		 * of data to be transferred.
		 */
		if (ep_p->queue_p->size > 0x10000)
			loopcount += ((ep_p->queue_p->size / 0x10000) * 100) ;
	}
	cy_as_hal_enable_interrupts(mask) ;

	/* If we are already sleeping on this endpoint, it is an error */
	if (cy_as_dma_end_point_is_sleeping(ep_p))
		return CY_AS_ERROR_NESTED_SLEEP ;

	/*
	* we disable the endpoint while the queue drains to
	* prevent any additional requests from being queued while we are waiting
	*/
	cy_as_dma_enable_end_point(dev_p, ep,
		cy_false, cy_as_direction_dont_change) ;

	if (kickstart) {
		/*
		* now, kick start the DMA if necessary
		*/
		cy_as_dma_kick_start(dev_p, ep) ;
	}

	/*
	* check one last time before we begin sleeping to see if the
	* queue is drained.
	*/
	if (ep_p->queue_p == 0) {
		cy_as_dma_enable_end_point(dev_p, ep, cy_true,
			cy_as_direction_dont_change) ;
		return CY_AS_ERROR_SUCCESS ;
	}

	while (loopcount-- > 0) {
		/*
		 * sleep for 10 ms maximum (per loop) while
		 * waiting for the transfer to complete.
		 */
		cy_as_dma_end_point_set_sleep_state(ep_p) ;
		cy_as_hal_sleep_on(&ep_p->channel, 10) ;

		/* If we timed out, the sleep bit will still be set */
		cy_as_dma_end_point_set_wake_state(ep_p) ;

		/* Check the queue to see if is drained */
		if (ep_p->queue_p == 0) {
			/*
			 * clear the endpoint running and in transit flags
			 * for the endpoint, now that its DMA queue is empty.
			 */
			cy_as_dma_end_point_clear_in_transit(ep_p) ;
			cy_as_dma_end_point_set_stopped(ep_p) ;

			cy_as_dma_enable_end_point(dev_p, ep,
				cy_true, cy_as_direction_dont_change) ;
			return CY_AS_ERROR_SUCCESS ;
		}
	}

	printk(KERN_ERR"cyasdevice:timeout 0xA0 = 0x%x\n",cy_as_hal_read_register(dev_p->tag,0xA0));
	printk(KERN_ERR"cyasdevice:timeout 0xA1 = 0x%x\n",cy_as_hal_read_register(dev_p->tag,0xA1));
	printk(KERN_ERR"cyasdevice:timeout 0xA2 = 0x%x\n",cy_as_hal_read_register(dev_p->tag,0xA2));
	printk(KERN_ERR"cyasdevice:timeout 0x90 = 0x%x\n",cy_as_hal_read_register(dev_p->tag,0x90));
	printk(KERN_ERR"cyasdevice:timeout 0x91 = 0x%x\n",cy_as_hal_read_register(dev_p->tag,0x91));
	/*
	 * the DMA operation that has timed out can be cancelled, so that later
	 * operations on this queue can proceed.
	 */
	cy_as_dma_cancel(dev_p, ep, CY_AS_ERROR_TIMEOUT) ;
	cy_as_dma_enable_end_point(dev_p, ep,
		cy_true, cy_as_direction_dont_change) ;
	return CY_AS_ERROR_TIMEOUT ;
}