diff options
Diffstat (limited to 'drivers/usb/gadget/mv_udc_core.c')
| -rw-r--r-- | drivers/usb/gadget/mv_udc_core.c | 342 |
1 files changed, 116 insertions, 226 deletions
diff --git a/drivers/usb/gadget/mv_udc_core.c b/drivers/usb/gadget/mv_udc_core.c index 6e8b1272ebc..fcff3a571b4 100644 --- a/drivers/usb/gadget/mv_udc_core.c +++ b/drivers/usb/gadget/mv_udc_core.c @@ -20,7 +20,6 @@ #include <linux/slab.h> #include <linux/errno.h> #include <linux/err.h> -#include <linux/init.h> #include <linux/timer.h> #include <linux/list.h> #include <linux/interrupt.h> @@ -61,9 +60,6 @@ static DECLARE_COMPLETION(release_done); static const char driver_name[] = "mv_udc"; static const char driver_desc[] = DRIVER_DESC; -/* controller device global variable */ -static struct mv_udc *the_controller; - static void nuke(struct mv_ep *ep, int status); static void stop_activity(struct mv_udc *udc, struct usb_gadget_driver *driver); @@ -215,6 +211,8 @@ static int process_ep_req(struct mv_udc *udc, int index, * request is still in progress. */ static void done(struct mv_ep *ep, struct mv_req *req, int status) + __releases(&ep->udc->lock) + __acquires(&ep->udc->lock) { struct mv_udc *udc = NULL; unsigned char stopped = ep->stopped; @@ -240,18 +238,7 @@ static void done(struct mv_ep *ep, struct mv_req *req, int status) dma_pool_free(udc->dtd_pool, curr_td, curr_td->td_dma); } - if (req->mapped) { - dma_unmap_single(ep->udc->gadget.dev.parent, - req->req.dma, req->req.length, - ((ep_dir(ep) == EP_DIR_IN) ? - DMA_TO_DEVICE : DMA_FROM_DEVICE)); - req->req.dma = DMA_ADDR_INVALID; - req->mapped = 0; - } else - dma_sync_single_for_cpu(ep->udc->gadget.dev.parent, - req->req.dma, req->req.length, - ((ep_dir(ep) == EP_DIR_IN) ? - DMA_TO_DEVICE : DMA_FROM_DEVICE)); + usb_gadget_unmap_request(&udc->gadget, &req->req, ep_dir(ep)); if (status && (status != -ESHUTDOWN)) dev_info(&udc->dev->dev, "complete %s req %p stat %d len %u/%u", @@ -735,21 +722,9 @@ mv_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) req->ep = ep; /* map virtual address to hardware */ - if (req->req.dma == DMA_ADDR_INVALID) { - req->req.dma = dma_map_single(ep->udc->gadget.dev.parent, - req->req.buf, - req->req.length, ep_dir(ep) - ? DMA_TO_DEVICE - : DMA_FROM_DEVICE); - req->mapped = 1; - } else { - dma_sync_single_for_device(ep->udc->gadget.dev.parent, - req->req.dma, req->req.length, - ep_dir(ep) - ? DMA_TO_DEVICE - : DMA_FROM_DEVICE); - req->mapped = 0; - } + retval = usb_gadget_map_request(&udc->gadget, _req, ep_dir(ep)); + if (retval) + return retval; req->req.status = -EINPROGRESS; req->req.actual = 0; @@ -783,18 +758,7 @@ mv_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) return 0; err_unmap_dma: - if (req->mapped) { - dma_unmap_single(ep->udc->gadget.dev.parent, - req->req.dma, req->req.length, - ((ep_dir(ep) == EP_DIR_IN) ? - DMA_TO_DEVICE : DMA_FROM_DEVICE)); - req->req.dma = DMA_ADDR_INVALID; - req->mapped = 0; - } else - dma_sync_single_for_cpu(ep->udc->gadget.dev.parent, - req->req.dma, req->req.length, - ((ep_dir(ep) == EP_DIR_IN) ? - DMA_TO_DEVICE : DMA_FROM_DEVICE)); + usb_gadget_unmap_request(&udc->gadget, _req, ep_dir(ep)); return retval; } @@ -1009,18 +973,12 @@ static struct usb_ep_ops mv_ep_ops = { static void udc_clock_enable(struct mv_udc *udc) { - unsigned int i; - - for (i = 0; i < udc->clknum; i++) - clk_prepare_enable(udc->clk[i]); + clk_prepare_enable(udc->clk); } static void udc_clock_disable(struct mv_udc *udc) { - unsigned int i; - - for (i = 0; i < udc->clknum; i++) - clk_disable_unprepare(udc->clk[i]); + clk_disable_unprepare(udc->clk); } static void udc_stop(struct mv_udc *udc) @@ -1268,9 +1226,8 @@ static int mv_udc_pullup(struct usb_gadget *gadget, int is_on) return retval; } -static int mv_udc_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)); -static int mv_udc_stop(struct usb_gadget_driver *driver); +static int mv_udc_start(struct usb_gadget *, struct usb_gadget_driver *); +static int mv_udc_stop(struct usb_gadget *, struct usb_gadget_driver *); /* device controller usb_gadget_ops structure */ static const struct usb_gadget_ops mv_ops = { @@ -1285,8 +1242,8 @@ static const struct usb_gadget_ops mv_ops = { /* D+ pullup, software-controlled connect/disconnect to USB host */ .pullup = mv_udc_pullup, - .start = mv_udc_start, - .stop = mv_udc_stop, + .udc_start = mv_udc_start, + .udc_stop = mv_udc_stop, }; static int eps_init(struct mv_udc *udc) @@ -1303,7 +1260,7 @@ static int eps_init(struct mv_udc *udc) ep->ep.ops = &mv_ep_ops; ep->wedge = 0; ep->stopped = 0; - ep->ep.maxpacket = EP0_MAX_PKT_SIZE; + usb_ep_set_maxpacket_limit(&ep->ep, EP0_MAX_PKT_SIZE); ep->ep_num = 0; ep->ep.desc = &mv_ep0_desc; INIT_LIST_HEAD(&ep->queue); @@ -1326,7 +1283,7 @@ static int eps_init(struct mv_udc *udc) ep->ep.ops = &mv_ep_ops; ep->stopped = 0; - ep->ep.maxpacket = (unsigned short) ~0; + usb_ep_set_maxpacket_limit(&ep->ep, (unsigned short) ~0); ep->ep_num = i / 2; INIT_LIST_HEAD(&ep->queue); @@ -1373,15 +1330,14 @@ static void stop_activity(struct mv_udc *udc, struct usb_gadget_driver *driver) } } -static int mv_udc_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)) +static int mv_udc_start(struct usb_gadget *gadget, + struct usb_gadget_driver *driver) { - struct mv_udc *udc = the_controller; + struct mv_udc *udc; int retval = 0; unsigned long flags; - if (!udc) - return -ENODEV; + udc = container_of(gadget, struct mv_udc, gadget); if (udc->driver) return -EBUSY; @@ -1391,7 +1347,6 @@ static int mv_udc_start(struct usb_gadget_driver *driver, /* hook up the driver ... */ driver->driver.bus = NULL; udc->driver = driver; - udc->gadget.dev.driver = &driver->driver; udc->usb_state = USB_STATE_ATTACHED; udc->ep0_state = WAIT_FOR_SETUP; @@ -1399,26 +1354,13 @@ static int mv_udc_start(struct usb_gadget_driver *driver, spin_unlock_irqrestore(&udc->lock, flags); - retval = bind(&udc->gadget, driver); - if (retval) { - dev_err(&udc->dev->dev, "bind to driver %s --> %d\n", - driver->driver.name, retval); - udc->driver = NULL; - udc->gadget.dev.driver = NULL; - return retval; - } - - if (!IS_ERR_OR_NULL(udc->transceiver)) { + if (udc->transceiver) { retval = otg_set_peripheral(udc->transceiver->otg, &udc->gadget); if (retval) { dev_err(&udc->dev->dev, "unable to register peripheral to otg\n"); - if (driver->unbind) { - driver->unbind(&udc->gadget); - udc->gadget.dev.driver = NULL; - udc->driver = NULL; - } + udc->driver = NULL; return retval; } } @@ -1433,13 +1375,13 @@ static int mv_udc_start(struct usb_gadget_driver *driver, return 0; } -static int mv_udc_stop(struct usb_gadget_driver *driver) +static int mv_udc_stop(struct usb_gadget *gadget, + struct usb_gadget_driver *driver) { - struct mv_udc *udc = the_controller; + struct mv_udc *udc; unsigned long flags; - if (!udc) - return -ENODEV; + udc = container_of(gadget, struct mv_udc, gadget); spin_lock_irqsave(&udc->lock, flags); @@ -1454,8 +1396,6 @@ static int mv_udc_stop(struct usb_gadget_driver *driver) spin_unlock_irqrestore(&udc->lock, flags); /* unbind gadget driver */ - driver->unbind(&udc->gadget); - udc->gadget.dev.driver = NULL; udc->driver = NULL; return 0; @@ -1472,10 +1412,13 @@ static void mv_set_ptc(struct mv_udc *udc, u32 mode) static void prime_status_complete(struct usb_ep *ep, struct usb_request *_req) { - struct mv_udc *udc = the_controller; + struct mv_ep *mvep = container_of(ep, struct mv_ep, ep); struct mv_req *req = container_of(_req, struct mv_req, req); + struct mv_udc *udc; unsigned long flags; + udc = mvep->udc; + dev_info(&udc->dev->dev, "switch to test mode %d\n", req->test_mode); spin_lock_irqsave(&udc->lock, flags); @@ -1543,14 +1486,7 @@ udc_prime_status(struct mv_udc *udc, u8 direction, u16 status, bool empty) return 0; out: - if (req->mapped) { - dma_unmap_single(ep->udc->gadget.dev.parent, - req->req.dma, req->req.length, - ((ep_dir(ep) == EP_DIR_IN) ? - DMA_TO_DEVICE : DMA_FROM_DEVICE)); - req->req.dma = DMA_ADDR_INVALID; - req->mapped = 0; - } + usb_gadget_unmap_request(&udc->gadget, &req->req, ep_dir(ep)); return retval; } @@ -1710,6 +1646,8 @@ out: static void handle_setup_packet(struct mv_udc *udc, u8 ep_num, struct usb_ctrlrequest *setup) + __releases(&ep->udc->lock) + __acquires(&ep->udc->lock) { bool delegate = false; @@ -1906,7 +1844,7 @@ static void irq_process_tr_complete(struct mv_udc *udc) } } -void irq_process_reset(struct mv_udc *udc) +static void irq_process_reset(struct mv_udc *udc) { u32 tmp; unsigned int loops; @@ -2123,15 +2061,18 @@ static void mv_udc_vbus_work(struct work_struct *work) /* release device structure */ static void gadget_release(struct device *_dev) { - struct mv_udc *udc = the_controller; + struct mv_udc *udc; + + udc = dev_get_drvdata(_dev); complete(udc->done); } -static int mv_udc_remove(struct platform_device *dev) +static int mv_udc_remove(struct platform_device *pdev) { - struct mv_udc *udc = the_controller; - int clk_i; + struct mv_udc *udc; + + udc = platform_get_drvdata(pdev); usb_del_gadget_udc(&udc->gadget); @@ -2140,129 +2081,95 @@ static int mv_udc_remove(struct platform_device *dev) destroy_workqueue(udc->qwork); } - /* - * If we have transceiver inited, - * then vbus irq will not be requested in udc driver. - */ - if (udc->pdata && udc->pdata->vbus - && udc->clock_gating && IS_ERR_OR_NULL(udc->transceiver)) - free_irq(udc->pdata->vbus->irq, &dev->dev); - /* free memory allocated in probe */ if (udc->dtd_pool) dma_pool_destroy(udc->dtd_pool); if (udc->ep_dqh) - dma_free_coherent(&dev->dev, udc->ep_dqh_size, + dma_free_coherent(&pdev->dev, udc->ep_dqh_size, udc->ep_dqh, udc->ep_dqh_dma); - kfree(udc->eps); - - if (udc->irq) - free_irq(udc->irq, &dev->dev); - mv_udc_disable(udc); - if (udc->cap_regs) - iounmap(udc->cap_regs); - - if (udc->phy_regs) - iounmap(udc->phy_regs); - - if (udc->status_req) { - kfree(udc->status_req->req.buf); - kfree(udc->status_req); - } - - for (clk_i = 0; clk_i <= udc->clknum; clk_i++) - clk_put(udc->clk[clk_i]); - - device_unregister(&udc->gadget.dev); - /* free dev, wait for the release() finished */ wait_for_completion(udc->done); - kfree(udc); - - the_controller = NULL; return 0; } -static int mv_udc_probe(struct platform_device *dev) +static int mv_udc_probe(struct platform_device *pdev) { - struct mv_usb_platform_data *pdata = dev->dev.platform_data; + struct mv_usb_platform_data *pdata = dev_get_platdata(&pdev->dev); struct mv_udc *udc; int retval = 0; - int clk_i = 0; struct resource *r; size_t size; if (pdata == NULL) { - dev_err(&dev->dev, "missing platform_data\n"); + dev_err(&pdev->dev, "missing platform_data\n"); return -ENODEV; } - size = sizeof(*udc) + sizeof(struct clk *) * pdata->clknum; - udc = kzalloc(size, GFP_KERNEL); + udc = devm_kzalloc(&pdev->dev, sizeof(*udc), GFP_KERNEL); if (udc == NULL) { - dev_err(&dev->dev, "failed to allocate memory for udc\n"); + dev_err(&pdev->dev, "failed to allocate memory for udc\n"); return -ENOMEM; } - the_controller = udc; udc->done = &release_done; - udc->pdata = dev->dev.platform_data; + udc->pdata = dev_get_platdata(&pdev->dev); spin_lock_init(&udc->lock); - udc->dev = dev; + udc->dev = pdev; -#ifdef CONFIG_USB_OTG_UTILS - if (pdata->mode == MV_USB_MODE_OTG) - udc->transceiver = usb_get_phy(USB_PHY_TYPE_USB2); -#endif + if (pdata->mode == MV_USB_MODE_OTG) { + udc->transceiver = devm_usb_get_phy(&pdev->dev, + USB_PHY_TYPE_USB2); + if (IS_ERR(udc->transceiver)) { + retval = PTR_ERR(udc->transceiver); + + if (retval == -ENXIO) + return retval; - udc->clknum = pdata->clknum; - for (clk_i = 0; clk_i < udc->clknum; clk_i++) { - udc->clk[clk_i] = clk_get(&dev->dev, pdata->clkname[clk_i]); - if (IS_ERR(udc->clk[clk_i])) { - retval = PTR_ERR(udc->clk[clk_i]); - goto err_put_clk; + udc->transceiver = NULL; + return -EPROBE_DEFER; } } + /* udc only have one sysclk. */ + udc->clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(udc->clk)) + return PTR_ERR(udc->clk); + r = platform_get_resource_byname(udc->dev, IORESOURCE_MEM, "capregs"); if (r == NULL) { - dev_err(&dev->dev, "no I/O memory resource defined\n"); - retval = -ENODEV; - goto err_put_clk; + dev_err(&pdev->dev, "no I/O memory resource defined\n"); + return -ENODEV; } udc->cap_regs = (struct mv_cap_regs __iomem *) - ioremap(r->start, resource_size(r)); + devm_ioremap(&pdev->dev, r->start, resource_size(r)); if (udc->cap_regs == NULL) { - dev_err(&dev->dev, "failed to map I/O memory\n"); - retval = -EBUSY; - goto err_put_clk; + dev_err(&pdev->dev, "failed to map I/O memory\n"); + return -EBUSY; } r = platform_get_resource_byname(udc->dev, IORESOURCE_MEM, "phyregs"); if (r == NULL) { - dev_err(&dev->dev, "no phy I/O memory resource defined\n"); - retval = -ENODEV; - goto err_iounmap_capreg; + dev_err(&pdev->dev, "no phy I/O memory resource defined\n"); + return -ENODEV; } udc->phy_regs = ioremap(r->start, resource_size(r)); if (udc->phy_regs == NULL) { - dev_err(&dev->dev, "failed to map phy I/O memory\n"); - retval = -EBUSY; - goto err_iounmap_capreg; + dev_err(&pdev->dev, "failed to map phy I/O memory\n"); + return -EBUSY; } /* we will acces controller register, so enable the clk */ retval = mv_udc_enable_internal(udc); if (retval) - goto err_iounmap_phyreg; + return retval; udc->op_regs = (struct mv_op_regs __iomem *)((unsigned long)udc->cap_regs @@ -2279,11 +2186,11 @@ static int mv_udc_probe(struct platform_device *dev) size = udc->max_eps * sizeof(struct mv_dqh) *2; size = (size + DQH_ALIGNMENT - 1) & ~(DQH_ALIGNMENT - 1); - udc->ep_dqh = dma_alloc_coherent(&dev->dev, size, + udc->ep_dqh = dma_alloc_coherent(&pdev->dev, size, &udc->ep_dqh_dma, GFP_KERNEL); if (udc->ep_dqh == NULL) { - dev_err(&dev->dev, "allocate dQH memory failed\n"); + dev_err(&pdev->dev, "allocate dQH memory failed\n"); retval = -ENOMEM; goto err_disable_clock; } @@ -2291,7 +2198,7 @@ static int mv_udc_probe(struct platform_device *dev) /* create dTD dma_pool resource */ udc->dtd_pool = dma_pool_create("mv_dtd", - &dev->dev, + &pdev->dev, sizeof(struct mv_dtd), DTD_ALIGNMENT, DMA_BOUNDARY); @@ -2302,19 +2209,20 @@ static int mv_udc_probe(struct platform_device *dev) } size = udc->max_eps * sizeof(struct mv_ep) *2; - udc->eps = kzalloc(size, GFP_KERNEL); + udc->eps = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); if (udc->eps == NULL) { - dev_err(&dev->dev, "allocate ep memory failed\n"); + dev_err(&pdev->dev, "allocate ep memory failed\n"); retval = -ENOMEM; goto err_destroy_dma; } /* initialize ep0 status request structure */ - udc->status_req = kzalloc(sizeof(struct mv_req), GFP_KERNEL); + udc->status_req = devm_kzalloc(&pdev->dev, sizeof(struct mv_req), + GFP_KERNEL); if (!udc->status_req) { - dev_err(&dev->dev, "allocate status_req memory failed\n"); + dev_err(&pdev->dev, "allocate status_req memory failed\n"); retval = -ENOMEM; - goto err_free_eps; + goto err_destroy_dma; } INIT_LIST_HEAD(&udc->status_req->queue); @@ -2329,17 +2237,17 @@ static int mv_udc_probe(struct platform_device *dev) r = platform_get_resource(udc->dev, IORESOURCE_IRQ, 0); if (r == NULL) { - dev_err(&dev->dev, "no IRQ resource defined\n"); + dev_err(&pdev->dev, "no IRQ resource defined\n"); retval = -ENODEV; - goto err_free_status_req; + goto err_destroy_dma; } udc->irq = r->start; - if (request_irq(udc->irq, mv_udc_irq, + if (devm_request_irq(&pdev->dev, udc->irq, mv_udc_irq, IRQF_SHARED, driver_name, udc)) { - dev_err(&dev->dev, "Request irq %d for UDC failed\n", + dev_err(&pdev->dev, "Request irq %d for UDC failed\n", udc->irq); retval = -ENODEV; - goto err_free_status_req; + goto err_destroy_dma; } /* initialize gadget structure */ @@ -2350,27 +2258,20 @@ static int mv_udc_probe(struct platform_device *dev) udc->gadget.max_speed = USB_SPEED_HIGH; /* support dual speed */ /* the "gadget" abstracts/virtualizes the controller */ - dev_set_name(&udc->gadget.dev, "gadget"); - udc->gadget.dev.parent = &dev->dev; - udc->gadget.dev.dma_mask = dev->dev.dma_mask; - udc->gadget.dev.release = gadget_release; udc->gadget.name = driver_name; /* gadget name */ - retval = device_register(&udc->gadget.dev); - if (retval) - goto err_free_irq; - eps_init(udc); /* VBUS detect: we can disable/enable clock on demand.*/ - if (!IS_ERR_OR_NULL(udc->transceiver)) + if (udc->transceiver) udc->clock_gating = 1; else if (pdata->vbus) { udc->clock_gating = 1; - retval = request_threaded_irq(pdata->vbus->irq, NULL, + retval = devm_request_threaded_irq(&pdev->dev, + pdata->vbus->irq, NULL, mv_udc_vbus_irq, IRQF_ONESHOT, "vbus", udc); if (retval) { - dev_info(&dev->dev, + dev_info(&pdev->dev, "Can not request irq for VBUS, " "disable clock gating\n"); udc->clock_gating = 0; @@ -2378,9 +2279,9 @@ static int mv_udc_probe(struct platform_device *dev) udc->qwork = create_singlethread_workqueue("mv_udc_queue"); if (!udc->qwork) { - dev_err(&dev->dev, "cannot create workqueue\n"); + dev_err(&pdev->dev, "cannot create workqueue\n"); retval = -ENOMEM; - goto err_unregister; + goto err_destroy_dma; } INIT_WORK(&udc->vbus_work, mv_udc_vbus_work); @@ -2396,53 +2297,39 @@ static int mv_udc_probe(struct platform_device *dev) else udc->vbus_active = 1; - retval = usb_add_gadget_udc(&dev->dev, &udc->gadget); + retval = usb_add_gadget_udc_release(&pdev->dev, &udc->gadget, + gadget_release); if (retval) - goto err_unregister; + goto err_create_workqueue; - dev_info(&dev->dev, "successful probe UDC device %s clock gating.\n", + platform_set_drvdata(pdev, udc); + dev_info(&pdev->dev, "successful probe UDC device %s clock gating.\n", udc->clock_gating ? "with" : "without"); return 0; -err_unregister: - if (udc->pdata && udc->pdata->vbus - && udc->clock_gating && IS_ERR_OR_NULL(udc->transceiver)) - free_irq(pdata->vbus->irq, &dev->dev); - device_unregister(&udc->gadget.dev); -err_free_irq: - free_irq(udc->irq, &dev->dev); -err_free_status_req: - kfree(udc->status_req->req.buf); - kfree(udc->status_req); -err_free_eps: - kfree(udc->eps); +err_create_workqueue: + destroy_workqueue(udc->qwork); err_destroy_dma: dma_pool_destroy(udc->dtd_pool); err_free_dma: - dma_free_coherent(&dev->dev, udc->ep_dqh_size, + dma_free_coherent(&pdev->dev, udc->ep_dqh_size, udc->ep_dqh, udc->ep_dqh_dma); err_disable_clock: mv_udc_disable_internal(udc); -err_iounmap_phyreg: - iounmap(udc->phy_regs); -err_iounmap_capreg: - iounmap(udc->cap_regs); -err_put_clk: - for (clk_i--; clk_i >= 0; clk_i--) - clk_put(udc->clk[clk_i]); - the_controller = NULL; - kfree(udc); + return retval; } #ifdef CONFIG_PM -static int mv_udc_suspend(struct device *_dev) +static int mv_udc_suspend(struct device *dev) { - struct mv_udc *udc = the_controller; + struct mv_udc *udc; + + udc = dev_get_drvdata(dev); /* if OTG is enabled, the following will be done in OTG driver*/ - if (!IS_ERR_OR_NULL(udc->transceiver)) + if (udc->transceiver) return 0; if (udc->pdata->vbus && udc->pdata->vbus->poll) @@ -2469,13 +2356,15 @@ static int mv_udc_suspend(struct device *_dev) return 0; } -static int mv_udc_resume(struct device *_dev) +static int mv_udc_resume(struct device *dev) { - struct mv_udc *udc = the_controller; + struct mv_udc *udc; int retval; + udc = dev_get_drvdata(dev); + /* if OTG is enabled, the following will be done in OTG driver*/ - if (!IS_ERR_OR_NULL(udc->transceiver)) + if (udc->transceiver) return 0; if (!udc->clock_gating) { @@ -2499,11 +2388,12 @@ static const struct dev_pm_ops mv_udc_pm_ops = { }; #endif -static void mv_udc_shutdown(struct platform_device *dev) +static void mv_udc_shutdown(struct platform_device *pdev) { - struct mv_udc *udc = the_controller; + struct mv_udc *udc; u32 mode; + udc = platform_get_drvdata(pdev); /* reset controller mode to IDLE */ mv_udc_enable(udc); mode = readl(&udc->op_regs->usbmode); @@ -2514,7 +2404,7 @@ static void mv_udc_shutdown(struct platform_device *dev) static struct platform_driver udc_driver = { .probe = mv_udc_probe, - .remove = __exit_p(mv_udc_remove), + .remove = mv_udc_remove, .shutdown = mv_udc_shutdown, .driver = { .owner = THIS_MODULE, |
