From 51216a597d33164e495993f7e2f65b63b745aa64 Mon Sep 17 00:00:00 2001 From: William Wu Date: Fri, 5 Mar 2021 09:38:50 +0800 Subject: [PATCH] usb: dwc3: core: init current_dr_role in async probe During dwc3 probe, it init the current_dr_role in drd_work, and it must make sure that the current_dr_role is initialized to DWC3_GCTL_PRTCAP_DEVICE or DWC3_GCTL_PRTCAP_HOST if it support dule role mode before do async probe. However, the drd_work and dwc3_rockchip_async_probe are handled asynchronously, if the drd_work is handled prior to async probe, it may fail to call dwc3_core_exit from dwc3_runtime_suspend in async probe because of uninitialized current_dr_role. If this case happens, the USB 2.0/3.0 PHY power on/off operations are unbalanced. This patch get the extcon state before do runtime suspend in async probe, and init the current_dr_role according to the extcon state. Signed-off-by: William Wu Change-Id: I4d1f7683d3ef3c5580f35be52d28821c47f6457f --- drivers/usb/dwc3/core.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index db379f936e7d..d4f2caac39d8 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -1538,6 +1538,15 @@ static void dwc3_rockchip_async_probe(void *data, async_cookie_t cookie) { struct dwc3 *dwc = data; struct device *dev = dwc->dev; + int id; + + if (dwc->edev && !dwc->drd_connected) { + id = extcon_get_state(dwc->edev, EXTCON_USB_HOST); + if (id < 0) + id = 0; + dwc->current_dr_role = id ? DWC3_GCTL_PRTCAP_HOST : + DWC3_GCTL_PRTCAP_DEVICE; + } pm_runtime_put_sync_suspend(dev); }