Message ID | 1350642285-8145-3-git-send-email-chf.fritz@googlemail.com (mailing list archive) |
---|---|
State | Not Applicable |
Headers | show |
Hi, typo on Subject. Should be udc, not ulc. On Fri, Oct 19, 2012 at 12:24:41PM +0200, Christoph Fritz wrote: > Convert to new UDC style registration and remove > global 'udc_controller' pointer. > > Signed-off-by: Christoph Fritz <chf.fritz@googlemail.com> > --- > drivers/usb/gadget/fsl_udc_core.c | 289 +++++++++++++++++-------------------- > 1 files changed, 131 insertions(+), 158 deletions(-) > > diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c > index 0a0d6a6..d113f39 100644 > --- a/drivers/usb/gadget/fsl_udc_core.c > +++ b/drivers/usb/gadget/fsl_udc_core.c > @@ -63,9 +63,6 @@ static struct usb_dr_device *dr_regs; > > static struct usb_sys_interface *usb_sys_regs; > > -/* it is initialized in probe() */ > -static struct fsl_udc *udc_controller = NULL; > - > static const struct usb_endpoint_descriptor > fsl_ep0_desc = { > .bLength = USB_DT_ENDPOINT_SIZE, > @@ -783,12 +780,14 @@ static void fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req) > } > > /* Fill in the dTD structure > + * @udc: driver private data > * @req: request that the transfer belongs to > * @length: return actually data length of the dTD > * @dma: return dma address of the dTD > * @is_last: return flag if it is the last dTD of the request > * return: pointer to the built dTD */ > -static struct ep_td_struct *fsl_build_dtd(struct fsl_req *req, unsigned *length, > +static struct ep_td_struct *fsl_build_dtd(struct fsl_udc *udc, > + struct fsl_req *req, unsigned *length, > dma_addr_t *dma, int *is_last, gfp_t gfp_flags) I would split this patch a little. First I would patch the missing arguments to these functions under the excuse that a later patch will get rid of the udc_controller pointer, then the next patch would do the conversion to new style. It will be a lot easier to review ;-) > { > u32 swap_temp; > @@ -798,7 +797,7 @@ static struct ep_td_struct *fsl_build_dtd(struct fsl_req *req, unsigned *length, > *length = min(req->req.length - req->req.actual, > (unsigned)EP_MAX_LENGTH_TRANSFER); > > - dtd = dma_pool_alloc(udc_controller->td_pool, gfp_flags, dma); > + dtd = dma_pool_alloc(udc->td_pool, gfp_flags, dma); > if (dtd == NULL) > return dtd; > > @@ -848,7 +847,8 @@ static struct ep_td_struct *fsl_build_dtd(struct fsl_req *req, unsigned *length, > } > > /* Generate dtd chain for a request */ > -static int fsl_req_to_dtd(struct fsl_req *req, gfp_t gfp_flags) > +static int fsl_req_to_dtd(struct fsl_udc *udc, struct fsl_req *req, > + gfp_t gfp_flags) > { > unsigned count; > int is_last; > @@ -857,7 +857,8 @@ static int fsl_req_to_dtd(struct fsl_req *req, gfp_t gfp_flags) > dma_addr_t dma; > > do { > - dtd = fsl_build_dtd(req, &count, &dma, &is_last, gfp_flags); > + dtd = fsl_build_dtd(udc, req, &count, &dma, &is_last, > + gfp_flags); > if (dtd == NULL) > return -ENOMEM; > > @@ -932,7 +933,7 @@ fsl_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) > req->dtd_count = 0; > > /* build dtds and push them to device queue */ > - if (!fsl_req_to_dtd(req, gfp_flags)) { > + if (!fsl_req_to_dtd(udc, req, gfp_flags)) { > spin_lock_irqsave(&udc->lock, flags); > fsl_queue_td(ep, req); > } else { > @@ -1258,9 +1259,10 @@ static int fsl_pullup(struct usb_gadget *gadget, int is_on) > return 0; > } > > -static int fsl_start(struct usb_gadget_driver *driver, > - int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)); > -static int fsl_stop(struct usb_gadget_driver *driver); > +static int fsl_udc_start(struct usb_gadget *gadget, > + struct usb_gadget_driver *driver); > +static int fsl_udc_stop(struct usb_gadget *gadget, > + struct usb_gadget_driver *driver); > /* defined in gadget.h */ > static struct usb_gadget_ops fsl_gadget_ops = { > .get_frame = fsl_get_frame, > @@ -1269,8 +1271,8 @@ static struct usb_gadget_ops fsl_gadget_ops = { > .vbus_session = fsl_vbus_session, > .vbus_draw = fsl_vbus_draw, > .pullup = fsl_pullup, > - .start = fsl_start, > - .stop = fsl_stop, > + .udc_start = fsl_udc_start, > + .udc_stop = fsl_udc_stop, > }; > > /* Set protocol stall on ep0, protocol stall will automatically be cleared > @@ -1314,7 +1316,7 @@ static int ep0_prime_status(struct fsl_udc *udc, int direction) > ep_is_in(ep) ? DMA_TO_DEVICE : DMA_FROM_DEVICE); > req->mapped = 1; > > - if (fsl_req_to_dtd(req, GFP_ATOMIC) == 0) > + if (fsl_req_to_dtd(udc, req, GFP_ATOMIC) == 0) > fsl_queue_td(ep, req); > else > return -ENOMEM; > @@ -1398,7 +1400,7 @@ static void ch9getstatus(struct fsl_udc *udc, u8 request_type, u16 value, > req->mapped = 1; > > /* prime the data phase */ > - if ((fsl_req_to_dtd(req, GFP_ATOMIC) == 0)) > + if ((fsl_req_to_dtd(udc, req, GFP_ATOMIC) == 0)) > fsl_queue_td(ep, req); > else /* no mem */ > goto stall; > @@ -1422,7 +1424,7 @@ static void setup_received_irq(struct fsl_udc *udc, > > udc_reset_ep_queue(udc, 0); > > - /* We process some stardard setup requests here */ > + /* We process some standard setup requests here */ > switch (setup->bRequest) { > case USB_REQ_GET_STATUS: > /* Data+Status phase from udc */ > @@ -1954,114 +1956,82 @@ static irqreturn_t fsl_udc_irq(int irq, void *_udc) > * Hook to gadget drivers > * Called by initialization code of gadget drivers > *----------------------------------------------------------------*/ > -static int fsl_start(struct usb_gadget_driver *driver, > - int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)) > +static int fsl_udc_start(struct usb_gadget *gadget, > + struct usb_gadget_driver *driver) > { > + struct fsl_udc *udc; > int retval = -ENODEV; > - unsigned long flags = 0; > + unsigned long flags; > > - if (!udc_controller) > + udc = container_of(gadget, struct fsl_udc, gadget); > + if (!udc) > return -ENODEV; > > if (!driver || driver->max_speed < USB_SPEED_FULL > - || !bind || !driver->disconnect || !driver->setup) > + || !driver->disconnect || !driver->setup) > return -EINVAL; > > - if (udc_controller->driver) > - return -EBUSY; > - > /* lock is needed but whether should use this lock or another */ > - spin_lock_irqsave(&udc_controller->lock, flags); > + spin_lock_irqsave(&udc->lock, flags); > > driver->driver.bus = NULL; > - /* hook up the driver */ > - udc_controller->driver = driver; > - udc_controller->gadget.dev.driver = &driver->driver; > - spin_unlock_irqrestore(&udc_controller->lock, flags); > - > - /* bind udc driver to gadget driver */ > - retval = bind(&udc_controller->gadget, driver); > - if (retval) { > - VDBG("bind to %s --> %d", driver->driver.name, retval); > - udc_controller->gadget.dev.driver = NULL; > - udc_controller->driver = NULL; > - goto out; > - } > > - if (!IS_ERR_OR_NULL(udc_controller->transceiver)) { > + if (!IS_ERR_OR_NULL(udc->transceiver)) { > /* Suspend the controller until OTG enable it */ > - udc_controller->stopped = 1; > + udc->stopped = 1; > printk(KERN_INFO "Suspend udc for OTG auto detect\n"); > > /* connect to bus through transceiver */ > - if (!IS_ERR_OR_NULL(udc_controller->transceiver)) { > - retval = otg_set_peripheral( > - udc_controller->transceiver->otg, > - &udc_controller->gadget); > + if (!IS_ERR_OR_NULL(udc->transceiver)) { > + retval = otg_set_peripheral(udc->transceiver->otg, > + &udc->gadget); > if (retval < 0) { > ERR("can't bind to transceiver\n"); > - driver->unbind(&udc_controller->gadget); > - udc_controller->gadget.dev.driver = 0; > - udc_controller->driver = 0; > return retval; > } > } > } else { > - /* Enable DR IRQ reg and set USBCMD reg Run bit */ > - dr_controller_run(udc_controller); > - udc_controller->usb_state = USB_STATE_ATTACHED; > - udc_controller->ep0_state = WAIT_FOR_SETUP; > - udc_controller->ep0_dir = 0; > + /* hook up the driver */ > + udc->driver = driver; > + udc->gadget.dev.driver = &driver->driver; > + dr_controller_run(udc); > + udc->usb_state = USB_STATE_ATTACHED; > + udc->ep0_state = WAIT_FOR_SETUP; > + udc->ep0_dir = USB_DIR_OUT; > } > - printk(KERN_INFO "%s: bind to driver %s\n", > - udc_controller->gadget.name, driver->driver.name); > + spin_unlock_irqrestore(&udc->lock, flags); > > -out: > - if (retval) > - printk(KERN_WARNING "gadget driver register failed %d\n", > - retval); > - return retval; > + return 0; > } > > /* Disconnect from gadget driver */ > -static int fsl_stop(struct usb_gadget_driver *driver) > +static int fsl_udc_stop(struct usb_gadget *gadget, > + struct usb_gadget_driver *driver) > { > + struct fsl_udc *udc; > struct fsl_ep *loop_ep; > unsigned long flags; > > - if (!udc_controller) > - return -ENODEV; > - > - if (!driver || driver != udc_controller->driver || !driver->unbind) > - return -EINVAL; > - > - if (!IS_ERR_OR_NULL(udc_controller->transceiver)) > - otg_set_peripheral(udc_controller->transceiver->otg, NULL); > + udc = container_of(gadget, struct fsl_udc, gadget); > > /* stop DR, disable intr */ > - dr_controller_stop(udc_controller); > + dr_controller_stop(udc); > > /* in fact, no needed */ > - udc_controller->usb_state = USB_STATE_ATTACHED; > - udc_controller->ep0_state = WAIT_FOR_SETUP; > - udc_controller->ep0_dir = 0; > + udc->usb_state = USB_STATE_ATTACHED; > + udc->ep0_state = WAIT_FOR_SETUP; > + udc->ep0_dir = USB_DIR_OUT; > > /* stand operation */ > - spin_lock_irqsave(&udc_controller->lock, flags); > - udc_controller->gadget.speed = USB_SPEED_UNKNOWN; > - nuke(&udc_controller->eps[0], -ESHUTDOWN); > - list_for_each_entry(loop_ep, &udc_controller->gadget.ep_list, > - ep.ep_list) > + spin_lock_irqsave(&udc->lock, flags); > + udc->gadget.speed = USB_SPEED_UNKNOWN; > + nuke(&udc->eps[0], -ESHUTDOWN); > + list_for_each_entry(loop_ep, &udc->gadget.ep_list, ep.ep_list) > nuke(loop_ep, -ESHUTDOWN); > - spin_unlock_irqrestore(&udc_controller->lock, flags); > - > - /* report disconnect; the controller is already quiesced */ > - driver->disconnect(&udc_controller->gadget); > + spin_unlock_irqrestore(&udc->lock, flags); > > - /* unbind gadget and unhook driver. */ > - driver->unbind(&udc_controller->gadget); > - udc_controller->gadget.dev.driver = NULL; > - udc_controller->driver = NULL; > + udc->gadget.dev.driver = NULL; > + udc->driver = NULL; > > printk(KERN_WARNING "unregistered gadget driver '%s'\n", > driver->driver.name); > @@ -2088,8 +2058,8 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count, > u32 tmp_reg; > struct fsl_ep *ep = NULL; > struct fsl_req *req; > + struct fsl_udc *udc = _dev; > > - struct fsl_udc *udc = udc_controller; > if (off != 0) > return 0; > > @@ -2318,7 +2288,7 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count, > } > > #define create_proc_file() create_proc_read_entry(proc_filename, \ > - 0, NULL, fsl_proc_read, NULL) > + 0, NULL, fsl_proc_read, udc) > > #define remove_proc_file() remove_proc_entry(proc_filename, NULL) > > @@ -2334,10 +2304,12 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count, > /* Release udc structures */ > static void fsl_udc_release(struct device *dev) > { > - complete(udc_controller->done); > - dma_free_coherent(dev->parent, udc_controller->ep_qh_size, > - udc_controller->ep_qh, udc_controller->ep_qh_dma); > - kfree(udc_controller); > + struct fsl_udc *udc = container_of(dev, struct fsl_udc, gadget.dev); > + > + complete(udc->done); > + dma_free_coherent(dev->parent, udc->ep_qh_size, > + udc->ep_qh, udc->ep_qh_dma); > + kfree(udc); > } > > /****************************************************************** > @@ -2436,6 +2408,7 @@ static int __init struct_ep_setup(struct fsl_udc *udc, unsigned char index, > */ > static int __init fsl_udc_probe(struct platform_device *pdev) > { > + struct fsl_udc *udc; > struct fsl_usb2_platform_data *pdata; > struct resource *res; > int ret = -ENODEV; > @@ -2447,21 +2420,21 @@ static int __init fsl_udc_probe(struct platform_device *pdev) > return -ENODEV; > } > > - udc_controller = kzalloc(sizeof(struct fsl_udc), GFP_KERNEL); > - if (udc_controller == NULL) { > + udc = kzalloc(sizeof(struct fsl_udc), GFP_KERNEL); > + if (udc == NULL) { > ERR("malloc udc failed\n"); > return -ENOMEM; > } > > pdata = pdev->dev.platform_data; > - udc_controller->pdata = pdata; > - spin_lock_init(&udc_controller->lock); > - udc_controller->stopped = 1; > + udc->pdata = pdata; > + spin_lock_init(&udc->lock); > + udc->stopped = 1; > > #ifdef CONFIG_USB_OTG > if (pdata->operating_mode == FSL_USB2_DR_OTG) { > - udc_controller->transceiver = usb_get_phy(USB_PHY_TYPE_USB2); > - if (IS_ERR_OR_NULL(udc_controller->transceiver)) { > + udc->transceiver = usb_get_phy(USB_PHY_TYPE_USB2); > + if (IS_ERR_OR_NULL(udc->transceiver)) { > ERR("Can't find OTG driver!\n"); > ret = -ENODEV; > goto err_kfree; > @@ -2522,90 +2495,90 @@ static int __init fsl_udc_probe(struct platform_device *pdev) > } > /* Get max device endpoints */ > /* DEN is bidirectional ep number, max_ep doubles the number */ > - udc_controller->max_ep = (dccparams & DCCPARAMS_DEN_MASK) * 2; > + udc->max_ep = (dccparams & DCCPARAMS_DEN_MASK) * 2; > > - udc_controller->irq = platform_get_irq(pdev, 0); > - if (!udc_controller->irq) { > + udc->irq = platform_get_irq(pdev, 0); > + if (!udc->irq) { > ret = -ENODEV; > goto err_iounmap; > } > > - ret = request_irq(udc_controller->irq, fsl_udc_irq, IRQF_SHARED, > - driver_name, udc_controller); > + ret = request_irq(udc->irq, fsl_udc_irq, IRQF_SHARED, > + driver_name, udc); > if (ret != 0) { > ERR("cannot request irq %d err %d\n", > - udc_controller->irq, ret); > + udc->irq, ret); > goto err_iounmap; > } > > /* Initialize the udc structure including QH member and other member */ > - if (struct_udc_setup(udc_controller, pdev)) { > + if (struct_udc_setup(udc, pdev)) { > ERR("Can't initialize udc data structure\n"); > ret = -ENOMEM; > goto err_free_irq; > } > > - if (IS_ERR_OR_NULL(udc_controller->transceiver)) { > + if (IS_ERR_OR_NULL(udc->transceiver)) { > /* initialize usb hw reg except for regs for EP, > * leave usbintr reg untouched */ > - dr_controller_setup(udc_controller); > + dr_controller_setup(udc); > } > > fsl_udc_clk_finalize(pdev); > > /* Setup gadget structure */ > - udc_controller->gadget.ops = &fsl_gadget_ops; > - udc_controller->gadget.max_speed = USB_SPEED_HIGH; > - udc_controller->gadget.ep0 = &udc_controller->eps[0].ep; > - INIT_LIST_HEAD(&udc_controller->gadget.ep_list); > - udc_controller->gadget.speed = USB_SPEED_UNKNOWN; > - udc_controller->gadget.name = driver_name; > + udc->gadget.ops = &fsl_gadget_ops; > + udc->gadget.max_speed = USB_SPEED_HIGH; > + udc->gadget.ep0 = &udc->eps[0].ep; > + INIT_LIST_HEAD(&udc->gadget.ep_list); > + udc->gadget.speed = USB_SPEED_UNKNOWN; > + udc->gadget.name = driver_name; > udc->vbus_active = true; > > /* Setup gadget.dev and register with kernel */ > - dev_set_name(&udc_controller->gadget.dev, "gadget"); > - udc_controller->gadget.dev.release = fsl_udc_release; > - udc_controller->gadget.dev.parent = &pdev->dev; > - udc_controller->gadget.dev.of_node = pdev->dev.of_node; > - ret = device_register(&udc_controller->gadget.dev); > + dev_set_name(&udc->gadget.dev, "gadget"); > + udc->gadget.dev.release = fsl_udc_release; > + udc->gadget.dev.parent = &pdev->dev; > + udc->gadget.dev.of_node = pdev->dev.of_node; > + ret = device_register(&udc->gadget.dev); > if (ret < 0) > goto err_free_irq; > > - if (!IS_ERR_OR_NULL(udc_controller->transceiver)) > - udc_controller->gadget.is_otg = 1; > + if (!IS_ERR_OR_NULL(udc->transceiver)) > + udc->gadget.is_otg = 1; > > /* setup QH and epctrl for ep0 */ > - ep0_setup(udc_controller); > + ep0_setup(udc); > > /* setup udc->eps[] for ep0 */ > - struct_ep_setup(udc_controller, 0, "ep0", 0); > + struct_ep_setup(udc, 0, "ep0", 0); > /* for ep0: the desc defined here; > * for other eps, gadget layer called ep_enable with defined desc > */ > - udc_controller->eps[0].ep.desc = &fsl_ep0_desc; > - udc_controller->eps[0].ep.maxpacket = USB_MAX_CTRL_PAYLOAD; > + udc->eps[0].ep.desc = &fsl_ep0_desc; > + udc->eps[0].ep.maxpacket = USB_MAX_CTRL_PAYLOAD; > > /* setup the udc->eps[] for non-control endpoints and link > * to gadget.ep_list */ > - for (i = 1; i < (int)(udc_controller->max_ep / 2); i++) { > + for (i = 1; i < (int)(udc->max_ep / 2); i++) { > char name[14]; > > sprintf(name, "ep%dout", i); > - struct_ep_setup(udc_controller, i * 2, name, 1); > + struct_ep_setup(udc, i * 2, name, 1); > sprintf(name, "ep%din", i); > - struct_ep_setup(udc_controller, i * 2 + 1, name, 1); > + struct_ep_setup(udc, i * 2 + 1, name, 1); > } > > /* use dma_pool for TD management */ > - udc_controller->td_pool = dma_pool_create("udc_td", &pdev->dev, > + udc->td_pool = dma_pool_create("udc_td", &pdev->dev, > sizeof(struct ep_td_struct), > DTD_ALIGNMENT, UDC_DMA_BOUNDARY); > - if (udc_controller->td_pool == NULL) { > + if (udc->td_pool == NULL) { > ret = -ENOMEM; > goto err_unregister; > } > > - ret = usb_add_gadget_udc(&pdev->dev, &udc_controller->gadget); > + ret = usb_add_gadget_udc(&pdev->dev, &udc->gadget); > if (ret) > goto err_del_udc; > > @@ -2613,11 +2586,11 @@ static int __init fsl_udc_probe(struct platform_device *pdev) > return 0; > > err_del_udc: > - dma_pool_destroy(udc_controller->td_pool); > + dma_pool_destroy(udc->td_pool); > err_unregister: > - device_unregister(&udc_controller->gadget.dev); > + device_unregister(&udc->gadget.dev); > err_free_irq: > - free_irq(udc_controller->irq, udc_controller); > + free_irq(udc->irq, udc); > err_iounmap: > if (pdata->exit) > pdata->exit(pdev); > @@ -2628,8 +2601,7 @@ err_release_mem_region: > if (pdata->operating_mode == FSL_USB2_DR_DEVICE) > release_mem_region(res->start, resource_size(res)); > err_kfree: > - kfree(udc_controller); > - udc_controller = NULL; > + kfree(udc); > return ret; > } > > @@ -2638,16 +2610,13 @@ err_kfree: > */ > static int __exit fsl_udc_remove(struct platform_device *pdev) > { > + struct fsl_udc *udc = dev_get_drvdata(&pdev->dev); > struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); > struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; > - > DECLARE_COMPLETION(done); > > - if (!udc_controller) > - return -ENODEV; > - > - usb_del_gadget_udc(&udc_controller->gadget); > - udc_controller->done = &done; > + usb_del_gadget_udc(&udc->gadget); > + udc->done = &done; > > fsl_udc_clk_release(); > > @@ -2655,17 +2624,17 @@ static int __exit fsl_udc_remove(struct platform_device *pdev) > remove_proc_file(); > > /* Free allocated memory */ > - kfree(udc_controller->status_req->req.buf); > - kfree(udc_controller->status_req); > - kfree(udc_controller->eps); > + kfree(udc->status_req->req.buf); > + kfree(udc->status_req); > + kfree(udc->eps); > > - dma_pool_destroy(udc_controller->td_pool); > - free_irq(udc_controller->irq, udc_controller); > + dma_pool_destroy(udc->td_pool); > + free_irq(udc->irq, udc); > iounmap(dr_regs); > if (pdata->operating_mode == FSL_USB2_DR_DEVICE) > release_mem_region(res->start, resource_size(res)); > > - device_unregister(&udc_controller->gadget.dev); > + device_unregister(&udc->gadget.dev); > /* free udc --wait for the release() finished */ > wait_for_completion(&done); > > @@ -2685,7 +2654,8 @@ static int __exit fsl_udc_remove(struct platform_device *pdev) > -----------------------------------------------------------------*/ > static int fsl_udc_suspend(struct platform_device *pdev, pm_message_t state) > { > - dr_controller_stop(udc_controller); > + struct fsl_udc *udc = dev_get_drvdata(&pdev->dev); > + dr_controller_stop(udc); > return 0; > } > > @@ -2695,20 +2665,21 @@ static int fsl_udc_suspend(struct platform_device *pdev, pm_message_t state) > *-----------------------------------------------------------------*/ > static int fsl_udc_resume(struct platform_device *pdev) > { > + struct fsl_udc *udc = dev_get_drvdata(&pdev->dev); > /* Enable DR irq reg and set controller Run */ > - if (udc_controller->stopped) { > - dr_controller_setup(udc_controller); > - dr_controller_run(udc_controller); > + if (udc->stopped) { > + dr_controller_setup(udc); > + dr_controller_run(udc); > } > - udc_controller->usb_state = USB_STATE_ATTACHED; > - udc_controller->ep0_state = WAIT_FOR_SETUP; > - udc_controller->ep0_dir = 0; > + udc->usb_state = USB_STATE_ATTACHED; > + udc->ep0_state = WAIT_FOR_SETUP; > + udc->ep0_dir = USB_DIR_OUT; > return 0; > } > > static int fsl_udc_otg_suspend(struct device *dev, pm_message_t state) > { > - struct fsl_udc *udc = udc_controller; > + struct fsl_udc *udc = container_of(dev, struct fsl_udc, gadget.dev); > u32 mode, usbcmd; > > mode = fsl_readl(&dr_regs->usbmode) & USB_MODE_CTRL_MODE_MASK; > @@ -2744,15 +2715,17 @@ static int fsl_udc_otg_suspend(struct device *dev, pm_message_t state) > > static int fsl_udc_otg_resume(struct device *dev) > { > + struct fsl_udc *udc = container_of(dev, struct fsl_udc, gadget.dev); > + > pr_debug("%s(): stopped %d already_stopped %d\n", __func__, > - udc_controller->stopped, udc_controller->already_stopped); > + udc->stopped, udc->already_stopped); > > /* > * If the controller was stopped at suspend time, then > * don't resume it now. > */ > - if (udc_controller->already_stopped) { > - udc_controller->already_stopped = 0; > + if (udc->already_stopped) { > + udc->already_stopped = 0; > pr_debug("gadget was already stopped, leaving early\n"); > return 0; > } > -- > 1.7.2.5 >
diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c index 0a0d6a6..d113f39 100644 --- a/drivers/usb/gadget/fsl_udc_core.c +++ b/drivers/usb/gadget/fsl_udc_core.c @@ -63,9 +63,6 @@ static struct usb_dr_device *dr_regs; static struct usb_sys_interface *usb_sys_regs; -/* it is initialized in probe() */ -static struct fsl_udc *udc_controller = NULL; - static const struct usb_endpoint_descriptor fsl_ep0_desc = { .bLength = USB_DT_ENDPOINT_SIZE, @@ -783,12 +780,14 @@ static void fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req) } /* Fill in the dTD structure + * @udc: driver private data * @req: request that the transfer belongs to * @length: return actually data length of the dTD * @dma: return dma address of the dTD * @is_last: return flag if it is the last dTD of the request * return: pointer to the built dTD */ -static struct ep_td_struct *fsl_build_dtd(struct fsl_req *req, unsigned *length, +static struct ep_td_struct *fsl_build_dtd(struct fsl_udc *udc, + struct fsl_req *req, unsigned *length, dma_addr_t *dma, int *is_last, gfp_t gfp_flags) { u32 swap_temp; @@ -798,7 +797,7 @@ static struct ep_td_struct *fsl_build_dtd(struct fsl_req *req, unsigned *length, *length = min(req->req.length - req->req.actual, (unsigned)EP_MAX_LENGTH_TRANSFER); - dtd = dma_pool_alloc(udc_controller->td_pool, gfp_flags, dma); + dtd = dma_pool_alloc(udc->td_pool, gfp_flags, dma); if (dtd == NULL) return dtd; @@ -848,7 +847,8 @@ static struct ep_td_struct *fsl_build_dtd(struct fsl_req *req, unsigned *length, } /* Generate dtd chain for a request */ -static int fsl_req_to_dtd(struct fsl_req *req, gfp_t gfp_flags) +static int fsl_req_to_dtd(struct fsl_udc *udc, struct fsl_req *req, + gfp_t gfp_flags) { unsigned count; int is_last; @@ -857,7 +857,8 @@ static int fsl_req_to_dtd(struct fsl_req *req, gfp_t gfp_flags) dma_addr_t dma; do { - dtd = fsl_build_dtd(req, &count, &dma, &is_last, gfp_flags); + dtd = fsl_build_dtd(udc, req, &count, &dma, &is_last, + gfp_flags); if (dtd == NULL) return -ENOMEM; @@ -932,7 +933,7 @@ fsl_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) req->dtd_count = 0; /* build dtds and push them to device queue */ - if (!fsl_req_to_dtd(req, gfp_flags)) { + if (!fsl_req_to_dtd(udc, req, gfp_flags)) { spin_lock_irqsave(&udc->lock, flags); fsl_queue_td(ep, req); } else { @@ -1258,9 +1259,10 @@ static int fsl_pullup(struct usb_gadget *gadget, int is_on) return 0; } -static int fsl_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)); -static int fsl_stop(struct usb_gadget_driver *driver); +static int fsl_udc_start(struct usb_gadget *gadget, + struct usb_gadget_driver *driver); +static int fsl_udc_stop(struct usb_gadget *gadget, + struct usb_gadget_driver *driver); /* defined in gadget.h */ static struct usb_gadget_ops fsl_gadget_ops = { .get_frame = fsl_get_frame, @@ -1269,8 +1271,8 @@ static struct usb_gadget_ops fsl_gadget_ops = { .vbus_session = fsl_vbus_session, .vbus_draw = fsl_vbus_draw, .pullup = fsl_pullup, - .start = fsl_start, - .stop = fsl_stop, + .udc_start = fsl_udc_start, + .udc_stop = fsl_udc_stop, }; /* Set protocol stall on ep0, protocol stall will automatically be cleared @@ -1314,7 +1316,7 @@ static int ep0_prime_status(struct fsl_udc *udc, int direction) ep_is_in(ep) ? DMA_TO_DEVICE : DMA_FROM_DEVICE); req->mapped = 1; - if (fsl_req_to_dtd(req, GFP_ATOMIC) == 0) + if (fsl_req_to_dtd(udc, req, GFP_ATOMIC) == 0) fsl_queue_td(ep, req); else return -ENOMEM; @@ -1398,7 +1400,7 @@ static void ch9getstatus(struct fsl_udc *udc, u8 request_type, u16 value, req->mapped = 1; /* prime the data phase */ - if ((fsl_req_to_dtd(req, GFP_ATOMIC) == 0)) + if ((fsl_req_to_dtd(udc, req, GFP_ATOMIC) == 0)) fsl_queue_td(ep, req); else /* no mem */ goto stall; @@ -1422,7 +1424,7 @@ static void setup_received_irq(struct fsl_udc *udc, udc_reset_ep_queue(udc, 0); - /* We process some stardard setup requests here */ + /* We process some standard setup requests here */ switch (setup->bRequest) { case USB_REQ_GET_STATUS: /* Data+Status phase from udc */ @@ -1954,114 +1956,82 @@ static irqreturn_t fsl_udc_irq(int irq, void *_udc) * Hook to gadget drivers * Called by initialization code of gadget drivers *----------------------------------------------------------------*/ -static int fsl_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)) +static int fsl_udc_start(struct usb_gadget *gadget, + struct usb_gadget_driver *driver) { + struct fsl_udc *udc; int retval = -ENODEV; - unsigned long flags = 0; + unsigned long flags; - if (!udc_controller) + udc = container_of(gadget, struct fsl_udc, gadget); + if (!udc) return -ENODEV; if (!driver || driver->max_speed < USB_SPEED_FULL - || !bind || !driver->disconnect || !driver->setup) + || !driver->disconnect || !driver->setup) return -EINVAL; - if (udc_controller->driver) - return -EBUSY; - /* lock is needed but whether should use this lock or another */ - spin_lock_irqsave(&udc_controller->lock, flags); + spin_lock_irqsave(&udc->lock, flags); driver->driver.bus = NULL; - /* hook up the driver */ - udc_controller->driver = driver; - udc_controller->gadget.dev.driver = &driver->driver; - spin_unlock_irqrestore(&udc_controller->lock, flags); - - /* bind udc driver to gadget driver */ - retval = bind(&udc_controller->gadget, driver); - if (retval) { - VDBG("bind to %s --> %d", driver->driver.name, retval); - udc_controller->gadget.dev.driver = NULL; - udc_controller->driver = NULL; - goto out; - } - if (!IS_ERR_OR_NULL(udc_controller->transceiver)) { + if (!IS_ERR_OR_NULL(udc->transceiver)) { /* Suspend the controller until OTG enable it */ - udc_controller->stopped = 1; + udc->stopped = 1; printk(KERN_INFO "Suspend udc for OTG auto detect\n"); /* connect to bus through transceiver */ - if (!IS_ERR_OR_NULL(udc_controller->transceiver)) { - retval = otg_set_peripheral( - udc_controller->transceiver->otg, - &udc_controller->gadget); + if (!IS_ERR_OR_NULL(udc->transceiver)) { + retval = otg_set_peripheral(udc->transceiver->otg, + &udc->gadget); if (retval < 0) { ERR("can't bind to transceiver\n"); - driver->unbind(&udc_controller->gadget); - udc_controller->gadget.dev.driver = 0; - udc_controller->driver = 0; return retval; } } } else { - /* Enable DR IRQ reg and set USBCMD reg Run bit */ - dr_controller_run(udc_controller); - udc_controller->usb_state = USB_STATE_ATTACHED; - udc_controller->ep0_state = WAIT_FOR_SETUP; - udc_controller->ep0_dir = 0; + /* hook up the driver */ + udc->driver = driver; + udc->gadget.dev.driver = &driver->driver; + dr_controller_run(udc); + udc->usb_state = USB_STATE_ATTACHED; + udc->ep0_state = WAIT_FOR_SETUP; + udc->ep0_dir = USB_DIR_OUT; } - printk(KERN_INFO "%s: bind to driver %s\n", - udc_controller->gadget.name, driver->driver.name); + spin_unlock_irqrestore(&udc->lock, flags); -out: - if (retval) - printk(KERN_WARNING "gadget driver register failed %d\n", - retval); - return retval; + return 0; } /* Disconnect from gadget driver */ -static int fsl_stop(struct usb_gadget_driver *driver) +static int fsl_udc_stop(struct usb_gadget *gadget, + struct usb_gadget_driver *driver) { + struct fsl_udc *udc; struct fsl_ep *loop_ep; unsigned long flags; - if (!udc_controller) - return -ENODEV; - - if (!driver || driver != udc_controller->driver || !driver->unbind) - return -EINVAL; - - if (!IS_ERR_OR_NULL(udc_controller->transceiver)) - otg_set_peripheral(udc_controller->transceiver->otg, NULL); + udc = container_of(gadget, struct fsl_udc, gadget); /* stop DR, disable intr */ - dr_controller_stop(udc_controller); + dr_controller_stop(udc); /* in fact, no needed */ - udc_controller->usb_state = USB_STATE_ATTACHED; - udc_controller->ep0_state = WAIT_FOR_SETUP; - udc_controller->ep0_dir = 0; + udc->usb_state = USB_STATE_ATTACHED; + udc->ep0_state = WAIT_FOR_SETUP; + udc->ep0_dir = USB_DIR_OUT; /* stand operation */ - spin_lock_irqsave(&udc_controller->lock, flags); - udc_controller->gadget.speed = USB_SPEED_UNKNOWN; - nuke(&udc_controller->eps[0], -ESHUTDOWN); - list_for_each_entry(loop_ep, &udc_controller->gadget.ep_list, - ep.ep_list) + spin_lock_irqsave(&udc->lock, flags); + udc->gadget.speed = USB_SPEED_UNKNOWN; + nuke(&udc->eps[0], -ESHUTDOWN); + list_for_each_entry(loop_ep, &udc->gadget.ep_list, ep.ep_list) nuke(loop_ep, -ESHUTDOWN); - spin_unlock_irqrestore(&udc_controller->lock, flags); - - /* report disconnect; the controller is already quiesced */ - driver->disconnect(&udc_controller->gadget); + spin_unlock_irqrestore(&udc->lock, flags); - /* unbind gadget and unhook driver. */ - driver->unbind(&udc_controller->gadget); - udc_controller->gadget.dev.driver = NULL; - udc_controller->driver = NULL; + udc->gadget.dev.driver = NULL; + udc->driver = NULL; printk(KERN_WARNING "unregistered gadget driver '%s'\n", driver->driver.name); @@ -2088,8 +2058,8 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count, u32 tmp_reg; struct fsl_ep *ep = NULL; struct fsl_req *req; + struct fsl_udc *udc = _dev; - struct fsl_udc *udc = udc_controller; if (off != 0) return 0; @@ -2318,7 +2288,7 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count, } #define create_proc_file() create_proc_read_entry(proc_filename, \ - 0, NULL, fsl_proc_read, NULL) + 0, NULL, fsl_proc_read, udc) #define remove_proc_file() remove_proc_entry(proc_filename, NULL) @@ -2334,10 +2304,12 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count, /* Release udc structures */ static void fsl_udc_release(struct device *dev) { - complete(udc_controller->done); - dma_free_coherent(dev->parent, udc_controller->ep_qh_size, - udc_controller->ep_qh, udc_controller->ep_qh_dma); - kfree(udc_controller); + struct fsl_udc *udc = container_of(dev, struct fsl_udc, gadget.dev); + + complete(udc->done); + dma_free_coherent(dev->parent, udc->ep_qh_size, + udc->ep_qh, udc->ep_qh_dma); + kfree(udc); } /****************************************************************** @@ -2436,6 +2408,7 @@ static int __init struct_ep_setup(struct fsl_udc *udc, unsigned char index, */ static int __init fsl_udc_probe(struct platform_device *pdev) { + struct fsl_udc *udc; struct fsl_usb2_platform_data *pdata; struct resource *res; int ret = -ENODEV; @@ -2447,21 +2420,21 @@ static int __init fsl_udc_probe(struct platform_device *pdev) return -ENODEV; } - udc_controller = kzalloc(sizeof(struct fsl_udc), GFP_KERNEL); - if (udc_controller == NULL) { + udc = kzalloc(sizeof(struct fsl_udc), GFP_KERNEL); + if (udc == NULL) { ERR("malloc udc failed\n"); return -ENOMEM; } pdata = pdev->dev.platform_data; - udc_controller->pdata = pdata; - spin_lock_init(&udc_controller->lock); - udc_controller->stopped = 1; + udc->pdata = pdata; + spin_lock_init(&udc->lock); + udc->stopped = 1; #ifdef CONFIG_USB_OTG if (pdata->operating_mode == FSL_USB2_DR_OTG) { - udc_controller->transceiver = usb_get_phy(USB_PHY_TYPE_USB2); - if (IS_ERR_OR_NULL(udc_controller->transceiver)) { + udc->transceiver = usb_get_phy(USB_PHY_TYPE_USB2); + if (IS_ERR_OR_NULL(udc->transceiver)) { ERR("Can't find OTG driver!\n"); ret = -ENODEV; goto err_kfree; @@ -2522,90 +2495,90 @@ static int __init fsl_udc_probe(struct platform_device *pdev) } /* Get max device endpoints */ /* DEN is bidirectional ep number, max_ep doubles the number */ - udc_controller->max_ep = (dccparams & DCCPARAMS_DEN_MASK) * 2; + udc->max_ep = (dccparams & DCCPARAMS_DEN_MASK) * 2; - udc_controller->irq = platform_get_irq(pdev, 0); - if (!udc_controller->irq) { + udc->irq = platform_get_irq(pdev, 0); + if (!udc->irq) { ret = -ENODEV; goto err_iounmap; } - ret = request_irq(udc_controller->irq, fsl_udc_irq, IRQF_SHARED, - driver_name, udc_controller); + ret = request_irq(udc->irq, fsl_udc_irq, IRQF_SHARED, + driver_name, udc); if (ret != 0) { ERR("cannot request irq %d err %d\n", - udc_controller->irq, ret); + udc->irq, ret); goto err_iounmap; } /* Initialize the udc structure including QH member and other member */ - if (struct_udc_setup(udc_controller, pdev)) { + if (struct_udc_setup(udc, pdev)) { ERR("Can't initialize udc data structure\n"); ret = -ENOMEM; goto err_free_irq; } - if (IS_ERR_OR_NULL(udc_controller->transceiver)) { + if (IS_ERR_OR_NULL(udc->transceiver)) { /* initialize usb hw reg except for regs for EP, * leave usbintr reg untouched */ - dr_controller_setup(udc_controller); + dr_controller_setup(udc); } fsl_udc_clk_finalize(pdev); /* Setup gadget structure */ - udc_controller->gadget.ops = &fsl_gadget_ops; - udc_controller->gadget.max_speed = USB_SPEED_HIGH; - udc_controller->gadget.ep0 = &udc_controller->eps[0].ep; - INIT_LIST_HEAD(&udc_controller->gadget.ep_list); - udc_controller->gadget.speed = USB_SPEED_UNKNOWN; - udc_controller->gadget.name = driver_name; + udc->gadget.ops = &fsl_gadget_ops; + udc->gadget.max_speed = USB_SPEED_HIGH; + udc->gadget.ep0 = &udc->eps[0].ep; + INIT_LIST_HEAD(&udc->gadget.ep_list); + udc->gadget.speed = USB_SPEED_UNKNOWN; + udc->gadget.name = driver_name; udc->vbus_active = true; /* Setup gadget.dev and register with kernel */ - dev_set_name(&udc_controller->gadget.dev, "gadget"); - udc_controller->gadget.dev.release = fsl_udc_release; - udc_controller->gadget.dev.parent = &pdev->dev; - udc_controller->gadget.dev.of_node = pdev->dev.of_node; - ret = device_register(&udc_controller->gadget.dev); + dev_set_name(&udc->gadget.dev, "gadget"); + udc->gadget.dev.release = fsl_udc_release; + udc->gadget.dev.parent = &pdev->dev; + udc->gadget.dev.of_node = pdev->dev.of_node; + ret = device_register(&udc->gadget.dev); if (ret < 0) goto err_free_irq; - if (!IS_ERR_OR_NULL(udc_controller->transceiver)) - udc_controller->gadget.is_otg = 1; + if (!IS_ERR_OR_NULL(udc->transceiver)) + udc->gadget.is_otg = 1; /* setup QH and epctrl for ep0 */ - ep0_setup(udc_controller); + ep0_setup(udc); /* setup udc->eps[] for ep0 */ - struct_ep_setup(udc_controller, 0, "ep0", 0); + struct_ep_setup(udc, 0, "ep0", 0); /* for ep0: the desc defined here; * for other eps, gadget layer called ep_enable with defined desc */ - udc_controller->eps[0].ep.desc = &fsl_ep0_desc; - udc_controller->eps[0].ep.maxpacket = USB_MAX_CTRL_PAYLOAD; + udc->eps[0].ep.desc = &fsl_ep0_desc; + udc->eps[0].ep.maxpacket = USB_MAX_CTRL_PAYLOAD; /* setup the udc->eps[] for non-control endpoints and link * to gadget.ep_list */ - for (i = 1; i < (int)(udc_controller->max_ep / 2); i++) { + for (i = 1; i < (int)(udc->max_ep / 2); i++) { char name[14]; sprintf(name, "ep%dout", i); - struct_ep_setup(udc_controller, i * 2, name, 1); + struct_ep_setup(udc, i * 2, name, 1); sprintf(name, "ep%din", i); - struct_ep_setup(udc_controller, i * 2 + 1, name, 1); + struct_ep_setup(udc, i * 2 + 1, name, 1); } /* use dma_pool for TD management */ - udc_controller->td_pool = dma_pool_create("udc_td", &pdev->dev, + udc->td_pool = dma_pool_create("udc_td", &pdev->dev, sizeof(struct ep_td_struct), DTD_ALIGNMENT, UDC_DMA_BOUNDARY); - if (udc_controller->td_pool == NULL) { + if (udc->td_pool == NULL) { ret = -ENOMEM; goto err_unregister; } - ret = usb_add_gadget_udc(&pdev->dev, &udc_controller->gadget); + ret = usb_add_gadget_udc(&pdev->dev, &udc->gadget); if (ret) goto err_del_udc; @@ -2613,11 +2586,11 @@ static int __init fsl_udc_probe(struct platform_device *pdev) return 0; err_del_udc: - dma_pool_destroy(udc_controller->td_pool); + dma_pool_destroy(udc->td_pool); err_unregister: - device_unregister(&udc_controller->gadget.dev); + device_unregister(&udc->gadget.dev); err_free_irq: - free_irq(udc_controller->irq, udc_controller); + free_irq(udc->irq, udc); err_iounmap: if (pdata->exit) pdata->exit(pdev); @@ -2628,8 +2601,7 @@ err_release_mem_region: if (pdata->operating_mode == FSL_USB2_DR_DEVICE) release_mem_region(res->start, resource_size(res)); err_kfree: - kfree(udc_controller); - udc_controller = NULL; + kfree(udc); return ret; } @@ -2638,16 +2610,13 @@ err_kfree: */ static int __exit fsl_udc_remove(struct platform_device *pdev) { + struct fsl_udc *udc = dev_get_drvdata(&pdev->dev); struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; - DECLARE_COMPLETION(done); - if (!udc_controller) - return -ENODEV; - - usb_del_gadget_udc(&udc_controller->gadget); - udc_controller->done = &done; + usb_del_gadget_udc(&udc->gadget); + udc->done = &done; fsl_udc_clk_release(); @@ -2655,17 +2624,17 @@ static int __exit fsl_udc_remove(struct platform_device *pdev) remove_proc_file(); /* Free allocated memory */ - kfree(udc_controller->status_req->req.buf); - kfree(udc_controller->status_req); - kfree(udc_controller->eps); + kfree(udc->status_req->req.buf); + kfree(udc->status_req); + kfree(udc->eps); - dma_pool_destroy(udc_controller->td_pool); - free_irq(udc_controller->irq, udc_controller); + dma_pool_destroy(udc->td_pool); + free_irq(udc->irq, udc); iounmap(dr_regs); if (pdata->operating_mode == FSL_USB2_DR_DEVICE) release_mem_region(res->start, resource_size(res)); - device_unregister(&udc_controller->gadget.dev); + device_unregister(&udc->gadget.dev); /* free udc --wait for the release() finished */ wait_for_completion(&done); @@ -2685,7 +2654,8 @@ static int __exit fsl_udc_remove(struct platform_device *pdev) -----------------------------------------------------------------*/ static int fsl_udc_suspend(struct platform_device *pdev, pm_message_t state) { - dr_controller_stop(udc_controller); + struct fsl_udc *udc = dev_get_drvdata(&pdev->dev); + dr_controller_stop(udc); return 0; } @@ -2695,20 +2665,21 @@ static int fsl_udc_suspend(struct platform_device *pdev, pm_message_t state) *-----------------------------------------------------------------*/ static int fsl_udc_resume(struct platform_device *pdev) { + struct fsl_udc *udc = dev_get_drvdata(&pdev->dev); /* Enable DR irq reg and set controller Run */ - if (udc_controller->stopped) { - dr_controller_setup(udc_controller); - dr_controller_run(udc_controller); + if (udc->stopped) { + dr_controller_setup(udc); + dr_controller_run(udc); } - udc_controller->usb_state = USB_STATE_ATTACHED; - udc_controller->ep0_state = WAIT_FOR_SETUP; - udc_controller->ep0_dir = 0; + udc->usb_state = USB_STATE_ATTACHED; + udc->ep0_state = WAIT_FOR_SETUP; + udc->ep0_dir = USB_DIR_OUT; return 0; } static int fsl_udc_otg_suspend(struct device *dev, pm_message_t state) { - struct fsl_udc *udc = udc_controller; + struct fsl_udc *udc = container_of(dev, struct fsl_udc, gadget.dev); u32 mode, usbcmd; mode = fsl_readl(&dr_regs->usbmode) & USB_MODE_CTRL_MODE_MASK; @@ -2744,15 +2715,17 @@ static int fsl_udc_otg_suspend(struct device *dev, pm_message_t state) static int fsl_udc_otg_resume(struct device *dev) { + struct fsl_udc *udc = container_of(dev, struct fsl_udc, gadget.dev); + pr_debug("%s(): stopped %d already_stopped %d\n", __func__, - udc_controller->stopped, udc_controller->already_stopped); + udc->stopped, udc->already_stopped); /* * If the controller was stopped at suspend time, then * don't resume it now. */ - if (udc_controller->already_stopped) { - udc_controller->already_stopped = 0; + if (udc->already_stopped) { + udc->already_stopped = 0; pr_debug("gadget was already stopped, leaving early\n"); return 0; }
Convert to new UDC style registration and remove global 'udc_controller' pointer. Signed-off-by: Christoph Fritz <chf.fritz@googlemail.com> --- drivers/usb/gadget/fsl_udc_core.c | 289 +++++++++++++++++-------------------- 1 files changed, 131 insertions(+), 158 deletions(-)