]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge tag 'xceiv-for-v3.6' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi...
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 5 Jul 2012 22:35:41 +0000 (15:35 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 5 Jul 2012 22:35:41 +0000 (15:35 -0700)
usb: phy: patches for v3.6 merge window

We are starting to support multiple USB phys as
we should thanks for Kishon's work. DeviceTree support
for USB PHYs won't come until discussion with DeviceTree
maintainer is finished.

Together with that series, we have one fix for twl4030
which missed a IRQF_ONESHOT annotation when requesting
a threaded IRQ without a top half handler, and removal
of an unused variable compilation warning to isp1301_omap.

38 files changed:
drivers/power/ab8500_charger.c
drivers/power/isp1704_charger.c
drivers/power/pda_power.c
drivers/power/twl4030_charger.c
drivers/usb/chipidea/udc.c
drivers/usb/gadget/fsl_udc_core.c
drivers/usb/gadget/mv_udc_core.c
drivers/usb/gadget/omap_udc.c
drivers/usb/gadget/pxa25x_udc.c
drivers/usb/gadget/pxa27x_udc.c
drivers/usb/gadget/s3c-hsudc.c
drivers/usb/host/ehci-fsl.c
drivers/usb/host/ehci-msm.c
drivers/usb/host/ehci-mv.c
drivers/usb/host/ehci-tegra.c
drivers/usb/host/ohci-omap.c
drivers/usb/musb/am35x.c
drivers/usb/musb/blackfin.c
drivers/usb/musb/da8xx.c
drivers/usb/musb/davinci.c
drivers/usb/musb/musb_core.c
drivers/usb/musb/musb_core.h
drivers/usb/musb/musb_dsps.c
drivers/usb/musb/omap2430.c
drivers/usb/musb/tusb6010.c
drivers/usb/musb/ux500.c
drivers/usb/otg/ab8500-usb.c
drivers/usb/otg/fsl_otg.c
drivers/usb/otg/gpio_vbus.c
drivers/usb/otg/isp1301_omap.c
drivers/usb/otg/msm_otg.c
drivers/usb/otg/mv_otg.c
drivers/usb/otg/nop-usb-xceiv.c
drivers/usb/otg/otg.c
drivers/usb/otg/twl4030-usb.c
drivers/usb/otg/twl6030-usb.c
include/linux/usb/musb-omap.h [new file with mode: 0644]
include/linux/usb/otg.h

index d2303d0b7c755669f7ab48b968e062474241997b..d4f0c98428cbacbef7767c8d375867aaf87cf529 100644 (file)
@@ -2517,7 +2517,7 @@ static int __devexit ab8500_charger_remove(struct platform_device *pdev)
                dev_err(di->dev, "%s mask and set failed\n", __func__);
 
        usb_unregister_notifier(di->usb_phy, &di->nb);
-       usb_put_transceiver(di->usb_phy);
+       usb_put_phy(di->usb_phy);
 
        /* Delete the work queue */
        destroy_workqueue(di->charger_wq);
@@ -2688,8 +2688,8 @@ static int __devinit ab8500_charger_probe(struct platform_device *pdev)
                goto free_ac;
        }
 
-       di->usb_phy = usb_get_transceiver();
-       if (!di->usb_phy) {
+       di->usb_phy = usb_get_phy(USB_PHY_TYPE_USB2);
+       if (IS_ERR_OR_NULL(di->usb_phy)) {
                dev_err(di->dev, "failed to get usb transceiver\n");
                ret = -EINVAL;
                goto free_usb;
@@ -2747,7 +2747,7 @@ free_irq:
                free_irq(irq, di);
        }
 put_usb_phy:
-       usb_put_transceiver(di->usb_phy);
+       usb_put_phy(di->usb_phy);
 free_usb:
        power_supply_unregister(&di->usb_chg.psy);
 free_ac:
index e5ccd29797732d8dae6992a558eabd896fe6a9f0..122911978da22a55f810044892873c654f19661e 100644 (file)
@@ -415,8 +415,8 @@ static int __devinit isp1704_charger_probe(struct platform_device *pdev)
        if (!isp)
                return -ENOMEM;
 
-       isp->phy = usb_get_transceiver();
-       if (!isp->phy)
+       isp->phy = usb_get_phy(USB_PHY_TYPE_USB2);
+       if (IS_ERR_OR_NULL(isp->phy))
                goto fail0;
 
        isp->dev = &pdev->dev;
@@ -475,7 +475,7 @@ fail2:
        power_supply_unregister(&isp->psy);
 fail1:
        isp1704_charger_set_power(isp, 0);
-       usb_put_transceiver(isp->phy);
+       usb_put_phy(isp->phy);
 fail0:
        kfree(isp);
 
@@ -490,7 +490,7 @@ static int __devexit isp1704_charger_remove(struct platform_device *pdev)
 
        usb_unregister_notifier(isp->phy, &isp->nb);
        power_supply_unregister(&isp->psy);
-       usb_put_transceiver(isp->phy);
+       usb_put_phy(isp->phy);
        isp1704_charger_set_power(isp, 0);
        kfree(isp);
 
index 214468f4444a0d68e61468dc19f8ec1abf56b40b..8dbcd53c5e67b2a8868de2028169139e0472a74e 100644 (file)
@@ -321,12 +321,12 @@ static int pda_power_probe(struct platform_device *pdev)
        }
 
 #ifdef CONFIG_USB_OTG_UTILS
-       transceiver = usb_get_transceiver();
-       if (transceiver && !pdata->is_usb_online) {
-               pdata->is_usb_online = otg_is_usb_online;
-       }
-       if (transceiver && !pdata->is_ac_online) {
-               pdata->is_ac_online = otg_is_ac_online;
+       transceiver = usb_get_phy(USB_PHY_TYPE_USB2);
+       if (!IS_ERR_OR_NULL(transceiver)) {
+               if (!pdata->is_usb_online)
+                       pdata->is_usb_online = otg_is_usb_online;
+               if (!pdata->is_ac_online)
+                       pdata->is_ac_online = otg_is_ac_online;
        }
 #endif
 
@@ -373,7 +373,7 @@ static int pda_power_probe(struct platform_device *pdev)
        }
 
 #ifdef CONFIG_USB_OTG_UTILS
-       if (transceiver && pdata->use_otg_notifier) {
+       if (!IS_ERR_OR_NULL(transceiver) && pdata->use_otg_notifier) {
                otg_nb.notifier_call = otg_handle_notification;
                ret = usb_register_notifier(transceiver, &otg_nb);
                if (ret) {
@@ -408,8 +408,8 @@ usb_supply_failed:
        if (pdata->is_ac_online && ac_irq)
                free_irq(ac_irq->start, &pda_psy_ac);
 #ifdef CONFIG_USB_OTG_UTILS
-       if (transceiver)
-               usb_put_transceiver(transceiver);
+       if (!IS_ERR_OR_NULL(transceiver))
+               usb_put_phy(transceiver);
 #endif
 ac_irq_failed:
        if (pdata->is_ac_online)
@@ -443,8 +443,8 @@ static int pda_power_remove(struct platform_device *pdev)
        if (pdata->is_ac_online)
                power_supply_unregister(&pda_psy_ac);
 #ifdef CONFIG_USB_OTG_UTILS
-       if (transceiver)
-               usb_put_transceiver(transceiver);
+       if (!IS_ERR_OR_NULL(transceiver))
+               usb_put_phy(transceiver);
 #endif
        if (ac_draw) {
                regulator_put(ac_draw);
index fdad850c77d3264c49b0981a8656bd8afbd74529..7cacbaa68efe410902c64bb04c3a68619c4cd689 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/slab.h>
+#include <linux/err.h>
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
 #include <linux/i2c/twl.h>
@@ -479,8 +480,8 @@ static int __init twl4030_bci_probe(struct platform_device *pdev)
 
        INIT_WORK(&bci->work, twl4030_bci_usb_work);
 
-       bci->transceiver = usb_get_transceiver();
-       if (bci->transceiver != NULL) {
+       bci->transceiver = usb_get_phy(USB_PHY_TYPE_USB2);
+       if (!IS_ERR_OR_NULL(bci->transceiver)) {
                bci->usb_nb.notifier_call = twl4030_bci_usb_ncb;
                usb_register_notifier(bci->transceiver, &bci->usb_nb);
        }
@@ -507,9 +508,9 @@ static int __init twl4030_bci_probe(struct platform_device *pdev)
        return 0;
 
 fail_unmask_interrupts:
-       if (bci->transceiver != NULL) {
+       if (!IS_ERR_OR_NULL(bci->transceiver)) {
                usb_unregister_notifier(bci->transceiver, &bci->usb_nb);
-               usb_put_transceiver(bci->transceiver);
+               usb_put_phy(bci->transceiver);
        }
        free_irq(bci->irq_bci, bci);
 fail_bci_irq:
@@ -538,9 +539,9 @@ static int __exit twl4030_bci_remove(struct platform_device *pdev)
        twl_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xff,
                         TWL4030_INTERRUPTS_BCIIMR2A);
 
-       if (bci->transceiver != NULL) {
+       if (!IS_ERR_OR_NULL(bci->transceiver)) {
                usb_unregister_notifier(bci->transceiver, &bci->usb_nb);
-               usb_put_transceiver(bci->transceiver);
+               usb_put_phy(bci->transceiver);
        }
        free_irq(bci->irq_bci, bci);
        free_irq(bci->irq_chg, bci);
index 51f96942dc5ef109319429464d267acc43d09600..4688ab71bd275108b6b787a8c756661f6d83c345 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/device.h>
 #include <linux/dmapool.h>
 #include <linux/dma-mapping.h>
+#include <linux/err.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/module.h>
@@ -1687,7 +1688,7 @@ static int udc_start(struct ci13xxx *udc)
 
        udc->gadget.ep0 = &udc->ep0in->ep;
 
-       udc->transceiver = usb_get_transceiver();
+       udc->transceiver = usb_get_phy(USB_PHY_TYPE_USB2);
 
        if (udc->udc_driver->flags & CI13XXX_REQUIRE_TRANSCEIVER) {
                if (udc->transceiver == NULL) {
@@ -1712,7 +1713,7 @@ static int udc_start(struct ci13xxx *udc)
        if (retval)
                goto unreg_device;
 
-       if (udc->transceiver) {
+       if (!IS_ERR_OR_NULL(udc->transceiver)) {
                retval = otg_set_peripheral(udc->transceiver->otg,
                                                &udc->gadget);
                if (retval)
@@ -1729,9 +1730,9 @@ static int udc_start(struct ci13xxx *udc)
        return retval;
 
 remove_trans:
-       if (udc->transceiver) {
+       if (!IS_ERR_OR_NULL(udc->transceiver)) {
                otg_set_peripheral(udc->transceiver->otg, &udc->gadget);
-               usb_put_transceiver(udc->transceiver);
+               usb_put_phy(udc->transceiver);
        }
 
        dev_err(dev, "error = %i\n", retval);
@@ -1740,8 +1741,8 @@ remove_dbg:
 unreg_device:
        device_unregister(&udc->gadget.dev);
 put_transceiver:
-       if (udc->transceiver)
-               usb_put_transceiver(udc->transceiver);
+       if (!IS_ERR_OR_NULL(udc->transceiver))
+               usb_put_phy(udc->transceiver);
 free_pools:
        dma_pool_destroy(udc->td_pool);
 free_qh_pool:
@@ -1772,9 +1773,9 @@ static void udc_stop(struct ci13xxx *udc)
        dma_pool_destroy(udc->td_pool);
        dma_pool_destroy(udc->qh_pool);
 
-       if (udc->transceiver) {
+       if (!IS_ERR_OR_NULL(udc->transceiver)) {
                otg_set_peripheral(udc->transceiver->otg, NULL);
-               usb_put_transceiver(udc->transceiver);
+               usb_put_phy(udc->transceiver);
        }
        dbg_remove_files(&udc->gadget.dev);
        device_unregister(&udc->gadget.dev);
index a65ca0f5d8c46cf4ec5479c4d5c4484fe052fe78..3def828f85e7fe5ad31a3eaf5c4bf5e71bbf1458 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/ioport.h>
 #include <linux/types.h>
 #include <linux/errno.h>
+#include <linux/err.h>
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/list.h>
@@ -1229,7 +1230,7 @@ static int fsl_vbus_draw(struct usb_gadget *gadget, unsigned mA)
        struct fsl_udc *udc;
 
        udc = container_of(gadget, struct fsl_udc, gadget);
-       if (udc->transceiver)
+       if (!IS_ERR_OR_NULL(udc->transceiver))
                return usb_phy_set_power(udc->transceiver, mA);
        return -ENOTSUPP;
 }
@@ -1983,13 +1984,13 @@ static int fsl_start(struct usb_gadget_driver *driver,
                goto out;
        }
 
-       if (udc_controller->transceiver) {
+       if (!IS_ERR_OR_NULL(udc_controller->transceiver)) {
                /* Suspend the controller until OTG enable it */
                udc_controller->stopped = 1;
                printk(KERN_INFO "Suspend udc for OTG auto detect\n");
 
                /* connect to bus through transceiver */
-               if (udc_controller->transceiver) {
+               if (!IS_ERR_OR_NULL(udc_controller->transceiver)) {
                        retval = otg_set_peripheral(
                                        udc_controller->transceiver->otg,
                                                    &udc_controller->gadget);
@@ -2030,7 +2031,7 @@ static int fsl_stop(struct usb_gadget_driver *driver)
        if (!driver || driver != udc_controller->driver || !driver->unbind)
                return -EINVAL;
 
-       if (udc_controller->transceiver)
+       if (!IS_ERR_OR_NULL(udc_controller->transceiver))
                otg_set_peripheral(udc_controller->transceiver->otg, NULL);
 
        /* stop DR, disable intr */
@@ -2455,8 +2456,8 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
 
 #ifdef CONFIG_USB_OTG
        if (pdata->operating_mode == FSL_USB2_DR_OTG) {
-               udc_controller->transceiver = usb_get_transceiver();
-               if (!udc_controller->transceiver) {
+               udc_controller->transceiver = usb_get_phy(USB_PHY_TYPE_USB2);
+               if (IS_ERR_OR_NULL(udc_controller->transceiver)) {
                        ERR("Can't find OTG driver!\n");
                        ret = -ENODEV;
                        goto err_kfree;
@@ -2540,7 +2541,7 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
                goto err_free_irq;
        }
 
-       if (!udc_controller->transceiver) {
+       if (IS_ERR_OR_NULL(udc_controller->transceiver)) {
                /* initialize usb hw reg except for regs for EP,
                 * leave usbintr reg untouched */
                dr_controller_setup(udc_controller);
@@ -2565,7 +2566,7 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
        if (ret < 0)
                goto err_free_irq;
 
-       if (udc_controller->transceiver)
+       if (!IS_ERR_OR_NULL(udc_controller->transceiver))
                udc_controller->gadget.is_otg = 1;
 
        /* setup QH and epctrl for ep0 */
index 117a4bba1b8c26a32b22e09400f6f346e531732d..75db2c306cea24ba3736b1ebd8c689546d02c2c5 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/errno.h>
+#include <linux/err.h>
 #include <linux/init.h>
 #include <linux/timer.h>
 #include <linux/list.h>
@@ -1381,7 +1382,7 @@ static int mv_udc_start(struct usb_gadget_driver *driver,
                return retval;
        }
 
-       if (udc->transceiver) {
+       if (!IS_ERR_OR_NULL(udc->transceiver)) {
                retval = otg_set_peripheral(udc->transceiver->otg,
                                        &udc->gadget);
                if (retval) {
@@ -2107,7 +2108,7 @@ static int __devexit mv_udc_remove(struct platform_device *dev)
         * then vbus irq will not be requested in udc driver.
         */
        if (udc->pdata && udc->pdata->vbus
-               && udc->clock_gating && udc->transceiver == NULL)
+               && udc->clock_gating && IS_ERR_OR_NULL(udc->transceiver))
                free_irq(udc->pdata->vbus->irq, &dev->dev);
 
        /* free memory allocated in probe */
@@ -2180,7 +2181,7 @@ static int __devinit mv_udc_probe(struct platform_device *dev)
 
 #ifdef CONFIG_USB_OTG_UTILS
        if (pdata->mode == MV_USB_MODE_OTG)
-               udc->transceiver = usb_get_transceiver();
+               udc->transceiver = usb_get_phy(USB_PHY_TYPE_USB2);
 #endif
 
        udc->clknum = pdata->clknum;
@@ -2325,7 +2326,7 @@ static int __devinit mv_udc_probe(struct platform_device *dev)
        eps_init(udc);
 
        /* VBUS detect: we can disable/enable clock on demand.*/
-       if (udc->transceiver)
+       if (!IS_ERR_OR_NULL(udc->transceiver))
                udc->clock_gating = 1;
        else if (pdata->vbus) {
                udc->clock_gating = 1;
@@ -2369,7 +2370,7 @@ static int __devinit mv_udc_probe(struct platform_device *dev)
 
 err_unregister:
        if (udc->pdata && udc->pdata->vbus
-               && udc->clock_gating && udc->transceiver == NULL)
+               && udc->clock_gating && IS_ERR_OR_NULL(udc->transceiver))
                free_irq(pdata->vbus->irq, &dev->dev);
        device_unregister(&udc->gadget.dev);
 err_free_irq:
@@ -2404,7 +2405,7 @@ static int mv_udc_suspend(struct device *_dev)
        struct mv_udc *udc = the_controller;
 
        /* if OTG is enabled, the following will be done in OTG driver*/
-       if (udc->transceiver)
+       if (!IS_ERR_OR_NULL(udc->transceiver))
                return 0;
 
        if (udc->pdata->vbus && udc->pdata->vbus->poll)
@@ -2437,7 +2438,7 @@ static int mv_udc_resume(struct device *_dev)
        int retval;
 
        /* if OTG is enabled, the following will be done in OTG driver*/
-       if (udc->transceiver)
+       if (!IS_ERR_OR_NULL(udc->transceiver))
                return 0;
 
        if (!udc->clock_gating) {
index b26c7d68cc06ca21ab0f4ef6fad539df8734bad3..d7df89e72efe3854abc299622293534e685a9bc7 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/usb/otg.h>
 #include <linux/dma-mapping.h>
 #include <linux/clk.h>
+#include <linux/err.h>
 #include <linux/prefetch.h>
 #include <linux/io.h>
 
@@ -1152,7 +1153,7 @@ static int omap_wakeup(struct usb_gadget *gadget)
 
        /* NOTE:  non-OTG systems may use SRP TOO... */
        } else if (!(udc->devstat & UDC_ATT)) {
-               if (udc->transceiver)
+               if (!IS_ERR_OR_NULL(udc->transceiver))
                        retval = otg_start_srp(udc->transceiver->otg);
        }
        spin_unlock_irqrestore(&udc->lock, flags);
@@ -1284,7 +1285,7 @@ static int omap_vbus_draw(struct usb_gadget *gadget, unsigned mA)
        struct omap_udc *udc;
 
        udc = container_of(gadget, struct omap_udc, gadget);
-       if (udc->transceiver)
+       if (!IS_ERR_OR_NULL(udc->transceiver))
                return usb_phy_set_power(udc->transceiver, mA);
        return -EOPNOTSUPP;
 }
@@ -1734,12 +1735,12 @@ static void devstate_irq(struct omap_udc *udc, u16 irq_src)
                        if (devstat & UDC_ATT) {
                                udc->gadget.speed = USB_SPEED_FULL;
                                VDBG("connect\n");
-                               if (!udc->transceiver)
+                               if (IS_ERR_OR_NULL(udc->transceiver))
                                        pullup_enable(udc);
                                /* if (driver->connect) call it */
                        } else if (udc->gadget.speed != USB_SPEED_UNKNOWN) {
                                udc->gadget.speed = USB_SPEED_UNKNOWN;
-                               if (!udc->transceiver)
+                               if (IS_ERR_OR_NULL(udc->transceiver))
                                        pullup_disable(udc);
                                DBG("disconnect, gadget %s\n",
                                        udc->driver->driver.name);
@@ -1779,12 +1780,12 @@ static void devstate_irq(struct omap_udc *udc, u16 irq_src)
                                        udc->driver->suspend(&udc->gadget);
                                        spin_lock(&udc->lock);
                                }
-                               if (udc->transceiver)
+                               if (!IS_ERR_OR_NULL(udc->transceiver))
                                        usb_phy_set_suspend(
                                                        udc->transceiver, 1);
                        } else {
                                VDBG("resume\n");
-                               if (udc->transceiver)
+                               if (!IS_ERR_OR_NULL(udc->transceiver))
                                        usb_phy_set_suspend(
                                                        udc->transceiver, 0);
                                if (udc->gadget.speed == USB_SPEED_FULL
@@ -2092,7 +2093,7 @@ static int omap_udc_start(struct usb_gadget_driver *driver,
        omap_writew(UDC_IRQ_SRC_MASK, UDC_IRQ_SRC);
 
        /* connect to bus through transceiver */
-       if (udc->transceiver) {
+       if (!IS_ERR_OR_NULL(udc->transceiver)) {
                status = otg_set_peripheral(udc->transceiver->otg,
                                                &udc->gadget);
                if (status < 0) {
@@ -2139,7 +2140,7 @@ static int omap_udc_stop(struct usb_gadget_driver *driver)
        if (machine_without_vbus_sense())
                omap_vbus_session(&udc->gadget, 0);
 
-       if (udc->transceiver)
+       if (!IS_ERR_OR_NULL(udc->transceiver))
                (void) otg_set_peripheral(udc->transceiver->otg, NULL);
        else
                pullup_disable(udc);
@@ -2829,8 +2830,8 @@ static int __devinit omap_udc_probe(struct platform_device *pdev)
                 * use it.  Except for OTG, we don't _need_ to talk to one;
                 * but not having one probably means no VBUS detection.
                 */
-               xceiv = usb_get_transceiver();
-               if (xceiv)
+               xceiv = usb_get_phy(USB_PHY_TYPE_USB2);
+               if (!IS_ERR_OR_NULL(xceiv))
                        type = xceiv->label;
                else if (config->otg) {
                        DBG("OTG requires external transceiver!\n");
@@ -2854,7 +2855,7 @@ static int __devinit omap_udc_probe(struct platform_device *pdev)
                case 16:
                case 19:
                case 25:
-                       if (!xceiv) {
+                       if (IS_ERR_OR_NULL(xceiv)) {
                                DBG("external transceiver not registered!\n");
                                type = "unknown";
                        }
@@ -2956,8 +2957,8 @@ cleanup1:
        udc = NULL;
 
 cleanup0:
-       if (xceiv)
-               usb_put_transceiver(xceiv);
+       if (!IS_ERR_OR_NULL(xceiv))
+               usb_put_phy(xceiv);
 
        if (cpu_is_omap16xx() || cpu_is_omap7xx()) {
                clk_disable(hhc_clk);
@@ -2986,8 +2987,8 @@ static int __devexit omap_udc_remove(struct platform_device *pdev)
        udc->done = &done;
 
        pullup_disable(udc);
-       if (udc->transceiver) {
-               usb_put_transceiver(udc->transceiver);
+       if (!IS_ERR_OR_NULL(udc->transceiver)) {
+               usb_put_phy(udc->transceiver);
                udc->transceiver = NULL;
        }
        omap_writew(0, UDC_SYSCON1);
index f7ff9e8e746a796f944713414ecb8acb43248f2a..53c093b941e5915302775b0916785fe24c7db866 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/ioport.h>
 #include <linux/types.h>
 #include <linux/errno.h>
+#include <linux/err.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
 #include <linux/init.h>
@@ -993,7 +994,7 @@ static int pxa25x_udc_vbus_draw(struct usb_gadget *_gadget, unsigned mA)
 
        udc = container_of(_gadget, struct pxa25x_udc, gadget);
 
-       if (udc->transceiver)
+       if (!IS_ERR_OR_NULL(udc->transceiver))
                return usb_phy_set_power(udc->transceiver, mA);
        return -EOPNOTSUPP;
 }
@@ -1299,7 +1300,7 @@ fail:
        DMSG("registered gadget driver '%s'\n", driver->driver.name);
 
        /* connect to bus through transceiver */
-       if (dev->transceiver) {
+       if (!IS_ERR_OR_NULL(dev->transceiver)) {
                retval = otg_set_peripheral(dev->transceiver->otg,
                                                &dev->gadget);
                if (retval) {
@@ -1359,7 +1360,7 @@ static int pxa25x_stop(struct usb_gadget_driver *driver)
        stop_activity(dev, driver);
        local_irq_enable();
 
-       if (dev->transceiver)
+       if (!IS_ERR_OR_NULL(dev->transceiver))
                (void) otg_set_peripheral(dev->transceiver->otg, NULL);
 
        driver->unbind(&dev->gadget);
@@ -2159,7 +2160,7 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev)
        dev->dev = &pdev->dev;
        dev->mach = pdev->dev.platform_data;
 
-       dev->transceiver = usb_get_transceiver();
+       dev->transceiver = usb_get_phy(USB_PHY_TYPE_USB2);
 
        if (gpio_is_valid(dev->mach->gpio_pullup)) {
                if ((retval = gpio_request(dev->mach->gpio_pullup,
@@ -2237,8 +2238,8 @@ lubbock_fail0:
        if (gpio_is_valid(dev->mach->gpio_pullup))
                gpio_free(dev->mach->gpio_pullup);
  err_gpio_pullup:
-       if (dev->transceiver) {
-               usb_put_transceiver(dev->transceiver);
+       if (!IS_ERR_OR_NULL(dev->transceiver)) {
+               usb_put_phy(dev->transceiver);
                dev->transceiver = NULL;
        }
        clk_put(dev->clk);
@@ -2279,8 +2280,8 @@ static int __exit pxa25x_udc_remove(struct platform_device *pdev)
 
        clk_put(dev->clk);
 
-       if (dev->transceiver) {
-               usb_put_transceiver(dev->transceiver);
+       if (!IS_ERR_OR_NULL(dev->transceiver)) {
+               usb_put_phy(dev->transceiver);
                dev->transceiver = NULL;
        }
 
index 98acb3ab9e1791f966c44be9b80c430d46a492fb..644b4305cb99fe1653ac8f9d0b5021ac4d8945a1 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/errno.h>
+#include <linux/err.h>
 #include <linux/platform_device.h>
 #include <linux/delay.h>
 #include <linux/list.h>
@@ -1573,7 +1574,7 @@ static int should_enable_udc(struct pxa_udc *udc)
        int put_on;
 
        put_on = ((udc->pullup_on) && (udc->driver));
-       put_on &= ((udc->vbus_sensed) || (!udc->transceiver));
+       put_on &= ((udc->vbus_sensed) || (IS_ERR_OR_NULL(udc->transceiver)));
        return put_on;
 }
 
@@ -1594,7 +1595,7 @@ static int should_disable_udc(struct pxa_udc *udc)
        int put_off;
 
        put_off = ((!udc->pullup_on) || (!udc->driver));
-       put_off |= ((!udc->vbus_sensed) && (udc->transceiver));
+       put_off |= ((!udc->vbus_sensed) && (!IS_ERR_OR_NULL(udc->transceiver)));
        return put_off;
 }
 
@@ -1665,7 +1666,7 @@ static int pxa_udc_vbus_draw(struct usb_gadget *_gadget, unsigned mA)
        struct pxa_udc *udc;
 
        udc = to_gadget_udc(_gadget);
-       if (udc->transceiver)
+       if (!IS_ERR_OR_NULL(udc->transceiver))
                return usb_phy_set_power(udc->transceiver, mA);
        return -EOPNOTSUPP;
 }
@@ -1834,7 +1835,7 @@ static int pxa27x_udc_start(struct usb_gadget_driver *driver,
        dev_dbg(udc->dev, "registered gadget driver '%s'\n",
                driver->driver.name);
 
-       if (udc->transceiver) {
+       if (!IS_ERR_OR_NULL(udc->transceiver)) {
                retval = otg_set_peripheral(udc->transceiver->otg,
                                                &udc->gadget);
                if (retval) {
@@ -1908,7 +1909,7 @@ static int pxa27x_udc_stop(struct usb_gadget_driver *driver)
        dev_info(udc->dev, "unregistered gadget driver '%s'\n",
                 driver->driver.name);
 
-       if (udc->transceiver)
+       if (!IS_ERR_OR_NULL(udc->transceiver))
                return otg_set_peripheral(udc->transceiver->otg, NULL);
        return 0;
 }
@@ -2464,7 +2465,7 @@ static int __init pxa_udc_probe(struct platform_device *pdev)
 
        udc->dev = &pdev->dev;
        udc->mach = pdev->dev.platform_data;
-       udc->transceiver = usb_get_transceiver();
+       udc->transceiver = usb_get_phy(USB_PHY_TYPE_USB2);
 
        gpio = udc->mach->gpio_pullup;
        if (gpio_is_valid(gpio)) {
@@ -2543,7 +2544,7 @@ static int __exit pxa_udc_remove(struct platform_device *_dev)
        if (gpio_is_valid(gpio))
                gpio_free(gpio);
 
-       usb_put_transceiver(udc->transceiver);
+       usb_put_phy(udc->transceiver);
 
        udc->transceiver = NULL;
        platform_set_drvdata(_dev, NULL);
index 236b271871a0bde44e353ebe5650c705bf48f163..e26a4e7ed2bf978868347ececb4332bb74db2db2 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/io.h>
 #include <linux/slab.h>
 #include <linux/clk.h>
+#include <linux/err.h>
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
 #include <linux/usb/otg.h>
@@ -1165,7 +1166,7 @@ static int s3c_hsudc_start(struct usb_gadget *gadget,
        }
 
        /* connect to bus through transceiver */
-       if (hsudc->transceiver) {
+       if (!IS_ERR_OR_NULL(hsudc->transceiver)) {
                ret = otg_set_peripheral(hsudc->transceiver->otg,
                                        &hsudc->gadget);
                if (ret) {
@@ -1220,7 +1221,7 @@ static int s3c_hsudc_stop(struct usb_gadget *gadget,
        s3c_hsudc_stop_activity(hsudc);
        spin_unlock_irqrestore(&hsudc->lock, flags);
 
-       if (hsudc->transceiver)
+       if (!IS_ERR_OR_NULL(hsudc->transceiver))
                (void) otg_set_peripheral(hsudc->transceiver->otg, NULL);
 
        disable_irq(hsudc->irq);
@@ -1249,7 +1250,7 @@ static int s3c_hsudc_vbus_draw(struct usb_gadget *gadget, unsigned mA)
        if (!hsudc)
                return -ENODEV;
 
-       if (hsudc->transceiver)
+       if (!IS_ERR_OR_NULL(hsudc->transceiver))
                return usb_phy_set_power(hsudc->transceiver, mA);
 
        return -EOPNOTSUPP;
@@ -1282,7 +1283,7 @@ static int __devinit s3c_hsudc_probe(struct platform_device *pdev)
        hsudc->dev = dev;
        hsudc->pd = pdev->dev.platform_data;
 
-       hsudc->transceiver = usb_get_transceiver();
+       hsudc->transceiver = usb_get_phy(USB_PHY_TYPE_USB2);
 
        for (i = 0; i < ARRAY_SIZE(hsudc->supplies); i++)
                hsudc->supplies[i].supply = s3c_hsudc_supply_names[i];
@@ -1385,8 +1386,8 @@ err_irq:
 err_remap:
        release_mem_region(res->start, resource_size(res));
 err_res:
-       if (hsudc->transceiver)
-               usb_put_transceiver(hsudc->transceiver);
+       if (!IS_ERR_OR_NULL(hsudc->transceiver))
+               usb_put_phy(hsudc->transceiver);
 
        regulator_bulk_free(ARRAY_SIZE(hsudc->supplies), hsudc->supplies);
 err_supplies:
index 3379945b095e23e47833b9c534ea1a98f2e5734a..74914de8b9bf64ad9d758222bc1bc9075bc8aa78 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/types.h>
 #include <linux/delay.h>
 #include <linux/pm.h>
+#include <linux/err.h>
 #include <linux/platform_device.h>
 #include <linux/fsl_devices.h>
 
@@ -142,15 +143,15 @@ static int usb_hcd_fsl_probe(const struct hc_driver *driver,
        if (pdata->operating_mode == FSL_USB2_DR_OTG) {
                struct ehci_hcd *ehci = hcd_to_ehci(hcd);
 
-               hcd->phy = usb_get_transceiver();
+               hcd->phy = usb_get_phy(USB_PHY_TYPE_USB2);
                dev_dbg(&pdev->dev, "hcd=0x%p  ehci=0x%p, phy=0x%p\n",
                        hcd, ehci, hcd->phy);
 
-               if (hcd->phy) {
+               if (!IS_ERR_OR_NULL(hcd->phy)) {
                        retval = otg_set_host(hcd->phy->otg,
                                              &ehci_to_hcd(ehci)->self);
                        if (retval) {
-                               usb_put_transceiver(hcd->phy);
+                               usb_put_phy(hcd->phy);
                                goto err4;
                        }
                } else {
@@ -191,9 +192,9 @@ static void usb_hcd_fsl_remove(struct usb_hcd *hcd,
 {
        struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data;
 
-       if (hcd->phy) {
+       if (!IS_ERR_OR_NULL(hcd->phy)) {
                otg_set_host(hcd->phy->otg, NULL);
-               usb_put_transceiver(hcd->phy);
+               usb_put_phy(hcd->phy);
        }
 
        usb_remove_hcd(hcd);
index 9803a55fd5f464b600d47b02ae3c2f923060473d..6b4ffb598db1e395480270330939c118bea48a55 100644 (file)
@@ -145,8 +145,8 @@ static int ehci_msm_probe(struct platform_device *pdev)
         * powering up VBUS, mapping of registers address space and power
         * management.
         */
-       phy = usb_get_transceiver();
-       if (!phy) {
+       phy = usb_get_phy(USB_PHY_TYPE_USB2);
+       if (IS_ERR_OR_NULL(phy)) {
                dev_err(&pdev->dev, "unable to find transceiver\n");
                ret = -ENODEV;
                goto unmap;
@@ -169,7 +169,7 @@ static int ehci_msm_probe(struct platform_device *pdev)
        return 0;
 
 put_transceiver:
-       usb_put_transceiver(phy);
+       usb_put_phy(phy);
 unmap:
        iounmap(hcd->regs);
 put_hcd:
@@ -187,7 +187,7 @@ static int __devexit ehci_msm_remove(struct platform_device *pdev)
        pm_runtime_set_suspended(&pdev->dev);
 
        otg_set_host(phy->otg, NULL);
-       usb_put_transceiver(phy);
+       usb_put_phy(phy);
 
        usb_put_hcd(hcd);
 
index a936bbcff8f496cd99d23256731887ecdd42c233..0e8c168ca24c1c88135841c7fddd492b3f69effd 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/err.h>
 #include <linux/usb/otg.h>
 #include <linux/platform_data/mv_usb.h>
 
@@ -253,8 +254,8 @@ static int mv_ehci_probe(struct platform_device *pdev)
        ehci_mv->mode = pdata->mode;
        if (ehci_mv->mode == MV_USB_MODE_OTG) {
 #ifdef CONFIG_USB_OTG_UTILS
-               ehci_mv->otg = usb_get_transceiver();
-               if (!ehci_mv->otg) {
+               ehci_mv->otg = usb_get_phy(USB_PHY_TYPE_USB2);
+               if (IS_ERR_OR_NULL(ehci_mv->otg)) {
                        dev_err(&pdev->dev,
                                "unable to find transceiver\n");
                        retval = -ENODEV;
@@ -302,8 +303,8 @@ err_set_vbus:
                pdata->set_vbus(0);
 #ifdef CONFIG_USB_OTG_UTILS
 err_put_transceiver:
-       if (ehci_mv->otg)
-               usb_put_transceiver(ehci_mv->otg);
+       if (!IS_ERR_OR_NULL(ehci_mv->otg))
+               usb_put_phy(ehci_mv->otg);
 #endif
 err_disable_clk:
        mv_ehci_disable(ehci_mv);
@@ -331,9 +332,9 @@ static int mv_ehci_remove(struct platform_device *pdev)
        if (hcd->rh_registered)
                usb_remove_hcd(hcd);
 
-       if (ehci_mv->otg) {
+       if (!IS_ERR_OR_NULL(ehci_mv->otg)) {
                otg_set_host(ehci_mv->otg->otg, NULL);
-               usb_put_transceiver(ehci_mv->otg);
+               usb_put_phy(ehci_mv->otg);
        }
 
        if (ehci_mv->mode == MV_USB_MODE_HOST) {
index 68548236ec4228ceb224d69845daba6345bf9971..477ecfa05154e3fdecfe3bd951e8d65cf1c65da2 100644 (file)
@@ -17,6 +17,7 @@
  */
 
 #include <linux/clk.h>
+#include <linux/err.h>
 #include <linux/platform_device.h>
 #include <linux/platform_data/tegra_usb.h>
 #include <linux/irq.h>
@@ -749,8 +750,8 @@ static int tegra_ehci_probe(struct platform_device *pdev)
 
 #ifdef CONFIG_USB_OTG_UTILS
        if (pdata->operating_mode == TEGRA_USB_OTG) {
-               tegra->transceiver = usb_get_transceiver();
-               if (tegra->transceiver)
+               tegra->transceiver = usb_get_phy(USB_PHY_TYPE_USB2);
+               if (!IS_ERR_OR_NULL(tegra->transceiver))
                        otg_set_host(tegra->transceiver->otg, &hcd->self);
        }
 #endif
@@ -773,9 +774,9 @@ static int tegra_ehci_probe(struct platform_device *pdev)
 
 fail:
 #ifdef CONFIG_USB_OTG_UTILS
-       if (tegra->transceiver) {
+       if (!IS_ERR_OR_NULL(tegra->transceiver)) {
                otg_set_host(tegra->transceiver->otg, NULL);
-               usb_put_transceiver(tegra->transceiver);
+               usb_put_phy(tegra->transceiver);
        }
 #endif
        tegra_usb_phy_close(tegra->phy);
@@ -808,9 +809,9 @@ static int tegra_ehci_remove(struct platform_device *pdev)
        pm_runtime_put_noidle(&pdev->dev);
 
 #ifdef CONFIG_USB_OTG_UTILS
-       if (tegra->transceiver) {
+       if (!IS_ERR_OR_NULL(tegra->transceiver)) {
                otg_set_host(tegra->transceiver->otg, NULL);
-               usb_put_transceiver(tegra->transceiver);
+               usb_put_phy(tegra->transceiver);
        }
 #endif
 
index eccddb461396d58ee6b10636f2379e21c0f67fc0..076d2018e6df752e4b3e1c30c3aa4f7598889797 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/jiffies.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/err.h>
 #include <linux/gpio.h>
 
 #include <mach/hardware.h>
@@ -212,14 +213,14 @@ static int ohci_omap_init(struct usb_hcd *hcd)
 
 #ifdef CONFIG_USB_OTG
        if (need_transceiver) {
-               hcd->phy = usb_get_transceiver();
-               if (hcd->phy) {
+               hcd->phy = usb_get_phy(USB_PHY_TYPE_USB2);
+               if (!IS_ERR_OR_NULL(hcd->phy)) {
                        int     status = otg_set_host(hcd->phy->otg,
                                                &ohci_to_hcd(ohci)->self);
                        dev_dbg(hcd->self.controller, "init %s phy, status %d\n",
                                        hcd->phy->label, status);
                        if (status) {
-                               usb_put_transceiver(hcd->phy);
+                               usb_put_phy(hcd->phy);
                                return status;
                        }
                } else {
@@ -404,9 +405,9 @@ usb_hcd_omap_remove (struct usb_hcd *hcd, struct platform_device *pdev)
        struct ohci_hcd         *ohci = hcd_to_ohci (hcd);
 
        usb_remove_hcd(hcd);
-       if (hcd->phy) {
+       if (!IS_ERR_OR_NULL(hcd->phy)) {
                (void) otg_set_host(hcd->phy->otg, 0);
-               usb_put_transceiver(hcd->phy);
+               usb_put_phy(hcd->phy);
        }
        if (machine_is_omap_osk())
                gpio_free(9);
index 9f3eda91ea4ddd980a8a7465d319e53ae30c19f4..7a95ab87ac00feaafe788342305cfb1d36255fbc 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/clk.h>
+#include <linux/err.h>
 #include <linux/io.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
@@ -364,8 +365,8 @@ static int am35x_musb_init(struct musb *musb)
                return -ENODEV;
 
        usb_nop_xceiv_register();
-       musb->xceiv = usb_get_transceiver();
-       if (!musb->xceiv)
+       musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2);
+       if (IS_ERR_OR_NULL(musb->xceiv))
                return -ENODEV;
 
        if (is_host_enabled(musb))
@@ -406,7 +407,7 @@ static int am35x_musb_exit(struct musb *musb)
        if (data->set_phy_power)
                data->set_phy_power(0);
 
-       usb_put_transceiver(musb->xceiv);
+       usb_put_phy(musb->xceiv);
        usb_nop_xceiv_unregister();
 
        return 0;
index a087ed6c3be9433c9e761bdb5f8b84374e62a853..428e6aa3e78a46a3b917fe6a079434d933caf4e6 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/list.h>
 #include <linux/gpio.h>
 #include <linux/io.h>
+#include <linux/err.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 #include <linux/prefetch.h>
@@ -415,8 +416,8 @@ static int bfin_musb_init(struct musb *musb)
        gpio_direction_output(musb->config->gpio_vrsel, 0);
 
        usb_nop_xceiv_register();
-       musb->xceiv = usb_get_transceiver();
-       if (!musb->xceiv) {
+       musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2);
+       if (IS_ERR_OR_NULL(musb->xceiv)) {
                gpio_free(musb->config->gpio_vrsel);
                return -ENODEV;
        }
@@ -440,7 +441,7 @@ static int bfin_musb_exit(struct musb *musb)
 {
        gpio_free(musb->config->gpio_vrsel);
 
-       usb_put_transceiver(musb->xceiv);
+       usb_put_phy(musb->xceiv);
        usb_nop_xceiv_unregister();
        return 0;
 }
index 8bd9566f3fbb0dc35968fe5b83d3be219662a730..0f9fcec4e1d3075d8c4e44c4aaa39066bece4f5c 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/clk.h>
+#include <linux/err.h>
 #include <linux/io.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
@@ -425,8 +426,8 @@ static int da8xx_musb_init(struct musb *musb)
                goto fail;
 
        usb_nop_xceiv_register();
-       musb->xceiv = usb_get_transceiver();
-       if (!musb->xceiv)
+       musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2);
+       if (IS_ERR_OR_NULL(musb->xceiv))
                goto fail;
 
        if (is_host_enabled(musb))
@@ -458,7 +459,7 @@ static int da8xx_musb_exit(struct musb *musb)
 
        phy_off();
 
-       usb_put_transceiver(musb->xceiv);
+       usb_put_phy(musb->xceiv);
        usb_nop_xceiv_unregister();
 
        return 0;
index 9d63ba4d10d6fe1500cf1b73e3ccf5e3c111f952..472c8b42d38b3a2007d3afa74c526b6431b031cf 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/list.h>
 #include <linux/delay.h>
 #include <linux/clk.h>
+#include <linux/err.h>
 #include <linux/io.h>
 #include <linux/gpio.h>
 #include <linux/platform_device.h>
@@ -385,8 +386,8 @@ static int davinci_musb_init(struct musb *musb)
        u32             revision;
 
        usb_nop_xceiv_register();
-       musb->xceiv = usb_get_transceiver();
-       if (!musb->xceiv)
+       musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2);
+       if (IS_ERR_OR_NULL(musb->xceiv))
                goto unregister;
 
        musb->mregs += DAVINCI_BASE_OFFSET;
@@ -444,7 +445,7 @@ static int davinci_musb_init(struct musb *musb)
        return 0;
 
 fail:
-       usb_put_transceiver(musb->xceiv);
+       usb_put_phy(musb->xceiv);
 unregister:
        usb_nop_xceiv_unregister();
        return -ENODEV;
@@ -494,7 +495,7 @@ static int davinci_musb_exit(struct musb *musb)
 
        phy_off();
 
-       usb_put_transceiver(musb->xceiv);
+       usb_put_phy(musb->xceiv);
        usb_nop_xceiv_unregister();
 
        return 0;
index db3dff854b715f2bf781846962db45caefe26487..26f1befb489677a7d214bcb90b26bf1775f67733 100644 (file)
@@ -1909,7 +1909,7 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
        /* The musb_platform_init() call:
         *   - adjusts musb->mregs and musb->isr if needed,
         *   - may initialize an integrated tranceiver
-        *   - initializes musb->xceiv, usually by otg_get_transceiver()
+        *   - initializes musb->xceiv, usually by otg_get_phy()
         *   - stops powering VBUS
         *
         * There are various transceiver configurations.  Blackfin,
index f4a40f001c8803eecfedab2af6dfcdd50d95ed22..dbcdeea30f09c199d0ebaa9b3f14a8f4d9179919 100644 (file)
@@ -327,7 +327,6 @@ struct musb {
 
        irqreturn_t             (*isr)(int, void *);
        struct work_struct      irq_work;
-       struct work_struct      otg_notifier_work;
        u16                     hwvers;
 
 /* this hub status bit is reserved by USB 2.0 and not seen by usbcore */
@@ -373,7 +372,6 @@ struct musb {
        u16                     int_tx;
 
        struct usb_phy          *xceiv;
-       u8                      xceiv_event;
 
        int nIrq;
        unsigned                irq_wake:1;
index 23db42db761a5de85a91e23efabe7ae53cfebaa2..217808d9fbe1991298da67295404d50cd71e593a 100644 (file)
@@ -31,6 +31,7 @@
 
 #include <linux/init.h>
 #include <linux/io.h>
+#include <linux/err.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 #include <linux/pm_runtime.h>
@@ -376,8 +377,8 @@ static int dsps_musb_init(struct musb *musb)
 
        /* NOP driver needs change if supporting dual instance */
        usb_nop_xceiv_register();
-       musb->xceiv = usb_get_transceiver();
-       if (!musb->xceiv)
+       musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2);
+       if (IS_ERR_OR_NULL(musb->xceiv))
                return -ENODEV;
 
        /* Returns zero if e.g. not clocked */
@@ -409,7 +410,7 @@ static int dsps_musb_init(struct musb *musb)
 
        return 0;
 err0:
-       usb_put_transceiver(musb->xceiv);
+       usb_put_phy(musb->xceiv);
        usb_nop_xceiv_unregister();
        return status;
 }
@@ -430,7 +431,7 @@ static int dsps_musb_exit(struct musb *musb)
                data->set_phy_power(0);
 
        /* NOP driver needs change if supporting dual instance */
-       usb_put_transceiver(musb->xceiv);
+       usb_put_phy(musb->xceiv);
        usb_nop_xceiv_unregister();
 
        return 0;
index c7785e81254cdf96eef46f352ee134fc8ca759aa..5fdb9da8dd5685789557d762377631601912c54a 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/pm_runtime.h>
 #include <linux/err.h>
+#include <linux/usb/musb-omap.h>
 
 #include "musb_core.h"
 #include "omap2430.h"
 struct omap2430_glue {
        struct device           *dev;
        struct platform_device  *musb;
+       enum omap_musb_vbus_id_status status;
+       struct work_struct      omap_musb_mailbox_work;
 };
 #define glue_to_musb(g)                platform_get_drvdata(g->musb)
 
+struct omap2430_glue           *_glue;
+
 static struct timer_list musb_idle_timer;
 
 static void musb_do_idle(unsigned long _musb)
@@ -223,50 +228,63 @@ static inline void omap2430_low_level_init(struct musb *musb)
        musb_writel(musb->mregs, OTG_FORCESTDBY, l);
 }
 
-static int musb_otg_notifications(struct notifier_block *nb,
-               unsigned long event, void *unused)
+void omap_musb_mailbox(enum omap_musb_vbus_id_status status)
 {
-       struct musb     *musb = container_of(nb, struct musb, nb);
+       struct omap2430_glue    *glue = _glue;
+       struct musb             *musb = glue_to_musb(glue);
 
-       musb->xceiv_event = event;
-       schedule_work(&musb->otg_notifier_work);
+       glue->status = status;
+       if (!musb) {
+               dev_err(glue->dev, "musb core is not yet ready\n");
+               return;
+       }
 
-       return NOTIFY_OK;
+       schedule_work(&glue->omap_musb_mailbox_work);
 }
+EXPORT_SYMBOL_GPL(omap_musb_mailbox);
 
-static void musb_otg_notifier_work(struct work_struct *data_notifier_work)
+static void omap_musb_set_mailbox(struct omap2430_glue *glue)
 {
-       struct musb *musb = container_of(data_notifier_work, struct musb, otg_notifier_work);
+       struct musb *musb = glue_to_musb(glue);
        struct device *dev = musb->controller;
        struct musb_hdrc_platform_data *pdata = dev->platform_data;
        struct omap_musb_board_data *data = pdata->board_data;
+       struct usb_otg *otg = musb->xceiv->otg;
 
-       switch (musb->xceiv_event) {
-       case USB_EVENT_ID:
-               dev_dbg(musb->controller, "ID GND\n");
+       switch (glue->status) {
+       case OMAP_MUSB_ID_GROUND:
+               dev_dbg(dev, "ID GND\n");
 
+               otg->default_a = true;
+               musb->xceiv->state = OTG_STATE_A_IDLE;
+               musb->xceiv->last_event = USB_EVENT_ID;
                if (!is_otg_enabled(musb) || musb->gadget_driver) {
-                       pm_runtime_get_sync(musb->controller);
+                       pm_runtime_get_sync(dev);
                        usb_phy_init(musb->xceiv);
                        omap2430_musb_set_vbus(musb, 1);
                }
                break;
 
-       case USB_EVENT_VBUS:
-               dev_dbg(musb->controller, "VBUS Connect\n");
+       case OMAP_MUSB_VBUS_VALID:
+               dev_dbg(dev, "VBUS Connect\n");
 
+               otg->default_a = false;
+               musb->xceiv->state = OTG_STATE_B_IDLE;
+               musb->xceiv->last_event = USB_EVENT_VBUS;
                if (musb->gadget_driver)
-                       pm_runtime_get_sync(musb->controller);
+                       pm_runtime_get_sync(dev);
                usb_phy_init(musb->xceiv);
                break;
 
-       case USB_EVENT_NONE:
-               dev_dbg(musb->controller, "VBUS Disconnect\n");
+       case OMAP_MUSB_ID_FLOAT:
+       case OMAP_MUSB_VBUS_OFF:
+               dev_dbg(dev, "VBUS Disconnect\n");
 
+               musb->xceiv->last_event = USB_EVENT_NONE;
                if (is_otg_enabled(musb) || is_peripheral_enabled(musb))
                        if (musb->gadget_driver) {
-                               pm_runtime_mark_last_busy(musb->controller);
-                               pm_runtime_put_autosuspend(musb->controller);
+                               pm_runtime_mark_last_busy(dev);
+                               pm_runtime_put_autosuspend(dev);
                        }
 
                if (data->interface_type == MUSB_INTERFACE_UTMI) {
@@ -276,15 +294,24 @@ static void musb_otg_notifier_work(struct work_struct *data_notifier_work)
                usb_phy_shutdown(musb->xceiv);
                break;
        default:
-               dev_dbg(musb->controller, "ID float\n");
+               dev_dbg(dev, "ID float\n");
        }
 }
 
+
+static void omap_musb_mailbox_work(struct work_struct *mailbox_work)
+{
+       struct omap2430_glue *glue = container_of(mailbox_work,
+                               struct omap2430_glue, omap_musb_mailbox_work);
+       omap_musb_set_mailbox(glue);
+}
+
 static int omap2430_musb_init(struct musb *musb)
 {
        u32 l;
        int status = 0;
        struct device *dev = musb->controller;
+       struct omap2430_glue *glue = dev_get_drvdata(dev->parent);
        struct musb_hdrc_platform_data *plat = dev->platform_data;
        struct omap_musb_board_data *data = plat->board_data;
 
@@ -292,14 +319,12 @@ static int omap2430_musb_init(struct musb *musb)
         * up through ULPI.  TWL4030-family PMICs include one,
         * which needs a driver, drivers aren't always needed.
         */
-       musb->xceiv = usb_get_transceiver();
-       if (!musb->xceiv) {
+       musb->xceiv = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
+       if (IS_ERR_OR_NULL(musb->xceiv)) {
                pr_err("HS USB OTG: no transceiver configured\n");
                return -ENODEV;
        }
 
-       INIT_WORK(&musb->otg_notifier_work, musb_otg_notifier_work);
-
        status = pm_runtime_get_sync(dev);
        if (status < 0) {
                dev_err(dev, "pm_runtime_get_sync FAILED %d\n", status);
@@ -326,14 +351,11 @@ static int omap2430_musb_init(struct musb *musb)
                        musb_readl(musb->mregs, OTG_INTERFSEL),
                        musb_readl(musb->mregs, OTG_SIMENABLE));
 
-       musb->nb.notifier_call = musb_otg_notifications;
-       status = usb_register_notifier(musb->xceiv, &musb->nb);
-
-       if (status)
-               dev_dbg(musb->controller, "notification register failed\n");
-
        setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb);
 
+       if (glue->status != OMAP_MUSB_UNKNOWN)
+               omap_musb_set_mailbox(glue);
+
        pm_runtime_put_noidle(musb->controller);
        return 0;
 
@@ -346,12 +368,13 @@ static void omap2430_musb_enable(struct musb *musb)
        u8              devctl;
        unsigned long timeout = jiffies + msecs_to_jiffies(1000);
        struct device *dev = musb->controller;
+       struct omap2430_glue *glue = dev_get_drvdata(dev->parent);
        struct musb_hdrc_platform_data *pdata = dev->platform_data;
        struct omap_musb_board_data *data = pdata->board_data;
 
-       switch (musb->xceiv->last_event) {
+       switch (glue->status) {
 
-       case USB_EVENT_ID:
+       case OMAP_MUSB_ID_GROUND:
                usb_phy_init(musb->xceiv);
                if (data->interface_type != MUSB_INTERFACE_UTMI)
                        break;
@@ -370,7 +393,7 @@ static void omap2430_musb_enable(struct musb *musb)
                }
                break;
 
-       case USB_EVENT_VBUS:
+       case OMAP_MUSB_VBUS_VALID:
                usb_phy_init(musb->xceiv);
                break;
 
@@ -381,17 +404,18 @@ static void omap2430_musb_enable(struct musb *musb)
 
 static void omap2430_musb_disable(struct musb *musb)
 {
-       if (musb->xceiv->last_event)
+       struct device *dev = musb->controller;
+       struct omap2430_glue *glue = dev_get_drvdata(dev->parent);
+
+       if (glue->status != OMAP_MUSB_UNKNOWN)
                usb_phy_shutdown(musb->xceiv);
 }
 
 static int omap2430_musb_exit(struct musb *musb)
 {
        del_timer_sync(&musb_idle_timer);
-       cancel_work_sync(&musb->otg_notifier_work);
 
        omap2430_low_level_exit(musb);
-       usb_put_transceiver(musb->xceiv);
 
        return 0;
 }
@@ -418,7 +442,7 @@ static int __devinit omap2430_probe(struct platform_device *pdev)
        struct omap2430_glue            *glue;
        int                             ret = -ENOMEM;
 
-       glue = kzalloc(sizeof(*glue), GFP_KERNEL);
+       glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL);
        if (!glue) {
                dev_err(&pdev->dev, "failed to allocate glue context\n");
                goto err0;
@@ -427,7 +451,7 @@ static int __devinit omap2430_probe(struct platform_device *pdev)
        musb = platform_device_alloc("musb-hdrc", -1);
        if (!musb) {
                dev_err(&pdev->dev, "failed to allocate musb device\n");
-               goto err1;
+               goto err0;
        }
 
        musb->dev.parent                = &pdev->dev;
@@ -436,22 +460,31 @@ static int __devinit omap2430_probe(struct platform_device *pdev)
 
        glue->dev                       = &pdev->dev;
        glue->musb                      = musb;
+       glue->status                    = OMAP_MUSB_UNKNOWN;
 
        pdata->platform_ops             = &omap2430_ops;
 
        platform_set_drvdata(pdev, glue);
 
+       /*
+        * REVISIT if we ever have two instances of the wrapper, we will be
+        * in big trouble
+        */
+       _glue   = glue;
+
+       INIT_WORK(&glue->omap_musb_mailbox_work, omap_musb_mailbox_work);
+
        ret = platform_device_add_resources(musb, pdev->resource,
                        pdev->num_resources);
        if (ret) {
                dev_err(&pdev->dev, "failed to add resources\n");
-               goto err2;
+               goto err1;
        }
 
        ret = platform_device_add_data(musb, pdata, sizeof(*pdata));
        if (ret) {
                dev_err(&pdev->dev, "failed to add platform_data\n");
-               goto err2;
+               goto err1;
        }
 
        pm_runtime_enable(&pdev->dev);
@@ -459,16 +492,13 @@ static int __devinit omap2430_probe(struct platform_device *pdev)
        ret = platform_device_add(musb);
        if (ret) {
                dev_err(&pdev->dev, "failed to register musb device\n");
-               goto err2;
+               goto err1;
        }
 
        return 0;
 
-err2:
-       platform_device_put(musb);
-
 err1:
-       kfree(glue);
+       platform_device_put(musb);
 
 err0:
        return ret;
@@ -478,9 +508,9 @@ static int __devexit omap2430_remove(struct platform_device *pdev)
 {
        struct omap2430_glue            *glue = platform_get_drvdata(pdev);
 
+       cancel_work_sync(&glue->omap_musb_mailbox_work);
        platform_device_del(glue->musb);
        platform_device_put(glue->musb);
-       kfree(glue);
 
        return 0;
 }
@@ -546,7 +576,7 @@ static int __init omap2430_init(void)
 {
        return platform_driver_register(&omap2430_driver);
 }
-module_init(omap2430_init);
+subsys_initcall(omap2430_init);
 
 static void __exit omap2430_exit(void)
 {
index de1355946a83a850a5df01bbb9e42e36320cf7c8..1a1bd9cf40c5ce7c1d6f7ef1ac46360d0b6884a4 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
+#include <linux/err.h>
 #include <linux/init.h>
 #include <linux/prefetch.h>
 #include <linux/usb.h>
@@ -1078,8 +1079,8 @@ static int tusb_musb_init(struct musb *musb)
        int                     ret;
 
        usb_nop_xceiv_register();
-       musb->xceiv = usb_get_transceiver();
-       if (!musb->xceiv)
+       musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2);
+       if (IS_ERR_OR_NULL(musb->xceiv))
                return -ENODEV;
 
        pdev = to_platform_device(musb->controller);
@@ -1130,7 +1131,7 @@ done:
                if (sync)
                        iounmap(sync);
 
-               usb_put_transceiver(musb->xceiv);
+               usb_put_phy(musb->xceiv);
                usb_nop_xceiv_unregister();
        }
        return ret;
@@ -1146,7 +1147,7 @@ static int tusb_musb_exit(struct musb *musb)
 
        iounmap(musb->sync_va);
 
-       usb_put_transceiver(musb->xceiv);
+       usb_put_phy(musb->xceiv);
        usb_nop_xceiv_unregister();
        return 0;
 }
index aa09dd417b9465662764943d49ed84b37070d369..a8c0fadce1b0e1006070c7e5e0fc3b5433c5e496 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/clk.h>
+#include <linux/err.h>
 #include <linux/io.h>
 #include <linux/platform_device.h>
 
@@ -37,8 +38,8 @@ struct ux500_glue {
 
 static int ux500_musb_init(struct musb *musb)
 {
-       musb->xceiv = usb_get_transceiver();
-       if (!musb->xceiv) {
+       musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2);
+       if (IS_ERR_OR_NULL(musb->xceiv)) {
                pr_err("HS USB OTG: no transceiver configured\n");
                return -ENODEV;
        }
@@ -48,7 +49,7 @@ static int ux500_musb_init(struct musb *musb)
 
 static int ux500_musb_exit(struct musb *musb)
 {
-       usb_put_transceiver(musb->xceiv);
+       usb_put_phy(musb->xceiv);
 
        return 0;
 }
index a84af677dc5941387dfc0d3805a5444fe21d0243..ae8ad561f08326144fe51d97bde495ad603611f0 100644 (file)
@@ -529,7 +529,7 @@ static int __devinit ab8500_usb_probe(struct platform_device *pdev)
        if (err < 0)
                goto fail0;
 
-       err = usb_set_transceiver(&ab->phy);
+       err = usb_add_phy(&ab->phy, USB_PHY_TYPE_USB2);
        if (err) {
                dev_err(&pdev->dev, "Can't register transceiver\n");
                goto fail1;
@@ -556,7 +556,7 @@ static int __devexit ab8500_usb_remove(struct platform_device *pdev)
 
        cancel_work_sync(&ab->phy_dis_work);
 
-       usb_set_transceiver(NULL);
+       usb_remove_phy(&ab->phy);
 
        ab8500_usb_host_phy_dis(ab);
        ab8500_usb_peri_phy_dis(ab);
index be4a63e8302f17a0e4bc6fba6fc0ab408a2efb1f..23c798cb2d7f23e9ce83ace89265b576fe816152 100644 (file)
@@ -806,7 +806,7 @@ static int fsl_otg_conf(struct platform_device *pdev)
        fsl_otg_dev = fsl_otg_tc;
 
        /* Store the otg transceiver */
-       status = usb_set_transceiver(&fsl_otg_tc->phy);
+       status = usb_add_phy(&fsl_otg_tc->phy, USB_PHY_TYPE_USB2);
        if (status) {
                pr_warn(FSL_OTG_NAME ": unable to register OTG transceiver.\n");
                goto err;
@@ -824,7 +824,7 @@ err:
 int usb_otg_start(struct platform_device *pdev)
 {
        struct fsl_otg *p_otg;
-       struct usb_phy *otg_trans = usb_get_transceiver();
+       struct usb_phy *otg_trans = usb_get_phy(USB_PHY_TYPE_USB2);
        struct otg_fsm *fsm;
        int status;
        struct resource *res;
@@ -1134,7 +1134,7 @@ static int __devexit fsl_otg_remove(struct platform_device *pdev)
 {
        struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data;
 
-       usb_set_transceiver(NULL);
+       usb_remove_phy(&fsl_otg_dev->phy);
        free_irq(fsl_otg_dev->irq, fsl_otg_dev);
 
        iounmap((void *)usb_dr_regs);
index bde6298a9693aa01f15f218bac544b252082ee3e..a67ffe22179a5719674e236cbe322260da1e43e9 100644 (file)
@@ -320,7 +320,7 @@ static int __init gpio_vbus_probe(struct platform_device *pdev)
        }
 
        /* only active when a gadget is registered */
-       err = usb_set_transceiver(&gpio_vbus->phy);
+       err = usb_add_phy(&gpio_vbus->phy, USB_PHY_TYPE_USB2);
        if (err) {
                dev_err(&pdev->dev, "can't register transceiver, err: %d\n",
                        err);
@@ -354,7 +354,7 @@ static int __exit gpio_vbus_remove(struct platform_device *pdev)
        cancel_delayed_work_sync(&gpio_vbus->work);
        regulator_put(gpio_vbus->vbus_draw);
 
-       usb_set_transceiver(NULL);
+       usb_remove_phy(&gpio_vbus->phy);
 
        free_irq(gpio_vbus->irq, pdev);
        if (gpio_is_valid(pdata->gpio_pullup))
index 70cf5d7bca48ed25ee08aa6e5fa40dec52b4268a..75cea4ab0985c024410f914fdf7e5c9f0cbcd63e 100644 (file)
@@ -1336,9 +1336,6 @@ static int
 isp1301_set_peripheral(struct usb_otg *otg, struct usb_gadget *gadget)
 {
        struct isp1301  *isp = container_of(otg->phy, struct isp1301, phy);
-#ifndef        CONFIG_USB_OTG
-       u32 l;
-#endif
 
        if (!otg || isp != the_transceiver)
                return -ENODEV;
@@ -1365,10 +1362,14 @@ isp1301_set_peripheral(struct usb_otg *otg, struct usb_gadget *gadget)
        otg->gadget = gadget;
        // FIXME update its refcount
 
-       l = omap_readl(OTG_CTRL) & OTG_CTRL_MASK;
-       l &= ~(OTG_XCEIV_OUTPUTS|OTG_CTRL_BITS);
-       l |= OTG_ID;
-       omap_writel(l, OTG_CTRL);
+       {
+               u32 l;
+
+               l = omap_readl(OTG_CTRL) & OTG_CTRL_MASK;
+               l &= ~(OTG_XCEIV_OUTPUTS|OTG_CTRL_BITS);
+               l |= OTG_ID;
+               omap_writel(l, OTG_CTRL);
+       }
 
        power_up(isp);
        isp->phy.state = OTG_STATE_B_IDLE;
@@ -1610,7 +1611,7 @@ isp1301_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
        dev_dbg(&i2c->dev, "scheduled timer, %d min\n", TIMER_MINUTES);
 #endif
 
-       status = usb_set_transceiver(&isp->phy);
+       status = usb_add_phy(&isp->phy, USB_PHY_TYPE_USB2);
        if (status < 0)
                dev_err(&i2c->dev, "can't register transceiver, %d\n",
                        status);
@@ -1649,7 +1650,7 @@ subsys_initcall(isp_init);
 static void __exit isp_exit(void)
 {
        if (the_transceiver)
-               usb_set_transceiver(NULL);
+               usb_remove_phy(&the_transceiver->phy);
        i2c_del_driver(&isp1301_driver);
 }
 module_exit(isp_exit);
index 1d0347c247d184c42548b30d3fc8c3496296b819..9f5fc906041a201e3cac694027fe8bd506c9441d 100644 (file)
@@ -1555,9 +1555,9 @@ static int __init msm_otg_probe(struct platform_device *pdev)
        phy->otg->set_host = msm_otg_set_host;
        phy->otg->set_peripheral = msm_otg_set_peripheral;
 
-       ret = usb_set_transceiver(&motg->phy);
+       ret = usb_add_phy(&motg->phy, USB_PHY_TYPE_USB2);
        if (ret) {
-               dev_err(&pdev->dev, "usb_set_transceiver failed\n");
+               dev_err(&pdev->dev, "usb_add_phy failed\n");
                goto free_irq;
        }
 
@@ -1624,7 +1624,7 @@ static int __devexit msm_otg_remove(struct platform_device *pdev)
        device_init_wakeup(&pdev->dev, 0);
        pm_runtime_disable(&pdev->dev);
 
-       usb_set_transceiver(NULL);
+       usb_remove_phy(phy);
        free_irq(motg->irq, motg);
 
        /*
index 6cc6c3ffbb83d6b4f2f8b036da714a7dbb0b1f42..3f124e8f5792957585494cf91234dad6d6e62888 100644 (file)
@@ -690,7 +690,7 @@ int mv_otg_remove(struct platform_device *pdev)
        for (clk_i = 0; clk_i <= mvotg->clknum; clk_i++)
                clk_put(mvotg->clk[clk_i]);
 
-       usb_set_transceiver(NULL);
+       usb_remove_phy(&mvotg->phy);
        platform_set_drvdata(pdev, NULL);
 
        kfree(mvotg->phy.otg);
@@ -853,7 +853,7 @@ static int mv_otg_probe(struct platform_device *pdev)
                goto err_disable_clk;
        }
 
-       retval = usb_set_transceiver(&mvotg->phy);
+       retval = usb_add_phy(&mvotg->phy, USB_PHY_TYPE_USB2);
        if (retval < 0) {
                dev_err(&pdev->dev, "can't register transceiver, %d\n",
                        retval);
@@ -880,7 +880,7 @@ static int mv_otg_probe(struct platform_device *pdev)
        return 0;
 
 err_set_transceiver:
-       usb_set_transceiver(NULL);
+       usb_remove_phy(&mvotg->phy);
 err_free_irq:
        free_irq(mvotg->irq, mvotg);
 err_disable_clk:
index 58b26df6afd1b3a457f2f1897b3c43d176a6e42c..803f958f413398400346977ae76c417c64302206 100644 (file)
@@ -117,7 +117,7 @@ static int __devinit nop_usb_xceiv_probe(struct platform_device *pdev)
        nop->phy.otg->set_host          = nop_set_host;
        nop->phy.otg->set_peripheral    = nop_set_peripheral;
 
-       err = usb_set_transceiver(&nop->phy);
+       err = usb_add_phy(&nop->phy, USB_PHY_TYPE_USB2);
        if (err) {
                dev_err(&pdev->dev, "can't register transceiver, err: %d\n",
                        err);
@@ -139,7 +139,7 @@ static int __devexit nop_usb_xceiv_remove(struct platform_device *pdev)
 {
        struct nop_usb_xceiv *nop = platform_get_drvdata(pdev);
 
-       usb_set_transceiver(NULL);
+       usb_remove_phy(&nop->phy);
 
        platform_set_drvdata(pdev, NULL);
        kfree(nop->phy.otg);
index 801e597a15413ece58964805e494c959315b26a1..1bf60a22595c706c2213720b1514391002e6284b 100644 (file)
 
 #include <linux/kernel.h>
 #include <linux/export.h>
+#include <linux/err.h>
 #include <linux/device.h>
+#include <linux/slab.h>
 
 #include <linux/usb/otg.h>
 
-static struct usb_phy *phy;
+static LIST_HEAD(phy_list);
+static DEFINE_SPINLOCK(phy_lock);
+
+static struct usb_phy *__usb_find_phy(struct list_head *list,
+       enum usb_phy_type type)
+{
+       struct usb_phy  *phy = NULL;
+
+       list_for_each_entry(phy, list, head) {
+               if (phy->type != type)
+                       continue;
+
+               return phy;
+       }
+
+       return ERR_PTR(-ENODEV);
+}
+
+static void devm_usb_phy_release(struct device *dev, void *res)
+{
+       struct usb_phy *phy = *(struct usb_phy **)res;
+
+       usb_put_phy(phy);
+}
+
+static int devm_usb_phy_match(struct device *dev, void *res, void *match_data)
+{
+       return res == match_data;
+}
 
 /**
- * usb_get_transceiver - find the (single) USB transceiver
+ * devm_usb_get_phy - find the USB PHY
+ * @dev - device that requests this phy
+ * @type - the type of the phy the controller requires
  *
- * Returns the transceiver driver, after getting a refcount to it; or
- * null if there is no such transceiver.  The caller is responsible for
- * calling usb_put_transceiver() to release that count.
+ * Gets the phy using usb_get_phy(), and associates a device with it using
+ * devres. On driver detach, release function is invoked on the devres data,
+ * then, devres data is freed.
  *
  * For use by USB host and peripheral drivers.
  */
-struct usb_phy *usb_get_transceiver(void)
+struct usb_phy *devm_usb_get_phy(struct device *dev, enum usb_phy_type type)
 {
-       if (phy)
-               get_device(phy->dev);
+       struct usb_phy **ptr, *phy;
+
+       ptr = devres_alloc(devm_usb_phy_release, sizeof(*ptr), GFP_KERNEL);
+       if (!ptr)
+               return NULL;
+
+       phy = usb_get_phy(type);
+       if (!IS_ERR(phy)) {
+               *ptr = phy;
+               devres_add(dev, ptr);
+       } else
+               devres_free(ptr);
+
+       return phy;
+}
+EXPORT_SYMBOL(devm_usb_get_phy);
+
+/**
+ * usb_get_phy - find the USB PHY
+ * @type - the type of the phy the controller requires
+ *
+ * Returns the phy driver, after getting a refcount to it; or
+ * -ENODEV if there is no such phy.  The caller is responsible for
+ * calling usb_put_phy() to release that count.
+ *
+ * For use by USB host and peripheral drivers.
+ */
+struct usb_phy *usb_get_phy(enum usb_phy_type type)
+{
+       struct usb_phy  *phy = NULL;
+       unsigned long   flags;
+
+       spin_lock_irqsave(&phy_lock, flags);
+
+       phy = __usb_find_phy(&phy_list, type);
+       if (IS_ERR(phy)) {
+               pr_err("unable to find transceiver of type %s\n",
+                       usb_phy_type_string(type));
+               goto err0;
+       }
+
+       get_device(phy->dev);
+
+err0:
+       spin_unlock_irqrestore(&phy_lock, flags);
+
        return phy;
 }
-EXPORT_SYMBOL(usb_get_transceiver);
+EXPORT_SYMBOL(usb_get_phy);
+
+/**
+ * devm_usb_put_phy - release the USB PHY
+ * @dev - device that wants to release this phy
+ * @phy - the phy returned by devm_usb_get_phy()
+ *
+ * destroys the devres associated with this phy and invokes usb_put_phy
+ * to release the phy.
+ *
+ * For use by USB host and peripheral drivers.
+ */
+void devm_usb_put_phy(struct device *dev, struct usb_phy *phy)
+{
+       int r;
+
+       r = devres_destroy(dev, devm_usb_phy_release, devm_usb_phy_match, phy);
+       dev_WARN_ONCE(dev, r, "couldn't find PHY resource\n");
+}
+EXPORT_SYMBOL(devm_usb_put_phy);
 
 /**
- * usb_put_transceiver - release the (single) USB transceiver
- * @x: the transceiver returned by usb_get_transceiver()
+ * usb_put_phy - release the USB PHY
+ * @x: the phy returned by usb_get_phy()
  *
- * Releases a refcount the caller received from usb_get_transceiver().
+ * Releases a refcount the caller received from usb_get_phy().
  *
  * For use by USB host and peripheral drivers.
  */
-void usb_put_transceiver(struct usb_phy *x)
+void usb_put_phy(struct usb_phy *x)
 {
        if (x)
                put_device(x->dev);
 }
-EXPORT_SYMBOL(usb_put_transceiver);
+EXPORT_SYMBOL(usb_put_phy);
 
 /**
- * usb_set_transceiver - declare the (single) USB transceiver
- * @x: the USB transceiver to be used; or NULL
+ * usb_add_phy - declare the USB PHY
+ * @x: the USB phy to be used; or NULL
+ * @type - the type of this PHY
  *
- * This call is exclusively for use by transceiver drivers, which
+ * This call is exclusively for use by phy drivers, which
  * coordinate the activities of drivers for host and peripheral
  * controllers, and in some cases for VBUS current regulation.
  */
-int usb_set_transceiver(struct usb_phy *x)
+int usb_add_phy(struct usb_phy *x, enum usb_phy_type type)
+{
+       int             ret = 0;
+       unsigned long   flags;
+       struct usb_phy  *phy;
+
+       if (x && x->type != USB_PHY_TYPE_UNDEFINED) {
+               dev_err(x->dev, "not accepting initialized PHY %s\n", x->label);
+               return -EINVAL;
+       }
+
+       spin_lock_irqsave(&phy_lock, flags);
+
+       list_for_each_entry(phy, &phy_list, head) {
+               if (phy->type == type) {
+                       ret = -EBUSY;
+                       dev_err(x->dev, "transceiver type %s already exists\n",
+                                               usb_phy_type_string(type));
+                       goto out;
+               }
+       }
+
+       x->type = type;
+       list_add_tail(&x->head, &phy_list);
+
+out:
+       spin_unlock_irqrestore(&phy_lock, flags);
+       return ret;
+}
+EXPORT_SYMBOL(usb_add_phy);
+
+/**
+ * usb_remove_phy - remove the OTG PHY
+ * @x: the USB OTG PHY to be removed;
+ *
+ * This reverts the effects of usb_add_phy
+ */
+void usb_remove_phy(struct usb_phy *x)
 {
-       if (phy && x)
-               return -EBUSY;
-       phy = x;
-       return 0;
+       unsigned long   flags;
+
+       spin_lock_irqsave(&phy_lock, flags);
+       if (x)
+               list_del(&x->head);
+       spin_unlock_irqrestore(&phy_lock, flags);
 }
-EXPORT_SYMBOL(usb_set_transceiver);
+EXPORT_SYMBOL(usb_remove_phy);
 
 const char *otg_state_string(enum usb_otg_state state)
 {
index c4a86da858e25f72d15d7c13ca0adea8e6a46d89..523cad5bfea947deca4d288a338cc3acc4c9c3a1 100644 (file)
 #include <linux/io.h>
 #include <linux/delay.h>
 #include <linux/usb/otg.h>
+#include <linux/usb/musb-omap.h>
 #include <linux/usb/ulpi.h>
 #include <linux/i2c/twl.h>
 #include <linux/regulator/consumer.h>
 #include <linux/err.h>
-#include <linux/notifier.h>
 #include <linux/slab.h>
 
 /* Register defines */
@@ -159,7 +159,7 @@ struct twl4030_usb {
        enum twl4030_usb_mode   usb_mode;
 
        int                     irq;
-       u8                      linkstat;
+       enum omap_musb_vbus_id_status linkstat;
        bool                    vbus_supplied;
        u8                      asleep;
        bool                    irq_enabled;
@@ -246,11 +246,11 @@ twl4030_usb_clear_bits(struct twl4030_usb *twl, u8 reg, u8 bits)
 
 /*-------------------------------------------------------------------------*/
 
-static enum usb_phy_events twl4030_usb_linkstat(struct twl4030_usb *twl)
+static enum omap_musb_vbus_id_status
+       twl4030_usb_linkstat(struct twl4030_usb *twl)
 {
        int     status;
-       int     linkstat = USB_EVENT_NONE;
-       struct usb_otg *otg = twl->phy.otg;
+       enum omap_musb_vbus_id_status linkstat = OMAP_MUSB_UNKNOWN;
 
        twl->vbus_supplied = false;
 
@@ -273,30 +273,23 @@ static enum usb_phy_events twl4030_usb_linkstat(struct twl4030_usb *twl)
                         twl->vbus_supplied = true;
 
                if (status & BIT(2))
-                       linkstat = USB_EVENT_ID;
+                       linkstat = OMAP_MUSB_ID_GROUND;
                else
-                       linkstat = USB_EVENT_VBUS;
-       } else
-               linkstat = USB_EVENT_NONE;
+                       linkstat = OMAP_MUSB_VBUS_VALID;
+       } else {
+               if (twl->linkstat != OMAP_MUSB_UNKNOWN)
+                       linkstat = OMAP_MUSB_VBUS_OFF;
+       }
 
        dev_dbg(twl->dev, "HW_CONDITIONS 0x%02x/%d; link %d\n",
                        status, status, linkstat);
 
-       twl->phy.last_event = linkstat;
-
        /* REVISIT this assumes host and peripheral controllers
         * are registered, and that both are active...
         */
 
        spin_lock_irq(&twl->lock);
        twl->linkstat = linkstat;
-       if (linkstat == USB_EVENT_ID) {
-               otg->default_a = true;
-               twl->phy.state = OTG_STATE_A_IDLE;
-       } else {
-               otg->default_a = false;
-               twl->phy.state = OTG_STATE_B_IDLE;
-       }
        spin_unlock_irq(&twl->lock);
 
        return linkstat;
@@ -501,10 +494,10 @@ static DEVICE_ATTR(vbus, 0444, twl4030_usb_vbus_show, NULL);
 static irqreturn_t twl4030_usb_irq(int irq, void *_twl)
 {
        struct twl4030_usb *twl = _twl;
-       int status;
+       enum omap_musb_vbus_id_status status;
 
        status = twl4030_usb_linkstat(twl);
-       if (status >= 0) {
+       if (status > 0) {
                /* FIXME add a set_power() method so that B-devices can
                 * configure the charger appropriately.  It's not always
                 * correct to consume VBUS power, and how much current to
@@ -516,13 +509,13 @@ static irqreturn_t twl4030_usb_irq(int irq, void *_twl)
                 * USB_LINK_VBUS state.  musb_hdrc won't care until it
                 * starts to handle softconnect right.
                 */
-               if (status == USB_EVENT_NONE)
+               if (status == OMAP_MUSB_VBUS_OFF ||
+                               status == OMAP_MUSB_ID_FLOAT)
                        twl4030_phy_suspend(twl, 0);
                else
                        twl4030_phy_resume(twl);
 
-               atomic_notifier_call_chain(&twl->phy.notifier, status,
-                               twl->phy.otg->gadget);
+               omap_musb_mailbox(twl->linkstat);
        }
        sysfs_notify(&twl->dev->kobj, NULL, "vbus");
 
@@ -531,11 +524,12 @@ static irqreturn_t twl4030_usb_irq(int irq, void *_twl)
 
 static void twl4030_usb_phy_init(struct twl4030_usb *twl)
 {
-       int status;
+       enum omap_musb_vbus_id_status status;
 
        status = twl4030_usb_linkstat(twl);
-       if (status >= 0) {
-               if (status == USB_EVENT_NONE) {
+       if (status > 0) {
+               if (status == OMAP_MUSB_VBUS_OFF ||
+                               status == OMAP_MUSB_ID_FLOAT) {
                        __twl4030_phy_power(twl, 0);
                        twl->asleep = 1;
                } else {
@@ -543,8 +537,7 @@ static void twl4030_usb_phy_init(struct twl4030_usb *twl)
                        twl->asleep = 0;
                }
 
-               atomic_notifier_call_chain(&twl->phy.notifier, status,
-                               twl->phy.otg->gadget);
+               omap_musb_mailbox(twl->linkstat);
        }
        sysfs_notify(&twl->dev->kobj, NULL, "vbus");
 }
@@ -598,21 +591,20 @@ static int __devinit twl4030_usb_probe(struct platform_device *pdev)
                return -EINVAL;
        }
 
-       twl = kzalloc(sizeof *twl, GFP_KERNEL);
+       twl = devm_kzalloc(&pdev->dev, sizeof *twl, GFP_KERNEL);
        if (!twl)
                return -ENOMEM;
 
-       otg = kzalloc(sizeof *otg, GFP_KERNEL);
-       if (!otg) {
-               kfree(twl);
+       otg = devm_kzalloc(&pdev->dev, sizeof *otg, GFP_KERNEL);
+       if (!otg)
                return -ENOMEM;
-       }
 
        twl->dev                = &pdev->dev;
        twl->irq                = platform_get_irq(pdev, 0);
        twl->usb_mode           = pdata->usb_mode;
        twl->vbus_supplied      = false;
        twl->asleep             = 1;
+       twl->linkstat           = OMAP_MUSB_UNKNOWN;
 
        twl->phy.dev            = twl->dev;
        twl->phy.label          = "twl4030";
@@ -629,18 +621,14 @@ static int __devinit twl4030_usb_probe(struct platform_device *pdev)
        err = twl4030_usb_ldo_init(twl);
        if (err) {
                dev_err(&pdev->dev, "ldo init failed\n");
-               kfree(otg);
-               kfree(twl);
                return err;
        }
-       usb_set_transceiver(&twl->phy);
+       usb_add_phy(&twl->phy, USB_PHY_TYPE_USB2);
 
        platform_set_drvdata(pdev, twl);
        if (device_create_file(&pdev->dev, &dev_attr_vbus))
                dev_warn(&pdev->dev, "could not create sysfs file\n");
 
-       ATOMIC_INIT_NOTIFIER_HEAD(&twl->phy.notifier);
-
        /* Our job is to use irqs and status from the power module
         * to keep the transceiver disabled when nothing's connected.
         *
@@ -651,13 +639,11 @@ static int __devinit twl4030_usb_probe(struct platform_device *pdev)
         */
        twl->irq_enabled = true;
        status = request_threaded_irq(twl->irq, NULL, twl4030_usb_irq,
-                       IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
-                       "twl4030_usb", twl);
+                       IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING |
+                       IRQF_ONESHOT, "twl4030_usb", twl);
        if (status < 0) {
                dev_dbg(&pdev->dev, "can't get IRQ %d, err %d\n",
                        twl->irq, status);
-               kfree(otg);
-               kfree(twl);
                return status;
        }
 
@@ -701,9 +687,6 @@ static int __exit twl4030_usb_remove(struct platform_device *pdev)
        regulator_put(twl->usb1v8);
        regulator_put(twl->usb3v1);
 
-       kfree(twl->phy.otg);
-       kfree(twl);
-
        return 0;
 }
 
index 0eabb049b6a94efb7fbb14d16cd42b3c9c0d212d..a3d0c0405ccaf8a898d3394d767a363f5826dc3d 100644 (file)
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <linux/usb/otg.h>
+#include <linux/usb/musb-omap.h>
 #include <linux/i2c/twl.h>
 #include <linux/regulator/consumer.h>
 #include <linux/err.h>
-#include <linux/notifier.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
 
@@ -100,7 +100,7 @@ struct twl6030_usb {
 
        int                     irq1;
        int                     irq2;
-       u8                      linkstat;
+       enum omap_musb_vbus_id_status linkstat;
        u8                      asleep;
        bool                    irq_enabled;
        bool                    vbus_enable;
@@ -147,7 +147,7 @@ static int twl6030_phy_init(struct usb_phy *x)
        dev  = twl->dev;
        pdata = dev->platform_data;
 
-       if (twl->linkstat == USB_EVENT_ID)
+       if (twl->linkstat == OMAP_MUSB_ID_GROUND)
                pdata->phy_power(twl->dev, 1, 1);
        else
                pdata->phy_power(twl->dev, 0, 1);
@@ -235,13 +235,13 @@ static ssize_t twl6030_usb_vbus_show(struct device *dev,
        spin_lock_irqsave(&twl->lock, flags);
 
        switch (twl->linkstat) {
-       case USB_EVENT_VBUS:
+       case OMAP_MUSB_VBUS_VALID:
               ret = snprintf(buf, PAGE_SIZE, "vbus\n");
               break;
-       case USB_EVENT_ID:
+       case OMAP_MUSB_ID_GROUND:
               ret = snprintf(buf, PAGE_SIZE, "id\n");
               break;
-       case USB_EVENT_NONE:
+       case OMAP_MUSB_VBUS_OFF:
               ret = snprintf(buf, PAGE_SIZE, "none\n");
               break;
        default:
@@ -256,8 +256,7 @@ static DEVICE_ATTR(vbus, 0444, twl6030_usb_vbus_show, NULL);
 static irqreturn_t twl6030_usb_irq(int irq, void *_twl)
 {
        struct twl6030_usb *twl = _twl;
-       struct usb_otg *otg = twl->phy.otg;
-       int status;
+       enum omap_musb_vbus_id_status status = OMAP_MUSB_UNKNOWN;
        u8 vbus_state, hw_state;
 
        hw_state = twl6030_readb(twl, TWL6030_MODULE_ID0, STS_HW_CONDITIONS);
@@ -268,22 +267,18 @@ static irqreturn_t twl6030_usb_irq(int irq, void *_twl)
                if (vbus_state & VBUS_DET) {
                        regulator_enable(twl->usb3v3);
                        twl->asleep = 1;
-                       status = USB_EVENT_VBUS;
-                       otg->default_a = false;
-                       twl->phy.state = OTG_STATE_B_IDLE;
+                       status = OMAP_MUSB_VBUS_VALID;
                        twl->linkstat = status;
-                       twl->phy.last_event = status;
-                       atomic_notifier_call_chain(&twl->phy.notifier,
-                                               status, otg->gadget);
+                       omap_musb_mailbox(status);
                } else {
-                       status = USB_EVENT_NONE;
-                       twl->linkstat = status;
-                       twl->phy.last_event = status;
-                       atomic_notifier_call_chain(&twl->phy.notifier,
-                                               status, otg->gadget);
-                       if (twl->asleep) {
-                               regulator_disable(twl->usb3v3);
-                               twl->asleep = 0;
+                       if (twl->linkstat != OMAP_MUSB_UNKNOWN) {
+                               status = OMAP_MUSB_VBUS_OFF;
+                               twl->linkstat = status;
+                               omap_musb_mailbox(status);
+                               if (twl->asleep) {
+                                       regulator_disable(twl->usb3v3);
+                                       twl->asleep = 0;
+                               }
                        }
                }
        }
@@ -295,8 +290,7 @@ static irqreturn_t twl6030_usb_irq(int irq, void *_twl)
 static irqreturn_t twl6030_usbotg_irq(int irq, void *_twl)
 {
        struct twl6030_usb *twl = _twl;
-       struct usb_otg *otg = twl->phy.otg;
-       int status = USB_EVENT_NONE;
+       enum omap_musb_vbus_id_status status = OMAP_MUSB_UNKNOWN;
        u8 hw_state;
 
        hw_state = twl6030_readb(twl, TWL6030_MODULE_ID0, STS_HW_CONDITIONS);
@@ -307,13 +301,11 @@ static irqreturn_t twl6030_usbotg_irq(int irq, void *_twl)
                twl->asleep = 1;
                twl6030_writeb(twl, TWL_MODULE_USB, 0x1, USB_ID_INT_EN_HI_CLR);
                twl6030_writeb(twl, TWL_MODULE_USB, 0x10, USB_ID_INT_EN_HI_SET);
-               status = USB_EVENT_ID;
+               status = OMAP_MUSB_ID_GROUND;
                otg->default_a = true;
                twl->phy.state = OTG_STATE_A_IDLE;
                twl->linkstat = status;
-               twl->phy.last_event = status;
-               atomic_notifier_call_chain(&twl->phy.notifier, status,
-                                                       otg->gadget);
+               omap_musb_mailbox(status);
        } else  {
                twl6030_writeb(twl, TWL_MODULE_USB, 0x10, USB_ID_INT_EN_HI_CLR);
                twl6030_writeb(twl, TWL_MODULE_USB, 0x1, USB_ID_INT_EN_HI_SET);
@@ -402,20 +394,19 @@ static int __devinit twl6030_usb_probe(struct platform_device *pdev)
        struct device *dev = &pdev->dev;
        pdata = dev->platform_data;
 
-       twl = kzalloc(sizeof *twl, GFP_KERNEL);
+       twl = devm_kzalloc(dev, sizeof *twl, GFP_KERNEL);
        if (!twl)
                return -ENOMEM;
 
-       otg = kzalloc(sizeof *otg, GFP_KERNEL);
-       if (!otg) {
-               kfree(twl);
+       otg = devm_kzalloc(dev, sizeof *otg, GFP_KERNEL);
+       if (!otg)
                return -ENOMEM;
-       }
 
        twl->dev                = &pdev->dev;
        twl->irq1               = platform_get_irq(pdev, 0);
        twl->irq2               = platform_get_irq(pdev, 1);
        twl->features           = pdata->features;
+       twl->linkstat           = OMAP_MUSB_UNKNOWN;
 
        twl->phy.dev            = twl->dev;
        twl->phy.label          = "twl6030";
@@ -436,18 +427,14 @@ static int __devinit twl6030_usb_probe(struct platform_device *pdev)
        err = twl6030_usb_ldo_init(twl);
        if (err) {
                dev_err(&pdev->dev, "ldo init failed\n");
-               kfree(otg);
-               kfree(twl);
                return err;
        }
-       usb_set_transceiver(&twl->phy);
+       usb_add_phy(&twl->phy, USB_PHY_TYPE_USB2);
 
        platform_set_drvdata(pdev, twl);
        if (device_create_file(&pdev->dev, &dev_attr_vbus))
                dev_warn(&pdev->dev, "could not create sysfs file\n");
 
-       ATOMIC_INIT_NOTIFIER_HEAD(&twl->phy.notifier);
-
        INIT_WORK(&twl->set_vbus_work, otg_set_vbus_work);
 
        twl->irq_enabled = true;
@@ -458,8 +445,6 @@ static int __devinit twl6030_usb_probe(struct platform_device *pdev)
                dev_err(&pdev->dev, "can't get IRQ %d, err %d\n",
                        twl->irq1, status);
                device_remove_file(twl->dev, &dev_attr_vbus);
-               kfree(otg);
-               kfree(twl);
                return status;
        }
 
@@ -471,8 +456,6 @@ static int __devinit twl6030_usb_probe(struct platform_device *pdev)
                        twl->irq2, status);
                free_irq(twl->irq1, twl);
                device_remove_file(twl->dev, &dev_attr_vbus);
-               kfree(otg);
-               kfree(twl);
                return status;
        }
 
@@ -503,8 +486,6 @@ static int __exit twl6030_usb_remove(struct platform_device *pdev)
        pdata->phy_exit(twl->dev);
        device_remove_file(twl->dev, &dev_attr_vbus);
        cancel_work_sync(&twl->set_vbus_work);
-       kfree(twl->phy.otg);
-       kfree(twl);
 
        return 0;
 }
diff --git a/include/linux/usb/musb-omap.h b/include/linux/usb/musb-omap.h
new file mode 100644 (file)
index 0000000..7774c59
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2011-2012 by Texas Instruments
+ *
+ * The Inventra Controller Driver for Linux is free software; you
+ * can redistribute it and/or modify it under the terms of the GNU
+ * General Public License version 2 as published by the Free Software
+ * Foundation.
+ */
+
+#ifndef __MUSB_OMAP_H__
+#define __MUSB_OMAP_H__
+
+enum omap_musb_vbus_id_status {
+       OMAP_MUSB_UNKNOWN = 0,
+       OMAP_MUSB_ID_GROUND,
+       OMAP_MUSB_ID_FLOAT,
+       OMAP_MUSB_VBUS_VALID,
+       OMAP_MUSB_VBUS_OFF,
+};
+
+#if (defined(CONFIG_USB_MUSB_OMAP2PLUS) || \
+                               defined(CONFIG_USB_MUSB_OMAP2PLUS_MODULE))
+void omap_musb_mailbox(enum omap_musb_vbus_id_status status);
+#else
+static inline void omap_musb_mailbox(enum omap_musb_vbus_id_status status)
+{
+}
+#endif
+
+#endif /* __MUSB_OMAP_H__ */
index 38ab3f46346ff4852eabc4e0bbfc3fc2d5e2e793..0cb2ec2e50c0129d9d42260fc7f3da0e67879529 100644 (file)
@@ -43,6 +43,13 @@ enum usb_phy_events {
        USB_EVENT_ENUMERATED,   /* gadget driver enumerated */
 };
 
+/* associate a type with PHY */
+enum usb_phy_type {
+       USB_PHY_TYPE_UNDEFINED,
+       USB_PHY_TYPE_USB2,
+       USB_PHY_TYPE_USB3,
+};
+
 struct usb_phy;
 
 /* for transceivers connected thru an ULPI interface, the user must
@@ -89,6 +96,7 @@ struct usb_phy {
        const char              *label;
        unsigned int             flags;
 
+       enum usb_phy_type       type;
        enum usb_otg_state      state;
        enum usb_phy_events     last_event;
 
@@ -105,6 +113,9 @@ struct usb_phy {
        u16                     port_status;
        u16                     port_change;
 
+       /* to support controllers that have multiple transceivers */
+       struct list_head        head;
+
        /* initialize/shutdown the OTG controller */
        int     (*init)(struct usb_phy *x);
        void    (*shutdown)(struct usb_phy *x);
@@ -121,7 +132,8 @@ struct usb_phy {
 
 
 /* for board-specific init logic */
-extern int usb_set_transceiver(struct usb_phy *);
+extern int usb_add_phy(struct usb_phy *, enum usb_phy_type type);
+extern void usb_remove_phy(struct usb_phy *);
 
 #if defined(CONFIG_NOP_USB_XCEIV) || (defined(CONFIG_NOP_USB_XCEIV_MODULE) && defined(MODULE))
 /* sometimes transceivers are accessed only through e.g. ULPI */
@@ -172,16 +184,29 @@ usb_phy_shutdown(struct usb_phy *x)
 
 /* for usb host and peripheral controller drivers */
 #ifdef CONFIG_USB_OTG_UTILS
-extern struct usb_phy *usb_get_transceiver(void);
-extern void usb_put_transceiver(struct usb_phy *);
+extern struct usb_phy *usb_get_phy(enum usb_phy_type type);
+extern struct usb_phy *devm_usb_get_phy(struct device *dev,
+       enum usb_phy_type type);
+extern void usb_put_phy(struct usb_phy *);
+extern void devm_usb_put_phy(struct device *dev, struct usb_phy *x);
 extern const char *otg_state_string(enum usb_otg_state state);
 #else
-static inline struct usb_phy *usb_get_transceiver(void)
+static inline struct usb_phy *usb_get_phy(enum usb_phy_type type)
+{
+       return NULL;
+}
+
+static inline struct usb_phy *devm_usb_get_phy(struct device *dev,
+       enum usb_phy_type type)
 {
        return NULL;
 }
 
-static inline void usb_put_transceiver(struct usb_phy *x)
+static inline void usb_put_phy(struct usb_phy *x)
+{
+}
+
+static inline void devm_usb_put_phy(struct device *dev, struct usb_phy *x)
 {
 }
 
@@ -276,4 +301,15 @@ usb_unregister_notifier(struct usb_phy *x, struct notifier_block *nb)
 /* for OTG controller drivers (and maybe other stuff) */
 extern int usb_bus_start_enum(struct usb_bus *bus, unsigned port_num);
 
+static inline const char *usb_phy_type_string(enum usb_phy_type type)
+{
+       switch (type) {
+       case USB_PHY_TYPE_USB2:
+               return "USB2 PHY";
+       case USB_PHY_TYPE_USB3:
+               return "USB3 PHY";
+       default:
+               return "UNKNOWN PHY TYPE";
+       }
+}
 #endif /* __LINUX_USB_OTG_H */