예제 #1
0
/*! 
 * generic_cf_modexit() - module init
 *
 * This is called by the Linux kernel; when the module is being unloaded 
 * if compiled as a module. This function is never called if the 
 * driver is linked into the kernel.
 *
 * @param void
 * @return void
 */
static void generic_cf_modexit (void)
{
        int i;
        otg_trace_invalidate_tag(GENERIC);
        for (i = 0; ; i++) {
                struct generic_config *config = generic_configs + i;

                BREAK_UNLESS(config->interface_names);

                //printk(KERN_INFO"%s: %s registered: %d\n", 
                //                __FUNCTION__, config->composite_driver.driver.name, config->registered);

                CONTINUE_UNLESS(config->registered);

                usbd_deregister_composite_function (&config->composite_driver);

                if (config->interface_list)
                        LKFREE(config->interface_list);
        }

        if (generic_config.registered)
                usbd_deregister_composite_function (&generic_config.composite_driver);

        if (generic_config.interface_list) 
                LKFREE(generic_config.interface_list);
}
예제 #2
0
/*! arc_udc_init
 */
static struct arcotg_udc *arc_udc_init (struct otg_dev *otg_dev)
{
        struct device           *device = otg_dev_get_drvdata(otg_dev);
        struct platform_device  *pdev = to_platform_device(device);

        struct fsl_usb2_platform_data *pdata = (struct fsl_usb2_platform_data*)pdev->dev.platform_data;

        struct otg_instance     *otg = otg_dev->otg_instance;
        struct pcd_instance     *pcd = otg_dev->pcd_instance;
        struct arcotg_udc       *udc = NULL;
        int                     timeout;


        /* Setting up the udc structure */
        THROW_UNLESS((udc = (struct arcotg_udc *) CKMALLOC(sizeof(struct arcotg_udc))), error);

        /* Allocate queue */
        THROW_UNLESS((udc->ep_qh = (struct ep_queue_head *) KMALLOC_ALIGN(    USB_MAX_PIPES * sizeof(struct ep_queue_head),
                                        GFP_KERNEL | GFP_DMA, 2 * 1024, (void **)&ep_qh_base)), error);
        THROW_UNLESS(ep_qh_base, error);
        THROW_UNLESS((udc->ep_dtd = (struct ep_td_struct *) CKMALLOC(USB_MAX_PIPES * sizeof(struct ep_td_struct))), error);

        /* Stop, reset and wait for the UDC to reset */
        UOG_USBCMD &= ~USB_CMD_RUN_STOP;
        UOG_USBCMD |= USB_CMD_CTRL_RESET;

        timeout = 10000000;     // XXX This needs to be fixed, should not need to resort to timeout
        while ((UOG_USBCMD & USB_CMD_CTRL_RESET) && --timeout) { continue; }
        if (timeout == 0) {
                printk(KERN_DEBUG "%s: TIMEOUT\n", __FUNCTION__);
                return NULL;
        }

        /* Setup UDC mode and disable lock out mode*/
        UOG_USBMODE |= USB_MODE_CTRL_MODE_DEVICE | USB_MODE_SETUP_LOCK_OFF;

        UOG_EPLISTADDR = virt_to_phys(udc->ep_qh);
        UOG_EPLISTADDR &= USB_EP_LIST_ADDRESS_MASK;

        /* Setup transceiver type, N.B. this must be done in one assignment */
        UOG_PORTSC1 = (UOG_PORTSC1 & ~PORTSCX_PHY_TYPE_SEL) | pdata->xcvr_type;

        #if !defined(CONFIG_OTG_HIGH_SPEED)
        UOG_PORTSC1 |= (0x01000000);
        #endif
	fsl_platform_set_vbus_power(pdata, 0);

        CATCH(error) {
                if (ep_qh_base) kfree(ep_qh_base);
                if (udc) {
                        if (udc->ep_dtd) LKFREE(udc->ep_dtd);
                        LKFREE(udc);
                }
                udc = NULL;
        }
        return udc;
}
예제 #3
0
/*! arc_udc_init
 */
void arc_udc_release (void)
{
        kfree(ep_qh_base);
        ep_qh_base = NULL;
        if (udc_controller) {
              if (udc_controller->ep_dtd) LKFREE(udc_controller->ep_dtd);
              LKFREE(udc_controller);
               udc_controller = NULL;
        }
}
예제 #4
0
/*! otg_tasklet_init
 * Create otg task structure, create workqueue, initialize it.
 * @param name - otg_tasklet name
 * @param proc - otg_tasklet process
 * @param data - otg_taskle data, argument for proc
 * @param tag - otg_tasklet tag
 * @return initialized otg_tasklet instance pointer
 */
static inline struct otg_tasklet *otg_tasklet_init(char *name, otg_tasklet_proc_t proc, otg_tasklet_arg_t data, otg_tag_t tag)
{
        struct otg_tasklet *tasklet;

        //TRACE_STRING(tag, "INIT: %s", name);
        //printk(KERN_INFO"%s: %s\n", __FUNCTION__, name);

        RETURN_NULL_UNLESS((tasklet = CKMALLOC(sizeof (struct otg_tasklet))));

        tasklet->tag = tag;
        tasklet->name = name;
        tasklet->terminated = TRUE;
        tasklet->proc = proc;
        tasklet->data = data;

        #ifdef OTG_TASKLET_WORK
        INIT_WORK(&tasklet->work, otg_tasklet_run, tasklet);
        #else /* OTG_TASKLET_WORK */
        tasklet_init(&tasklet->tasklet, otg_tasklet_run, (otg_tasklet_arg_t) tasklet);
        #endif /* OTG_TASKLET_WORK */

        return tasklet;

        CATCH(error) {
                if (tasklet) LKFREE(tasklet);
                return NULL;
        }
}
예제 #5
0
/*! otg_workitem_init
 * Create otg work structure, create workqueue, initialize it.
 * @param name - workitem name
 * @param proc - workitem handler
 * @param data - workitem data
 * @param tag - otg tag
 * @return otg_workitem instance pointer
 */
static inline struct otg_workitem *otg_workitem_init(char *name, otg_workitem_proc_t proc, otg_workitem_arg_t data, otg_tag_t tag)
{
        struct otg_workitem *workitem;

        //TRACE_STRING(tag, "INIT: %s", name);

        //printk(KERN_INFO"%s: %s\n", __FUNCTION__, name);

        RETURN_NULL_UNLESS((workitem = CKMALLOC(sizeof (struct otg_workitem))));

        workitem->data = data;
        workitem->tag = tag;
        workitem->name = name;
        workitem->proc = proc;
        //workitem->debug = TRUE;

        workitem->terminated = workitem->terminate = TRUE;

        INIT_WORK(&workitem->work, otg_workitem_run, workitem);

        return workitem;

        CATCH(error) {
                printk(KERN_INFO"%s: ERROR\n", __FUNCTION__);
                if (workitem) LKFREE(workitem);
                return NULL;
        }
}
예제 #6
0
/*! otg_workitem_exit
 * Terminate and wait for otg work.
 * @param workitem - workitem pointer
 */
static void inline otg_workitem_exit(struct otg_workitem *workitem)
{
        //TRACE_STRING(workitem->tag, "EXIT: %s", workitem->name);
        if (workitem->debug)
                printk(KERN_INFO"%s: %s terminating\n", __FUNCTION__, workitem->name);

        while (!workitem->terminated) {
                otg_sleep( 1 );
        }

        if (workitem->debug)
                printk(KERN_INFO"%s: %s terminated\n", __FUNCTION__, workitem->name);

        LKFREE(workitem);
}
예제 #7
0
/*! otg_tasklet_exit
 * Terminate and wait for otg task.
 * @param tasklet - otg_tasklet instance pointer
 */
static void inline otg_tasklet_exit(struct otg_tasklet *tasklet)
{
        //TRACE_STRING(tag, "EXIT: %s", name);
        if (tasklet->debug)
                printk(KERN_INFO"%s: %s\n", __FUNCTION__, tasklet->name);

        #ifdef OTG_TASKLET_WORK
        while (!tasklet->terminated) {
                if (tasklet->debug)
                        printk(KERN_INFO"%s: SLEEPING\n", __FUNCTION__);
                otg_sleep( 1 );
                if (tasklet->debug)
                        printk(KERN_INFO"%s: RUNNING\n", __FUNCTION__);
        }
        #else /* OTG_TASKLET_WORK */
        tasklet_kill(&tasklet->tasklet);
        #endif /* OTG_TASKLET_WORK */

        LKFREE(tasklet);
}
예제 #8
0
/*! otg_task_exit
 * Terminate and wait for otg task.
 * @param task - otg_task instance pointer
 */
void otg_task_exit(struct otg_task *task)
{
        TRACE_STRING(task->tag, "EXIT: %s", task->name);
        if (task->debug)
                printk(KERN_INFO"%s: %s\n", __FUNCTION__, task->name);

        #if defined(OTG_TASK_WORK)
        while (!task->terminated) {
                otg_sleep( 1 );
        }
        #else /* defined(OTG_TASK_WORK) */
        /* signal termination */
        task->terminate = TRUE;
        otg_up_work(task);
        otg_down_admin(task);

        /* destroy workqueue */
        flush_workqueue(task->work_queue);
        destroy_workqueue(task->work_queue);
        #endif /* defined(OTG_TASK_WORK) */

        LKFREE(task);
}
예제 #9
0
/*! otg_task_init
 *@brief Create otg task structure, create workqueue, initialize it.
 *@param name - name of task or workqueue
 *@param proc - handler
 *@param data - parameter pointer for handler
 *@param tag-
 *@return initialized otg_task instance pointer
 */
struct otg_task *otg_task_init2(char *name, otg_task_proc_t proc, otg_task_arg_t data, otg_tag_t tag)
{
        struct otg_task *task;

        //TRACE_STRING(tag, "INIT: %s", name);

        RETURN_NULL_UNLESS((task = CKMALLOC(sizeof (struct otg_task))));

        task->tag = tag;
        task->data = data;
        task->name = name;
        task->proc = proc;

        #if defined(OTG_TASK_WORK)
        task->terminated = task->terminate = TRUE;
        #else /* defined(OTG_TASK_WORK) */
        task->terminated = task->terminate = FALSE;
        #if defined(LINUX26)
        THROW_UNLESS((task->work_queue = create_singlethread_workqueue(name)), error);
        #else /* LINUX26 */
        THROW_UNLESS((task->work_queue = create_workqueue(name)), error);
        #endif /* LINUX26 */
        init_MUTEX_LOCKED(&task->admin_sem);
        init_MUTEX_LOCKED(&task->work_sem);
        #endif /* defined(OTG_TASK_WORK) */

        INIT_WORK(&task->work, otg_task_proc, task);

        return task;

        CATCH(error) {
                printk(KERN_INFO"%s: ERROR\n", __FUNCTION__);
                if (task) LKFREE(task);
                return NULL;
        }
}