]> Git Repo - linux.git/commitdiff
Merge tag 'gadget-for-v3.9' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi...
authorGreg Kroah-Hartman <[email protected]>
Fri, 25 Jan 2013 17:08:05 +0000 (09:08 -0800)
committerGreg Kroah-Hartman <[email protected]>
Fri, 25 Jan 2013 17:08:05 +0000 (09:08 -0800)
Felipe writes:
usb: gadget: patches for v3.9 merge window

finally getting rid of the old ->start()/->stop() methods
in favor of the better and improved ->udc_start()/->udc_stop().

There were surprisingly quite a few users left, but all of them
have been converted.

f_mass_storage removed some dead code, which is always great ;-)

There's also a big cleanup to the gadget framework from Sebastian
which gets us a lot closer to having only function drivers in
kernel and move over to configfs-based binding.

Other than these, there's the usual set of cleanups: s3c UDCs are
moving over to devm_regulator_bulk_get() API, at91_udc removed
an unnecessary check for work_pending() before scheduling and
there's the removal of an unused variable from uac2_pcm_trigger().

1  2 
drivers/usb/gadget/amd5536udc.c
drivers/usb/gadget/mv_udc_core.c
drivers/usb/gadget/s3c-hsotg.c
drivers/usb/gadget/u_serial.c
drivers/usb/host/ehci-mv.c
drivers/usb/otg/mv_otg.c
drivers/usb/renesas_usbhs/mod_gadget.c

index d9f6b9372491d487a817de021f8bfc660d04cd00,3dac001aebf0db3771f963fcb78bf7bd65f543bd..75973f33a4c80590ab6f8a012f9a1dec58c7ccbe
@@@ -1400,15 -1400,16 +1400,16 @@@ static int udc_wakeup(struct usb_gadge
        return 0;
  }
  
- static int amd5536_start(struct usb_gadget_driver *driver,
-               int (*bind)(struct usb_gadget *, struct usb_gadget_driver *));
- static int amd5536_stop(struct usb_gadget_driver *driver);
+ static int amd5536_udc_start(struct usb_gadget *g,
+               struct usb_gadget_driver *driver);
+ static int amd5536_udc_stop(struct usb_gadget *g,
+               struct usb_gadget_driver *driver);
  /* gadget operations */
  static const struct usb_gadget_ops udc_ops = {
        .wakeup         = udc_wakeup,
        .get_frame      = udc_get_frame,
-       .start          = amd5536_start,
-       .stop           = amd5536_stop,
+       .udc_start      = amd5536_udc_start,
+       .udc_stop       = amd5536_udc_stop,
  };
  
  /* Setups endpoint parameters, adds endpoints to linked list */
@@@ -1913,41 -1914,22 +1914,22 @@@ static int setup_ep0(struct udc *dev
  }
  
  /* Called by gadget driver to register itself */
- static int amd5536_start(struct usb_gadget_driver *driver,
-               int (*bind)(struct usb_gadget *, struct usb_gadget_driver *))
+ static int amd5536_udc_start(struct usb_gadget *g,
+               struct usb_gadget_driver *driver)
  {
-       struct udc              *dev = udc;
-       int                     retval;
+       struct udc *dev = to_amd5536_udc(g);
        u32 tmp;
  
-       if (!driver || !bind || !driver->setup
-                       || driver->max_speed < USB_SPEED_HIGH)
-               return -EINVAL;
-       if (!dev)
-               return -ENODEV;
-       if (dev->driver)
-               return -EBUSY;
        driver->driver.bus = NULL;
        dev->driver = driver;
        dev->gadget.dev.driver = &driver->driver;
  
-       retval = bind(&dev->gadget, driver);
        /* Some gadget drivers use both ep0 directions.
         * NOTE: to gadget driver, ep0 is just one endpoint...
         */
        dev->ep[UDC_EP0OUT_IX].ep.driver_data =
                dev->ep[UDC_EP0IN_IX].ep.driver_data;
  
-       if (retval) {
-               DBG(dev, "binding to %s returning %d\n",
-                               driver->driver.name, retval);
-               dev->driver = NULL;
-               dev->gadget.dev.driver = NULL;
-               return retval;
-       }
        /* get ready for ep0 traffic */
        setup_ep0(dev);
  
@@@ -1969,14 -1951,9 +1951,9 @@@ __acquires(dev->lock
  {
        int tmp;
  
-       if (dev->gadget.speed != USB_SPEED_UNKNOWN) {
-               spin_unlock(&dev->lock);
-               driver->disconnect(&dev->gadget);
-               spin_lock(&dev->lock);
-       }
        /* empty queues and init hardware */
        udc_basic_init(dev);
        for (tmp = 0; tmp < UDC_EP_NUM; tmp++)
                empty_req_queue(&dev->ep[tmp]);
  
  }
  
  /* Called by gadget driver to unregister itself */
- static int amd5536_stop(struct usb_gadget_driver *driver)
+ static int amd5536_udc_stop(struct usb_gadget *g,
+               struct usb_gadget_driver *driver)
  {
-       struct udc      *dev = udc;
-       unsigned long   flags;
+       struct udc *dev = to_amd5536_udc(g);
+       unsigned long flags;
        u32 tmp;
  
-       if (!dev)
-               return -ENODEV;
-       if (!driver || driver != dev->driver || !driver->unbind)
-               return -EINVAL;
        spin_lock_irqsave(&dev->lock, flags);
        udc_mask_unused_interrupts(dev);
        shutdown(dev, driver);
        spin_unlock_irqrestore(&dev->lock, flags);
  
-       driver->unbind(&dev->gadget);
        dev->gadget.dev.driver = NULL;
        dev->driver = NULL;
  
        tmp |= AMD_BIT(UDC_DEVCTL_SD);
        writel(tmp, &dev->regs->ctl);
  
-       DBG(dev, "%s: unregistered\n", driver->driver.name);
        return 0;
  }
  
@@@ -3231,7 -3200,7 +3200,7 @@@ static int udc_pci_probe
        }
  
        if (!pdev->irq) {
 -              dev_err(&dev->pdev->dev, "irq not set\n");
 +              dev_err(&pdev->dev, "irq not set\n");
                kfree(dev);
                dev = NULL;
                retval = -ENODEV;
        dev->txfifo = (u32 __iomem *)(dev->virt_addr + UDC_TXFIFO_ADDR);
  
        if (request_irq(pdev->irq, udc_irq, IRQF_SHARED, name, dev) != 0) {
 -              dev_dbg(&dev->pdev->dev, "request_irq(%d) fail\n", pdev->irq);
 +              dev_dbg(&pdev->dev, "request_irq(%d) fail\n", pdev->irq);
                kfree(dev);
                dev = NULL;
                retval = -EBUSY;
index 6e8b1272ebceb3e1317e092ae7243e584c6eeda4,67d72f97a09b962f2e90d7be1fe7994600b461d7..c8cf959057fe186962960b1e177a72114d8b37d6
@@@ -61,9 -61,6 +61,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);
  
@@@ -1012,7 -1009,7 +1009,7 @@@ static void udc_clock_enable(struct mv_
        unsigned int i;
  
        for (i = 0; i < udc->clknum; i++)
 -              clk_enable(udc->clk[i]);
 +              clk_prepare_enable(udc->clk[i]);
  }
  
  static void udc_clock_disable(struct mv_udc *udc)
        unsigned int i;
  
        for (i = 0; i < udc->clknum; i++)
 -              clk_disable(udc->clk[i]);
 +              clk_disable_unprepare(udc->clk[i]);
  }
  
  static void udc_stop(struct mv_udc *udc)
@@@ -1268,9 -1265,8 +1265,8 @@@ static int mv_udc_pullup(struct usb_gad
        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 = {
  
  
        /* 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)
@@@ -1373,15 -1369,14 +1369,14 @@@ static void stop_activity(struct mv_ud
        }
  }
  
- 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;
  
        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;
+                       udc->gadget.dev.driver = NULL;
                        return retval;
                }
        }
        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);
  
        spin_unlock_irqrestore(&udc->lock, flags);
  
        /* unbind gadget driver */
-       driver->unbind(&udc->gadget);
        udc->gadget.dev.driver = NULL;
        udc->driver = NULL;
  
@@@ -1472,10 -1454,13 +1454,13 @@@ static void mv_set_ptc(struct mv_udc *u
  
  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);
@@@ -2123,15 -2108,18 +2108,18 @@@ static void mv_udc_vbus_work(struct wor
  /* 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);
  
                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 = pdev->dev.platform_data;
        struct mv_udc *udc;
        int retval = 0;
        int clk_i = 0;
        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, size, 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 = pdev->dev.platform_data;
        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);
+       if (pdata->mode == MV_USB_MODE_OTG) {
+               udc->transceiver = devm_usb_get_phy(&pdev->dev,
+                                       USB_PHY_TYPE_USB2);
+               if (IS_ERR_OR_NULL(udc->transceiver)) {
+                       udc->transceiver = NULL;
+                       return -ENODEV;
+               }
+       }
  #endif
  
        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]);
+               udc->clk[clk_i] = devm_clk_get(&pdev->dev,
+                                       pdata->clkname[clk_i]);
                if (IS_ERR(udc->clk[clk_i])) {
                        retval = PTR_ERR(udc->clk[clk_i]);
-                       goto err_put_clk;
+                       return retval;
                }
        }
  
        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
  
        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;
        }
  
        /* 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);
        }
  
        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);
  
  
        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 */
  
        /* 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.parent = &pdev->dev;
+       udc->gadget.dev.dma_mask = pdev->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;
+               goto err_destroy_dma;
  
        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;
  
                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;
                }
        else
                udc->vbus_active = 1;
  
-       retval = usb_add_gadget_udc(&dev->dev, &udc->gadget);
+       retval = usb_add_gadget_udc(&pdev->dev, &udc->gadget);
        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_create_workqueue:
+       destroy_workqueue(udc->qwork);
  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_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)
        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 -2450,12 +2450,12 @@@ static const struct dev_pm_ops mv_udc_p
  };
  #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);
  
  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,
index 439c3f972f8c28d18fb34c691ab9cf8b51559098,26033b50b54a5aca058c381f180c492f4f315f3d..e1cd0f1adfb9d9509bc1c306e11e1285d219d083
@@@ -3055,7 -3055,7 +3055,7 @@@ static int s3c_hsotg_pullup(struct usb_
        return 0;
  }
  
- static struct usb_gadget_ops s3c_hsotg_gadget_ops = {
+ static const struct usb_gadget_ops s3c_hsotg_gadget_ops = {
        .get_frame      = s3c_hsotg_gadget_getframe,
        .udc_start              = s3c_hsotg_udc_start,
        .udc_stop               = s3c_hsotg_udc_stop,
@@@ -3477,11 -3477,12 +3477,11 @@@ static void s3c_hsotg_delete_debug(stru
  /**
   * s3c_hsotg_release - release callback for hsotg device
   * @dev: Device to for which release is called
 + *
 + * Nothing to do as the resource is allocated using devm_ API.
   */
  static void s3c_hsotg_release(struct device *dev)
  {
 -      struct s3c_hsotg *hsotg = dev_get_drvdata(dev);
 -
 -      kfree(hsotg);
  }
  
  /**
@@@ -3572,7 -3573,7 +3572,7 @@@ static int s3c_hsotg_probe(struct platf
        for (i = 0; i < ARRAY_SIZE(hsotg->supplies); i++)
                hsotg->supplies[i].supply = s3c_hsotg_supply_names[i];
  
-       ret = regulator_bulk_get(dev, ARRAY_SIZE(hsotg->supplies),
+       ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(hsotg->supplies),
                                 hsotg->supplies);
        if (ret) {
                dev_err(dev, "failed to request supplies: %d\n", ret);
@@@ -3662,8 -3663,6 +3662,6 @@@ err_ep_mem
        kfree(eps);
  err_supplies:
        s3c_hsotg_phy_disable(hsotg);
-       regulator_bulk_free(ARRAY_SIZE(hsotg->supplies), hsotg->supplies);
  err_clk:
        clk_disable_unprepare(hsotg->clk);
  
@@@ -3688,7 -3687,6 +3686,6 @@@ static int s3c_hsotg_remove(struct plat
        }
  
        s3c_hsotg_phy_disable(hsotg);
-       regulator_bulk_free(ARRAY_SIZE(hsotg->supplies), hsotg->supplies);
  
        clk_disable_unprepare(hsotg->clk);
  
index 598dcc1212f0bb231830f0022961f67e37b6b0fa,9e14079b63091f660c4502200ab98a0a418cda96..588a9be18ef81c77c8cdbf1a06e547c67350c14d
@@@ -26,6 -26,7 +26,7 @@@
  #include <linux/tty_flip.h>
  #include <linux/slab.h>
  #include <linux/export.h>
+ #include <linux/module.h>
  
  #include "u_serial.h"
  
   * "serial port" functionality through the USB gadget stack.  Each such
   * port is exposed through a /dev/ttyGS* node.
   *
-  * After initialization (gserial_setup), these TTY port devices stay
-  * available until they are removed (gserial_cleanup).  Each one may be
-  * connected to a USB function (gserial_connect), or disconnected (with
-  * gserial_disconnect) when the USB host issues a config change event.
-  * Data can only flow when the port is connected to the host.
+  * After this module has been loaded, the individual TTY port can be requested
+  * (gserial_alloc_line()) and it will stay available until they are removed
+  * (gserial_free_line()). Each one may be connected to a USB function
+  * (gserial_connect), or disconnected (with gserial_disconnect) when the USB
+  * host issues a config change event. Data can only flow when the port is
+  * connected to the host.
   *
   * A given TTY port can be made available in multiple configurations.
   * For example, each one might expose a ttyGS0 node which provides a
@@@ -119,13 -121,10 +121,10 @@@ struct gs_port 
        struct usb_cdc_line_coding port_line_coding;    /* 8-N-1 etc */
  };
  
- /* increase N_PORTS if you need more */
- #define N_PORTS               4
  static struct portmaster {
        struct mutex    lock;                   /* protect open/close */
        struct gs_port  *port;
- } ports[N_PORTS];
- static unsigned       n_ports;
+ } ports[MAX_U_SERIAL_PORTS];
  
  #define GS_CLOSE_TIMEOUT              15              /* seconds */
  
@@@ -309,6 -308,7 +308,7 @@@ gs_alloc_req(struct usb_ep *ep, unsigne
  
        return req;
  }
+ EXPORT_SYMBOL_GPL(gs_alloc_req);
  
  /*
   * gs_free_req
@@@ -320,6 -320,7 +320,7 @@@ void gs_free_req(struct usb_ep *ep, str
        kfree(req->buf);
        usb_ep_free_request(ep, req);
  }
+ EXPORT_SYMBOL_GPL(gs_free_req);
  
  /*
   * gs_send_packet
@@@ -887,7 -888,7 +888,7 @@@ static void gs_close(struct tty_struct 
        pr_debug("gs_close: ttyGS%d (%p,%p) done!\n",
                        port->port_num, tty, file);
  
 -      wake_up_interruptible(&port->port.close_wait);
 +      wake_up(&port->port.close_wait);
  exit:
        spin_unlock_irq(&port->port_lock);
  }
@@@ -1030,10 -1031,19 +1031,19 @@@ static in
  gs_port_alloc(unsigned port_num, struct usb_cdc_line_coding *coding)
  {
        struct gs_port  *port;
+       int             ret = 0;
+       mutex_lock(&ports[port_num].lock);
+       if (ports[port_num].port) {
+               ret = -EBUSY;
+               goto out;
+       }
  
        port = kzalloc(sizeof(struct gs_port), GFP_KERNEL);
-       if (port == NULL)
-               return -ENOMEM;
+       if (port == NULL) {
+               ret = -ENOMEM;
+               goto out;
+       }
  
        tty_port_init(&port->port);
        spin_lock_init(&port->port_lock);
        port->port_line_coding = *coding;
  
        ports[port_num].port = port;
-       return 0;
- }
- /**
-  * gserial_setup - initialize TTY driver for one or more ports
-  * @g: gadget to associate with these ports
-  * @count: how many ports to support
-  * Context: may sleep
-  *
-  * The TTY stack needs to know in advance how many devices it should
-  * plan to manage.  Use this call to set up the ports you will be
-  * exporting through USB.  Later, connect them to functions based
-  * on what configuration is activated by the USB host; and disconnect
-  * them as appropriate.
-  *
-  * An example would be a two-configuration device in which both
-  * configurations expose port 0, but through different functions.
-  * One configuration could even expose port 1 while the other
-  * one doesn't.
-  *
-  * Returns negative errno or zero.
-  */
- int gserial_setup(struct usb_gadget *g, unsigned count)
- {
-       unsigned                        i;
-       struct usb_cdc_line_coding      coding;
-       int                             status;
-       if (count == 0 || count > N_PORTS)
-               return -EINVAL;
-       gs_tty_driver = alloc_tty_driver(count);
-       if (!gs_tty_driver)
-               return -ENOMEM;
-       gs_tty_driver->driver_name = "g_serial";
-       gs_tty_driver->name = PREFIX;
-       /* uses dynamically assigned dev_t values */
-       gs_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
-       gs_tty_driver->subtype = SERIAL_TYPE_NORMAL;
-       gs_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
-       gs_tty_driver->init_termios = tty_std_termios;
-       /* 9600-8-N-1 ... matches defaults expected by "usbser.sys" on
-        * MS-Windows.  Otherwise, most of these flags shouldn't affect
-        * anything unless we were to actually hook up to a serial line.
-        */
-       gs_tty_driver->init_termios.c_cflag =
-                       B9600 | CS8 | CREAD | HUPCL | CLOCAL;
-       gs_tty_driver->init_termios.c_ispeed = 9600;
-       gs_tty_driver->init_termios.c_ospeed = 9600;
-       coding.dwDTERate = cpu_to_le32(9600);
-       coding.bCharFormat = 8;
-       coding.bParityType = USB_CDC_NO_PARITY;
-       coding.bDataBits = USB_CDC_1_STOP_BITS;
-       tty_set_operations(gs_tty_driver, &gs_tty_ops);
-       /* make devices be openable */
-       for (i = 0; i < count; i++) {
-               mutex_init(&ports[i].lock);
-               status = gs_port_alloc(i, &coding);
-               if (status) {
-                       count = i;
-                       goto fail;
-               }
-       }
-       n_ports = count;
-       /* export the driver ... */
-       status = tty_register_driver(gs_tty_driver);
-       if (status) {
-               pr_err("%s: cannot register, err %d\n",
-                               __func__, status);
-               goto fail;
-       }
-       /* ... and sysfs class devices, so mdev/udev make /dev/ttyGS* */
-       for (i = 0; i < count; i++) {
-               struct device   *tty_dev;
-               tty_dev = tty_port_register_device(&ports[i].port->port,
-                               gs_tty_driver, i, &g->dev);
-               if (IS_ERR(tty_dev))
-                       pr_warning("%s: no classdev for port %d, err %ld\n",
-                               __func__, i, PTR_ERR(tty_dev));
-       }
-       pr_debug("%s: registered %d ttyGS* device%s\n", __func__,
-                       count, (count == 1) ? "" : "s");
-       return status;
- fail:
-       while (count--) {
-               tty_port_destroy(&ports[count].port->port);
-               kfree(ports[count].port);
-       }
-       put_tty_driver(gs_tty_driver);
-       gs_tty_driver = NULL;
-       return status;
+ out:
+       mutex_unlock(&ports[port_num].lock);
+       return ret;
  }
  
  static int gs_closed(struct gs_port *port)
        return cond;
  }
  
- /**
-  * gserial_cleanup - remove TTY-over-USB driver and devices
-  * Context: may sleep
-  *
-  * This is called to free all resources allocated by @gserial_setup().
-  * Accordingly, it may need to wait until some open /dev/ files have
-  * closed.
-  *
-  * The caller must have issued @gserial_disconnect() for any ports
-  * that had previously been connected, so that there is never any
-  * I/O pending when it's called.
-  */
- void gserial_cleanup(void)
+ static void gserial_free_port(struct gs_port *port)
+ {
+       tasklet_kill(&port->push);
+       /* wait for old opens to finish */
+       wait_event(port->port.close_wait, gs_closed(port));
+       WARN_ON(port->port_usb != NULL);
+       tty_port_destroy(&port->port);
+       kfree(port);
+ }
+ void gserial_free_line(unsigned char port_num)
  {
-       unsigned        i;
        struct gs_port  *port;
  
-       if (!gs_tty_driver)
+       mutex_lock(&ports[port_num].lock);
+       if (WARN_ON(!ports[port_num].port)) {
+               mutex_unlock(&ports[port_num].lock);
                return;
+       }
+       port = ports[port_num].port;
+       ports[port_num].port = NULL;
+       mutex_unlock(&ports[port_num].lock);
  
-       /* start sysfs and /dev/ttyGS* node removal */
-       for (i = 0; i < n_ports; i++)
-               tty_unregister_device(gs_tty_driver, i);
-       for (i = 0; i < n_ports; i++) {
-               /* prevent new opens */
-               mutex_lock(&ports[i].lock);
-               port = ports[i].port;
-               ports[i].port = NULL;
-               mutex_unlock(&ports[i].lock);
-               tasklet_kill(&port->push);
+       gserial_free_port(port);
+       tty_unregister_device(gs_tty_driver, port_num);
+ }
+ EXPORT_SYMBOL_GPL(gserial_free_line);
  
-               /* wait for old opens to finish */
-               wait_event(port->port.close_wait, gs_closed(port));
+ int gserial_alloc_line(unsigned char *line_num)
+ {
+       struct usb_cdc_line_coding      coding;
+       struct device                   *tty_dev;
+       int                             ret;
+       int                             port_num;
  
-               WARN_ON(port->port_usb != NULL);
+       coding.dwDTERate = cpu_to_le32(9600);
+       coding.bCharFormat = 8;
+       coding.bParityType = USB_CDC_NO_PARITY;
+       coding.bDataBits = USB_CDC_1_STOP_BITS;
  
-               tty_port_destroy(&port->port);
-               kfree(port);
+       for (port_num = 0; port_num < MAX_U_SERIAL_PORTS; port_num++) {
+               ret = gs_port_alloc(port_num, &coding);
+               if (ret == -EBUSY)
+                       continue;
+               if (ret)
+                       return ret;
+               break;
        }
-       n_ports = 0;
+       if (ret)
+               return ret;
  
-       tty_unregister_driver(gs_tty_driver);
-       put_tty_driver(gs_tty_driver);
-       gs_tty_driver = NULL;
+       /* ... and sysfs class devices, so mdev/udev make /dev/ttyGS* */
+       tty_dev = tty_port_register_device(&ports[port_num].port->port,
+                       gs_tty_driver, port_num, NULL);
+       if (IS_ERR(tty_dev)) {
+               struct gs_port  *port;
+               pr_err("%s: failed to register tty for port %d, err %ld\n",
+                               __func__, port_num, PTR_ERR(tty_dev));
  
-       pr_debug("%s: cleaned up ttyGS* support\n", __func__);
+               ret = PTR_ERR(tty_dev);
+               port = ports[port_num].port;
+               ports[port_num].port = NULL;
+               gserial_free_port(port);
+               goto err;
+       }
+       *line_num = port_num;
+ err:
+       return ret;
  }
+ EXPORT_SYMBOL_GPL(gserial_alloc_line);
  
  /**
   * gserial_connect - notify TTY I/O glue that USB link is active
   *
   * Caller needs to have set up the endpoints and USB function in @dev
   * before calling this, as well as the appropriate (speed-specific)
-  * endpoint descriptors, and also have set up the TTY driver by calling
-  * @gserial_setup().
+  * endpoint descriptors, and also have allocate @port_num by calling
+  * @gserial_alloc_line().
   *
   * Returns negative errno or zero.
   * On success, ep->driver_data will be overwritten.
@@@ -1241,11 -1173,18 +1173,18 @@@ int gserial_connect(struct gserial *gse
        unsigned long   flags;
        int             status;
  
-       if (!gs_tty_driver || port_num >= n_ports)
+       if (port_num >= MAX_U_SERIAL_PORTS)
                return -ENXIO;
  
-       /* we "know" gserial_cleanup() hasn't been called */
        port = ports[port_num].port;
+       if (!port) {
+               pr_err("serial line %d not allocated.\n", port_num);
+               return -EINVAL;
+       }
+       if (port->port_usb) {
+               pr_err("serial line %d is in use.\n", port_num);
+               return -EBUSY;
+       }
  
        /* activate the endpoints */
        status = usb_ep_enable(gser->in);
@@@ -1292,7 -1231,7 +1231,7 @@@ fail_out
        gser->in->driver_data = NULL;
        return status;
  }
+ EXPORT_SYMBOL_GPL(gserial_connect);
  /**
   * gserial_disconnect - notify TTY I/O glue that USB link is inactive
   * @gser: the function, on which gserial_connect() was called
@@@ -1347,3 -1286,65 +1286,65 @@@ void gserial_disconnect(struct gserial 
  
        spin_unlock_irqrestore(&port->port_lock, flags);
  }
+ EXPORT_SYMBOL_GPL(gserial_disconnect);
+ static int userial_init(void)
+ {
+       unsigned                        i;
+       int                             status;
+       gs_tty_driver = alloc_tty_driver(MAX_U_SERIAL_PORTS);
+       if (!gs_tty_driver)
+               return -ENOMEM;
+       gs_tty_driver->driver_name = "g_serial";
+       gs_tty_driver->name = PREFIX;
+       /* uses dynamically assigned dev_t values */
+       gs_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
+       gs_tty_driver->subtype = SERIAL_TYPE_NORMAL;
+       gs_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
+       gs_tty_driver->init_termios = tty_std_termios;
+       /* 9600-8-N-1 ... matches defaults expected by "usbser.sys" on
+        * MS-Windows.  Otherwise, most of these flags shouldn't affect
+        * anything unless we were to actually hook up to a serial line.
+        */
+       gs_tty_driver->init_termios.c_cflag =
+                       B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+       gs_tty_driver->init_termios.c_ispeed = 9600;
+       gs_tty_driver->init_termios.c_ospeed = 9600;
+       tty_set_operations(gs_tty_driver, &gs_tty_ops);
+       for (i = 0; i < MAX_U_SERIAL_PORTS; i++)
+               mutex_init(&ports[i].lock);
+       /* export the driver ... */
+       status = tty_register_driver(gs_tty_driver);
+       if (status) {
+               pr_err("%s: cannot register, err %d\n",
+                               __func__, status);
+               goto fail;
+       }
+       pr_debug("%s: registered %d ttyGS* device%s\n", __func__,
+                       MAX_U_SERIAL_PORTS,
+                       (MAX_U_SERIAL_PORTS == 1) ? "" : "s");
+       return status;
+ fail:
+       put_tty_driver(gs_tty_driver);
+       gs_tty_driver = NULL;
+       return status;
+ }
+ module_init(userial_init);
+ static void userial_cleanup(void)
+ {
+       tty_unregister_driver(gs_tty_driver);
+       put_tty_driver(gs_tty_driver);
+       gs_tty_driver = NULL;
+ }
+ module_exit(userial_cleanup);
+ MODULE_LICENSE("GPL");
index 6c56297ea16b8f59bd887f9025cd68ca46a2be96,0da3f081aa78ed14ad27837742cdbfe8abdf9111..3065809546b159c1966b87f5fe4cdc6c333bc3da
@@@ -43,7 -43,7 +43,7 @@@ static void ehci_clock_enable(struct eh
        unsigned int i;
  
        for (i = 0; i < ehci_mv->clknum; i++)
 -              clk_enable(ehci_mv->clk[i]);
 +              clk_prepare_enable(ehci_mv->clk[i]);
  }
  
  static void ehci_clock_disable(struct ehci_hcd_mv *ehci_mv)
@@@ -51,7 -51,7 +51,7 @@@
        unsigned int i;
  
        for (i = 0; i < ehci_mv->clknum; i++)
 -              clk_disable(ehci_mv->clk[i]);
 +              clk_disable_unprepare(ehci_mv->clk[i]);
  }
  
  static int mv_ehci_enable(struct ehci_hcd_mv *ehci_mv)
@@@ -302,7 -302,6 +302,6 @@@ static int mv_ehci_remove(struct platfo
  {
        struct ehci_hcd_mv *ehci_mv = platform_get_drvdata(pdev);
        struct usb_hcd *hcd = ehci_mv->hcd;
-       int clk_i;
  
        if (hcd->rh_registered)
                usb_remove_hcd(hcd);
diff --combined drivers/usb/otg/mv_otg.c
index eace975991a873a938983da7c3dbb5abc2ce2df5,fe1b56a31947051ddb36cf8bddc8e6ea617b2887..da2d60c06f152dcd87768e2054ee1c049b8427cf
@@@ -240,7 -240,7 +240,7 @@@ static void otg_clock_enable(struct mv_
        unsigned int i;
  
        for (i = 0; i < mvotg->clknum; i++)
 -              clk_enable(mvotg->clk[i]);
 +              clk_prepare_enable(mvotg->clk[i]);
  }
  
  static void otg_clock_disable(struct mv_otg *mvotg)
        unsigned int i;
  
        for (i = 0; i < mvotg->clknum; i++)
 -              clk_disable(mvotg->clk[i]);
 +              clk_disable_unprepare(mvotg->clk[i]);
  }
  
  static int mv_otg_enable_internal(struct mv_otg *mvotg)
@@@ -662,18 -662,9 +662,9 @@@ static struct attribute_group inputs_at
  int mv_otg_remove(struct platform_device *pdev)
  {
        struct mv_otg *mvotg = platform_get_drvdata(pdev);
-       int clk_i;
  
        sysfs_remove_group(&mvotg->pdev->dev.kobj, &inputs_attr_group);
  
-       if (mvotg->irq)
-               free_irq(mvotg->irq, mvotg);
-       if (mvotg->pdata->vbus)
-               free_irq(mvotg->pdata->vbus->irq, mvotg);
-       if (mvotg->pdata->id)
-               free_irq(mvotg->pdata->id->irq, mvotg);
        if (mvotg->qwork) {
                flush_workqueue(mvotg->qwork);
                destroy_workqueue(mvotg->qwork);
  
        mv_otg_disable(mvotg);
  
-       if (mvotg->cap_regs)
-               iounmap(mvotg->cap_regs);
-       if (mvotg->phy_regs)
-               iounmap(mvotg->phy_regs);
-       for (clk_i = 0; clk_i <= mvotg->clknum; clk_i++)
-               clk_put(mvotg->clk[clk_i]);
        usb_remove_phy(&mvotg->phy);
        platform_set_drvdata(pdev, NULL);
  
-       kfree(mvotg->phy.otg);
-       kfree(mvotg);
        return 0;
  }
  
@@@ -714,17 -693,15 +693,15 @@@ static int mv_otg_probe(struct platform
        }
  
        size = sizeof(*mvotg) + sizeof(struct clk *) * pdata->clknum;
-       mvotg = kzalloc(size, GFP_KERNEL);
+       mvotg = devm_kzalloc(&pdev->dev, size, GFP_KERNEL);
        if (!mvotg) {
                dev_err(&pdev->dev, "failed to allocate memory!\n");
                return -ENOMEM;
        }
  
-       otg = kzalloc(sizeof *otg, GFP_KERNEL);
-       if (!otg) {
-               kfree(mvotg);
+       otg = devm_kzalloc(&pdev->dev, sizeof(*otg), GFP_KERNEL);
+       if (!otg)
                return -ENOMEM;
-       }
  
        platform_set_drvdata(pdev, mvotg);
  
  
        mvotg->clknum = pdata->clknum;
        for (clk_i = 0; clk_i < mvotg->clknum; clk_i++) {
-               mvotg->clk[clk_i] = clk_get(&pdev->dev, pdata->clkname[clk_i]);
+               mvotg->clk[clk_i] = devm_clk_get(&pdev->dev,
+                                               pdata->clkname[clk_i]);
                if (IS_ERR(mvotg->clk[clk_i])) {
                        retval = PTR_ERR(mvotg->clk[clk_i]);
-                       goto err_put_clk;
+                       return retval;
                }
        }
  
        mvotg->qwork = create_singlethread_workqueue("mv_otg_queue");
        if (!mvotg->qwork) {
                dev_dbg(&pdev->dev, "cannot create workqueue for OTG\n");
-               retval = -ENOMEM;
-               goto err_put_clk;
+               return -ENOMEM;
        }
  
        INIT_DELAYED_WORK(&mvotg->work, mv_otg_work);
                goto err_destroy_workqueue;
        }
  
-       mvotg->phy_regs = ioremap(r->start, resource_size(r));
+       mvotg->phy_regs = devm_ioremap(&pdev->dev, r->start, resource_size(r));
        if (mvotg->phy_regs == NULL) {
                dev_err(&pdev->dev, "failed to map phy I/O memory\n");
                retval = -EFAULT;
        if (r == NULL) {
                dev_err(&pdev->dev, "no I/O memory resource defined\n");
                retval = -ENODEV;
-               goto err_unmap_phyreg;
+               goto err_destroy_workqueue;
        }
  
-       mvotg->cap_regs = ioremap(r->start, resource_size(r));
+       mvotg->cap_regs = devm_ioremap(&pdev->dev, r->start, resource_size(r));
        if (mvotg->cap_regs == NULL) {
                dev_err(&pdev->dev, "failed to map I/O memory\n");
                retval = -EFAULT;
-               goto err_unmap_phyreg;
+               goto err_destroy_workqueue;
        }
  
        /* we will acces controller register, so enable the udc controller */
        retval = mv_otg_enable_internal(mvotg);
        if (retval) {
                dev_err(&pdev->dev, "mv otg enable error %d\n", retval);
-               goto err_unmap_capreg;
+               goto err_destroy_workqueue;
        }
  
        mvotg->op_regs =
                        + (readl(mvotg->cap_regs) & CAPLENGTH_MASK));
  
        if (pdata->id) {
-               retval = request_threaded_irq(pdata->id->irq, NULL,
-                                             mv_otg_inputs_irq,
-                                             IRQF_ONESHOT, "id", mvotg);
+               retval = devm_request_threaded_irq(&pdev->dev, pdata->id->irq,
+                                               NULL, mv_otg_inputs_irq,
+                                               IRQF_ONESHOT, "id", mvotg);
                if (retval) {
                        dev_info(&pdev->dev,
                                 "Failed to request irq for ID\n");
  
        if (pdata->vbus) {
                mvotg->clock_gating = 1;
-               retval = request_threaded_irq(pdata->vbus->irq, NULL,
-                                             mv_otg_inputs_irq,
-                                             IRQF_ONESHOT, "vbus", mvotg);
+               retval = devm_request_threaded_irq(&pdev->dev, pdata->vbus->irq,
+                                               NULL, mv_otg_inputs_irq,
+                                               IRQF_ONESHOT, "vbus", mvotg);
                if (retval) {
                        dev_info(&pdev->dev,
                                 "Failed to request irq for VBUS, "
        }
  
        mvotg->irq = r->start;
-       if (request_irq(mvotg->irq, mv_otg_irq, IRQF_SHARED,
+       if (devm_request_irq(&pdev->dev, mvotg->irq, mv_otg_irq, IRQF_SHARED,
                        driver_name, mvotg)) {
                dev_err(&pdev->dev, "Request irq %d for OTG failed\n",
                        mvotg->irq);
        if (retval < 0) {
                dev_err(&pdev->dev, "can't register transceiver, %d\n",
                        retval);
-               goto err_free_irq;
+               goto err_disable_clk;
        }
  
        retval = sysfs_create_group(&pdev->dev.kobj, &inputs_attr_group);
        if (retval < 0) {
                dev_dbg(&pdev->dev,
                        "Can't register sysfs attr group: %d\n", retval);
-               goto err_set_transceiver;
+               goto err_remove_phy;
        }
  
        spin_lock_init(&mvotg->wq_lock);
  
        return 0;
  
- err_set_transceiver:
+ err_remove_phy:
        usb_remove_phy(&mvotg->phy);
- err_free_irq:
-       free_irq(mvotg->irq, mvotg);
  err_disable_clk:
-       if (pdata->vbus)
-               free_irq(pdata->vbus->irq, mvotg);
-       if (pdata->id)
-               free_irq(pdata->id->irq, mvotg);
        mv_otg_disable_internal(mvotg);
- err_unmap_capreg:
-       iounmap(mvotg->cap_regs);
- err_unmap_phyreg:
-       iounmap(mvotg->phy_regs);
  err_destroy_workqueue:
        flush_workqueue(mvotg->qwork);
        destroy_workqueue(mvotg->qwork);
- err_put_clk:
-       for (clk_i--; clk_i >= 0; clk_i--)
-               clk_put(mvotg->clk[clk_i]);
  
        platform_set_drvdata(pdev, NULL);
-       kfree(otg);
-       kfree(mvotg);
  
        return retval;
  }
index f2985cd88021c0bd52178ee48cc64c4c7c97bc00,809745072c11069f40061d039a37d699627015e7..78fca978b2d058a86bb4b9a178bb5336951e99cf
@@@ -545,6 -545,15 +545,6 @@@ static int usbhsg_pipe_disable(struct u
        return 0;
  }
  
 -static void usbhsg_uep_init(struct usbhsg_gpriv *gpriv)
 -{
 -      int i;
 -      struct usbhsg_uep *uep;
 -
 -      usbhsg_for_each_uep_with_dcp(uep, gpriv, i)
 -              uep->pipe = NULL;
 -}
 -
  /*
   *
   *            usb_ep_ops
@@@ -601,12 -610,7 +601,12 @@@ static int usbhsg_ep_disable(struct usb
  {
        struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep);
  
 -      return usbhsg_pipe_disable(uep);
 +      usbhsg_pipe_disable(uep);
 +
 +      uep->pipe->mod_private  = NULL;
 +      uep->pipe               = NULL;
 +
 +      return 0;
  }
  
  static struct usb_request *usbhsg_ep_alloc_request(struct usb_ep *ep,
@@@ -757,8 -761,9 +757,8 @@@ static int usbhsg_try_start(struct usbh
        usbhs_pipe_init(priv,
                        usbhsg_dma_map_ctrl);
        usbhs_fifo_init(priv);
 -      usbhsg_uep_init(gpriv);
  
 -      /* dcp init */
 +      /* dcp init instead of usbhsg_ep_enable() */
        dcp->pipe               = usbhs_dcp_malloc(priv);
        dcp->pipe->mod_private  = dcp;
        usbhs_pipe_config_update(dcp->pipe, 0, 0, 64);
@@@ -820,7 -825,7 +820,7 @@@ static int usbhsg_try_stop(struct usbhs
        usbhs_sys_set_test_mode(priv, 0);
        usbhs_sys_function_ctrl(priv, 0);
  
 -      usbhsg_pipe_disable(dcp);
 +      usbhsg_ep_disable(&dcp->ep);
  
        dev_dbg(dev, "stop gadget\n");
  
@@@ -900,7 -905,7 +900,7 @@@ static int usbhsg_set_selfpowered(struc
        return 0;
  }
  
- static struct usb_gadget_ops usbhsg_gadget_ops = {
+ static const struct usb_gadget_ops usbhsg_gadget_ops = {
        .get_frame              = usbhsg_get_frame,
        .set_selfpowered        = usbhsg_set_selfpowered,
        .udc_start              = usbhsg_gadget_start,
@@@ -993,7 -998,6 +993,7 @@@ int usbhs_mod_gadget_probe(struct usbhs
         */
        usbhsg_for_each_uep_with_dcp(uep, gpriv, i) {
                uep->gpriv      = gpriv;
 +              uep->pipe       = NULL;
                snprintf(uep->ep_name, EP_NAME_SIZE, "ep%d", i);
  
                uep->ep.name            = uep->ep_name;
This page took 0.138329 seconds and 4 git commands to generate.