From fc50ca8555d9abc2bfaf5423809810d2cc9cd4e0 Mon Sep 17 00:00:00 2001 From: William Wu Date: Tue, 16 Apr 2024 16:27:47 +0800 Subject: [PATCH] usb: dwc3: drd: Avoid host enter runtime suspend during probe On rockchip platforms, if the dr_mode supports otg, it will allow dwc3 pm runtime and put the dwc3 in runtime suspend synchronously at the end of dwc3 probe. It works well in most scenarios with USB-C or USB-A interface. However, for USB Micro interface with ID pin, if ID pin is pull to low by OTG to Host cable during probe, the drd_work which called from the dwc3_core_init_mode() maybe scheduled before pm_runtime_put_sync_suspend. In this case, the dwc-> current_dr_role is DWC3_GCTL_PRTCAP_HOST when enter runtime suspend. Later in xhci_plat_probe, it try to do pm runtime resume, but it fail to do dwc3_core_init_for_resume() in the dwc3_resume_common() because the condition "!PMSG_IS_AUTO(msg)" is not true for the current_dr_role DWC3_GCTL_PRTCAP_HOST, so it can't initialize the dwc3 core. This patch do dwc3_set_mode after pm_runtime_put_sync_suspend if EXTCON_USB_HOST state is true, it can avoid host enter runtime suspend during probe. With this patch, it can fix otg host mode fail to detect device using a Micro OTG cable at system boot time. Change-Id: I8b71f8c2490988b51a89bad5c880fe3cdeba2bfa Signed-off-by: William Wu --- drivers/usb/dwc3/core.c | 4 ++++ drivers/usb/dwc3/drd.c | 7 +++++++ 2 files changed, 11 insertions(+) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 8c35ca59a99d..631929da4803 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -2075,6 +2075,10 @@ static int dwc3_probe(struct platform_device *pdev) pm_runtime_set_autosuspend_delay(dev, 100); pm_runtime_allow(dev); pm_runtime_put_sync_suspend(dev); + + if (dwc->edev && extcon_get_state(dwc->edev, EXTCON_USB_HOST)) + dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_HOST); + return 0; } diff --git a/drivers/usb/dwc3/drd.c b/drivers/usb/dwc3/drd.c index a96cca41efa4..3bf470032e1f 100644 --- a/drivers/usb/dwc3/drd.c +++ b/drivers/usb/dwc3/drd.c @@ -421,6 +421,13 @@ static void dwc3_drd_update(struct dwc3 *dwc) if (id < 0) id = 0; + if ((id > 0) && dwc->dr_mode == USB_DR_MODE_OTG && + (of_device_is_compatible(dwc->dev->parent->of_node, + "rockchip,rk3399-dwc3") || + of_device_is_compatible(dwc->dev->of_node, + "rockchip,rk3576-dwc3"))) + return; + #if defined(CONFIG_ARCH_ROCKCHIP) && defined(CONFIG_NO_GKI) if (extcon_get_state(dwc->edev, EXTCON_USB)) dwc->desired_role_sw_mode = USB_DR_MODE_PERIPHERAL;