From: Minas Harutyunyan <[email protected]>

commit 207324a321a866401b098cadf19e4a2dd6584622 upstream.

During dwc2 driver probe, after gadget registration to the udc class
driver, if exist any builtin function driver it immediately bound to
dwc2 and after init host side (dwc2_hcd_init()) stucked in host mode.
Patch postpone gadget registration after host side initialization done.

Fixes: 117777b2c3bb9 ("usb: dwc2: Move gadget probe function into platform 
code")
Reported-by: kbuild test robot <[email protected]>
Tested-by: Marek Vasut <[email protected]>
Cc: stable <[email protected]>
Signed-off-by: Minas Harutyunyan <[email protected]>
Link: 
https://lore.kernel.org/r/f21cb38fecc72a230b86155d94c7e60c9cb66f58.1591690938.git.hmi...@synopsys.com
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
 drivers/usb/dwc2/gadget.c   |  6 ------
 drivers/usb/dwc2/platform.c | 11 +++++++++++
 2 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c
index 12b98b4662872..7faf5f8c056d4 100644
--- a/drivers/usb/dwc2/gadget.c
+++ b/drivers/usb/dwc2/gadget.c
@@ -4920,12 +4920,6 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg)
                                          epnum, 0);
        }
 
-       ret = usb_add_gadget_udc(dev, &hsotg->gadget);
-       if (ret) {
-               dwc2_hsotg_ep_free_request(&hsotg->eps_out[0]->ep,
-                                          hsotg->ctrl_req);
-               return ret;
-       }
        dwc2_hsotg_dump(hsotg);
 
        return 0;
diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c
index 69972750e1612..5684c4781af9e 100644
--- a/drivers/usb/dwc2/platform.c
+++ b/drivers/usb/dwc2/platform.c
@@ -536,6 +536,17 @@ static int dwc2_driver_probe(struct platform_device *dev)
        if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL)
                dwc2_lowlevel_hw_disable(hsotg);
 
+#if IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL) || \
+       IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE)
+       /* Postponed adding a new gadget to the udc class driver list */
+       if (hsotg->gadget_enabled) {
+               retval = usb_add_gadget_udc(hsotg->dev, &hsotg->gadget);
+               if (retval) {
+                       dwc2_hsotg_remove(hsotg);
+                       goto error_init;
+               }
+       }
+#endif /* CONFIG_USB_DWC2_PERIPHERAL || CONFIG_USB_DWC2_DUAL_ROLE */
        return 0;
 
 error_init:
-- 
2.25.1

Reply via email to