From: Gregory Herrero <gregory.herr...@intel.com>

If phy driver is present, register hcd handle to it and let it take
care of calling usb_add_hcd. Otherwise, add hcd here.

Moreover, save irq number so that it can be used to call usb_add_hcd.

Signed-off-by: Gregory Herrero <gregory.herr...@intel.com>
---
 drivers/usb/dwc2/hcd.c | 35 ++++++++++++++++++++++++++++++-----
 1 file changed, 30 insertions(+), 5 deletions(-)

diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index a0cd9db..849af7b 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -2845,6 +2845,7 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq,
        u32 hcfg;
        int i, num_channels;
        int retval;
+       bool add_host = true;
 
        if (usb_disabled())
                return -ENODEV;
@@ -3001,14 +3002,30 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq,
        /* Don't support SG list at this point */
        hcd->self.sg_tablesize = 0;
 
+       /* Save irq number */
+       hcd->irq = irq;
+
        /*
         * Finish generic HCD initialization and start the HCD. This function
         * allocates the DMA buffer pool, registers the USB bus, requests the
         * IRQ line, and calls hcd_start method.
+        * If a phy driver is present, let it handle the hcd initialization.
         */
-       retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
-       if (retval < 0)
-               goto error3;
+       if (!IS_ERR_OR_NULL(hsotg->uphy)) {
+               retval = otg_set_host(hsotg->uphy->otg, &hcd->self);
+               if (retval) {
+                       if (retval != -ENOTSUPP)
+                               goto error3;
+               } else {
+                       add_host = false;
+               }
+       }
+
+       if (add_host) {
+               retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
+               if (retval)
+                       goto error3;
+       }
 
        device_wakeup_enable(hcd->self.controller);
 
@@ -3042,7 +3059,8 @@ EXPORT_SYMBOL_GPL(dwc2_hcd_init);
 void dwc2_hcd_remove(struct dwc2_hsotg *hsotg)
 {
        struct usb_hcd *hcd;
-
+       bool remove_host = true;
+       int retval;
        dev_dbg(hsotg->dev, "DWC OTG HCD REMOVE\n");
 
        hcd = dwc2_hsotg_to_hcd(hsotg);
@@ -3054,7 +3072,14 @@ void dwc2_hcd_remove(struct dwc2_hsotg *hsotg)
                return;
        }
 
-       usb_remove_hcd(hcd);
+       if (!IS_ERR_OR_NULL(hsotg->uphy)) {
+               retval = otg_set_host(hsotg->uphy->otg, NULL);
+               if (!retval)
+                       remove_host = false;
+       }
+
+       if (remove_host)
+               usb_remove_hcd(hcd);
        hsotg->priv = NULL;
        dwc2_hcd_release(hsotg);
        usb_put_hcd(hcd);
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to