This patches converts the driver into the new style start/stop interface. As a result the driver no longer uses the static global udc_conroller variable. Compile tested only. Cc: Li Yang <leoli@xxxxxxxxxxxxx> Signed-off-by: Sebastian Andrzej Siewior <sebastian@xxxxxxxxxxxxx> --- drivers/usb/gadget/fsl_udc_core.c | 347 +++++++++++++++++-------------------- 1 files changed, 162 insertions(+), 185 deletions(-) diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c index d7ea6c0..a44f551 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; #endif -/* 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, @@ -128,16 +125,16 @@ static inline void fsl_set_accessors(struct fsl_usb2_platform_data *pdata) } } -static inline u32 cpu_to_hc32(const u32 x) +static inline u32 cpu_to_hc32(struct fsl_udc *udc, const u32 x) { - return udc_controller->pdata->big_endian_desc + return udc->pdata->big_endian_desc ? (__force u32)cpu_to_be32(x) : (__force u32)cpu_to_le32(x); } -static inline u32 hc32_to_cpu(const u32 x) +static inline u32 hc32_to_cpu(struct fsl_udc *udc, const u32 x) { - return udc_controller->pdata->big_endian_desc + return udc->pdata->big_endian_desc ? be32_to_cpu((__force __be32)x) : le32_to_cpu((__force __le32)x); } @@ -146,8 +143,8 @@ static inline void fsl_set_accessors(struct fsl_usb2_platform_data *pdata) {} #define fsl_readl(addr) readl(addr) #define fsl_writel(val32, addr) writel(val32, addr) -#define cpu_to_hc32(x) cpu_to_le32(x) -#define hc32_to_cpu(x) le32_to_cpu(x) +#define cpu_to_hc32(udc, x) cpu_to_le32(x) +#define hc32_to_cpu(udc, x) le32_to_cpu(x) #endif /* CONFIG_PPC32 */ /******************************************************************** @@ -506,7 +503,7 @@ static void struct_ep_qh_setup(struct fsl_udc *udc, unsigned char ep_num, if (zlt) tmp |= EP_QUEUE_HEAD_ZLT_SEL; - p_QH->max_pkt_length = cpu_to_hc32(tmp); + p_QH->max_pkt_length = cpu_to_hc32(udc, tmp); p_QH->next_dtd_ptr = 1; p_QH->size_ioc_int_sts = 0; } @@ -702,12 +699,12 @@ static void fsl_prime_ep(struct fsl_ep *ep, struct ep_td_struct *td) struct ep_queue_head *qh = get_qh_by_ep(ep); /* Write dQH next pointer and terminate bit to 0 */ - qh->next_dtd_ptr = cpu_to_hc32(td->td_dma + qh->next_dtd_ptr = cpu_to_hc32(ep->udc, td->td_dma & EP_QUEUE_HEAD_NEXT_POINTER_MASK); /* Clear active and halt bit */ - qh->size_ioc_int_sts &= cpu_to_hc32(~(EP_QUEUE_HEAD_STATUS_ACTIVE - | EP_QUEUE_HEAD_STATUS_HALT)); + qh->size_ioc_int_sts &= cpu_to_hc32(ep->udc, + ~(EP_QUEUE_HEAD_STATUS_ACTIVE | EP_QUEUE_HEAD_STATUS_HALT)); /* Ensure that updates to the QH will occur before priming. */ wmb(); @@ -735,7 +732,7 @@ static void fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req) struct fsl_req *lastreq; lastreq = list_entry(ep->queue.prev, struct fsl_req, queue); lastreq->tail->next_td_ptr = - cpu_to_hc32(req->head->td_dma & DTD_ADDR_MASK); + cpu_to_hc32(ep->udc, req->head->td_dma & DTD_ADDR_MASK); /* Read prime bit, if 1 goto done */ if (fsl_readl(&dr_regs->endpointprime) & bitmask) return; @@ -767,8 +764,9 @@ static void fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req) * @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, - dma_addr_t *dma, int *is_last) +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) { u32 swap_temp; struct ep_td_struct *dtd; @@ -777,23 +775,23 @@ 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_KERNEL, dma); + dtd = dma_pool_alloc(udc->td_pool, GFP_KERNEL, dma); if (dtd == NULL) return dtd; dtd->td_dma = *dma; /* Clear reserved field */ - swap_temp = hc32_to_cpu(dtd->size_ioc_sts); + swap_temp = hc32_to_cpu(udc, dtd->size_ioc_sts); swap_temp &= ~DTD_RESERVED_FIELDS; - dtd->size_ioc_sts = cpu_to_hc32(swap_temp); + dtd->size_ioc_sts = cpu_to_hc32(udc, swap_temp); /* Init all of buffer page pointers */ swap_temp = (u32) (req->req.dma + req->req.actual); - dtd->buff_ptr0 = cpu_to_hc32(swap_temp); - dtd->buff_ptr1 = cpu_to_hc32(swap_temp + 0x1000); - dtd->buff_ptr2 = cpu_to_hc32(swap_temp + 0x2000); - dtd->buff_ptr3 = cpu_to_hc32(swap_temp + 0x3000); - dtd->buff_ptr4 = cpu_to_hc32(swap_temp + 0x4000); + dtd->buff_ptr0 = cpu_to_hc32(udc, swap_temp); + dtd->buff_ptr1 = cpu_to_hc32(udc, swap_temp + 0x1000); + dtd->buff_ptr2 = cpu_to_hc32(udc, swap_temp + 0x2000); + dtd->buff_ptr3 = cpu_to_hc32(udc, swap_temp + 0x3000); + dtd->buff_ptr4 = cpu_to_hc32(udc, swap_temp + 0x4000); req->req.actual += *length; @@ -817,7 +815,7 @@ static struct ep_td_struct *fsl_build_dtd(struct fsl_req *req, unsigned *length, if (*is_last && !req->req.no_interrupt) swap_temp |= DTD_IOC; - dtd->size_ioc_sts = cpu_to_hc32(swap_temp); + dtd->size_ioc_sts = cpu_to_hc32(udc, swap_temp); mb(); @@ -827,7 +825,7 @@ 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) +static int fsl_req_to_dtd(struct fsl_udc *udc, struct fsl_req *req) { unsigned count; int is_last; @@ -836,7 +834,7 @@ static int fsl_req_to_dtd(struct fsl_req *req) dma_addr_t dma; do { - dtd = fsl_build_dtd(req, &count, &dma, &is_last); + dtd = fsl_build_dtd(udc, req, &count, &dma, &is_last); if (dtd == NULL) return -ENOMEM; @@ -844,7 +842,7 @@ static int fsl_req_to_dtd(struct fsl_req *req) is_first = 0; req->head = dtd; } else { - last_dtd->next_td_ptr = cpu_to_hc32(dma); + last_dtd->next_td_ptr = cpu_to_hc32(udc, dma); last_dtd->next_td_virt = dtd; } last_dtd = dtd; @@ -852,7 +850,7 @@ static int fsl_req_to_dtd(struct fsl_req *req) req->dtd_count++; } while (!is_last); - dtd->next_td_ptr = cpu_to_hc32(DTD_NEXT_TERMINATE); + dtd->next_td_ptr = cpu_to_hc32(udc, DTD_NEXT_TERMINATE); req->tail = dtd; @@ -913,7 +911,7 @@ fsl_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) spin_lock_irqsave(&udc->lock, flags); /* build dtds and push them to device queue */ - if (!fsl_req_to_dtd(req)) { + if (!fsl_req_to_dtd(udc, req)) { fsl_queue_td(ep, req); } else { spin_unlock_irqrestore(&udc->lock, flags); @@ -1240,9 +1238,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 *)); -static int fsl_stop(struct usb_gadget_driver *driver); +static int fsl_start(struct usb_gadget *gadget, + struct usb_gadget_driver *driver); +static int fsl_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, @@ -1251,8 +1250,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_start, + .udc_stop = fsl_stop, }; /* Set protocol stall on ep0, protocol stall will automatically be cleared @@ -1295,7 +1294,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) == 0) + if (fsl_req_to_dtd(udc, req) == 0) fsl_queue_td(ep, req); else return -ENOMEM; @@ -1379,7 +1378,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) == 0)) + if ((fsl_req_to_dtd(udc, req) == 0)) fsl_queue_td(ep, req); else /* no mem */ goto stall; @@ -1597,19 +1596,21 @@ static int process_ep_req(struct fsl_udc *udc, int pipe, actual = curr_req->req.length; for (j = 0; j < curr_req->dtd_count; j++) { - remaining_length = (hc32_to_cpu(curr_td->size_ioc_sts) + remaining_length = (hc32_to_cpu(udc, curr_td->size_ioc_sts) & DTD_PACKET_SIZE) >> DTD_LENGTH_BIT_POS; actual -= remaining_length; - errors = hc32_to_cpu(curr_td->size_ioc_sts); + errors = hc32_to_cpu(udc, curr_td->size_ioc_sts); if (errors & DTD_ERROR_MASK) { if (errors & DTD_STATUS_HALTED) { ERR("dTD error %08x QH=%d\n", errors, pipe); /* Clear the errors and Halt condition */ - tmp = hc32_to_cpu(curr_qh->size_ioc_int_sts); + tmp = hc32_to_cpu(udc, + curr_qh->size_ioc_int_sts); tmp &= ~errors; - curr_qh->size_ioc_int_sts = cpu_to_hc32(tmp); + curr_qh->size_ioc_int_sts = cpu_to_hc32(udc, + tmp); status = -EPIPE; /* FIXME: continue with next queued TD? */ @@ -1627,7 +1628,7 @@ static int process_ep_req(struct fsl_udc *udc, int pipe, ERR("Unknown error has occurred (0x%x)!\n", errors); - } else if (hc32_to_cpu(curr_td->size_ioc_sts) + } else if (hc32_to_cpu(udc, curr_td->size_ioc_sts) & DTD_STATUS_ACTIVE) { VDBG("Request not complete"); status = REQ_UNCOMPLETE; @@ -1925,113 +1926,83 @@ 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 *)) +static int fsl_start(struct usb_gadget *gadget, + struct usb_gadget_driver *driver) { - int retval = -ENODEV; - unsigned long flags = 0; - - if (!udc_controller) - return -ENODEV; - - if (!driver || driver->max_speed < USB_SPEED_FULL - || !bind || !driver->disconnect || !driver->setup) - return -EINVAL; - - if (udc_controller->driver) - return -EBUSY; + struct fsl_udc *udc; + unsigned long flags; + udc = container_of(gadget, struct fsl_udc, gadget); /* 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); - if (retval) { - VDBG("bind to %s --> %d", driver->driver.name, retval); - udc_controller->gadget.dev.driver = NULL; - udc_controller->driver = NULL; - goto out; - } + udc->driver = driver; + udc->gadget.dev.driver = &driver->driver; + spin_unlock_irqrestore(&udc->lock, flags); - if (udc_controller->transceiver) { + if (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 (udc_controller->transceiver) { - retval = otg_set_peripheral(udc_controller->transceiver, - &udc_controller->gadget); + if (udc->transceiver) { + int retval; + + retval = otg_set_peripheral(udc->transceiver, + &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; + udc->gadget.dev.driver = 0; + udc->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; + dr_controller_run(udc); + udc->usb_state = USB_STATE_ATTACHED; + udc->ep0_state = WAIT_FOR_SETUP; + udc->ep0_dir = 0; } printk(KERN_INFO "%s: bind to driver %s\n", - udc_controller->gadget.name, driver->driver.name); - -out: - if (retval) - printk(KERN_WARNING "gadget driver register failed %d\n", - retval); - return retval; + udc->gadget.name, driver->driver.name); + return 0; } /* Disconnect from gadget driver */ -static int fsl_stop(struct usb_gadget_driver *driver) +static int fsl_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 (udc_controller->transceiver) - otg_set_peripheral(udc_controller->transceiver, NULL); + udc = container_of(gadget, struct fsl_udc, gadget); + if (udc->transceiver) + otg_set_peripheral(udc->transceiver, NULL); /* 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 = 0; /* 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, + 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); - - /* 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; + spin_unlock_irqrestore(&udc->lock, flags); printk(KERN_WARNING "unregistered gadget driver '%s'\n", driver->driver.name); @@ -2058,8 +2029,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; @@ -2288,7 +2259,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) @@ -2304,10 +2275,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); } /****************************************************************** @@ -2406,6 +2379,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; @@ -2417,21 +2391,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 = otg_get_transceiver(); - if (!udc_controller->transceiver) { + udc->transceiver = otg_get_transceiver(); + if (!udc->transceiver) { ERR("Can't find OTG driver!\n"); ret = -ENODEV; goto err_kfree; @@ -2492,100 +2466,101 @@ 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 (!udc_controller->transceiver) { + if (!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; /* 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; - 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; + ret = device_register(&udc->gadget.dev); if (ret < 0) goto err_free_irq; - if (udc_controller->transceiver) - udc_controller->gadget.is_otg = 1; + if (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].desc = &fsl_ep0_desc; - udc_controller->eps[0].ep.maxpacket = USB_MAX_CTRL_PAYLOAD; + udc->eps[0].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 < (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; + dev_set_drvdata(&pdev->dev, udc); create_proc_file(); 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); @@ -2596,8 +2571,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; } @@ -2606,16 +2580,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(); @@ -2623,17 +2594,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); @@ -2653,7 +2624,9 @@ 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; } @@ -2663,20 +2636,22 @@ 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 = 0; 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 = dev_get_drvdata(dev); u32 mode, usbcmd; mode = fsl_readl(&dr_regs->usbmode) & USB_MODE_CTRL_MODE_MASK; @@ -2712,15 +2687,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 = dev_get_drvdata(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.8.3 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html