[RFC PATCH] usb: dwc3: core: resume xHCI child on runtime resume in host mode

Junzhong Pan <[email protected]>
Newsgroups org.kernel.vger.linux-usb,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
USB controller runtime suspend halts the controller on disconnection.
It relies on platforms with custom connection notification to start
the controller again.

The host branch of dwc3_runtime_resume() does nothing currently. There
are two paths that can trigger a runtime resume of the dwc3 core in
host mode:

(a) Wake lands on the xHCI child (DT platforms, e.g. Qualcomm, i.MX8MP)
    A platform wakeup IRQ fires and the glue handler calls
    pm_runtime_resume(&xhci->dev). Runtime PM walks upward, resumes
    the dwc3 parent first, then resumes xHCI. Both wake correctly.

(b) Wake lands on the dwc3 parent (ACPI platforms)
    When an ACPI Notify(ACPI_NOTIFY_DEVICE_WAKE) targets the dwc3
    parent device -- for example via a Generic Event Device on a
    hardware-reduced platform where dwc3 is enumerated as an ACPI
    device without a glue driver -- the ACPI core turns this into
    pm_request_resume(dwc3_dev). Runtime PM does not propagate resume
    downward, so the xHCI child stays suspended. Root hub polling is
    never re-armed, and a device plugged in while suspended is silently
    dropped.

This patch fills in the host branch to cover case (b) by requesting an
async resume of the xHCI child so xhci_resume() can restore the port
state machine and re-arm root hub polling. Async is required to avoid
deadlocking on the parent's own rpm_resume() re-entry.

Signed-off-by: Junzhong Pan <[email protected]>
---
base-commit: d58772d8520c7ef247c4b95c9bd76d3a25da9ff5
 drivers/usb/dwc3/core.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index ceb49f2f8004..bce56765ad90 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -2668,6 +2668,18 @@ int dwc3_runtime_resume(struct dwc3 *dwc)
 		}
 		break;
 	case DWC3_GCTL_PRTCAP_HOST:
+		/*
+		 * Only the xHCI child's resume re-arms root hub polling, which
+		 * is what rediscovers a device plugged in while suspended.
+		 * Runtime PM never resumes children on its own, so request it
+		 * here. This has to be asynchronous: resuming the child
+		 * synchronously would deadlock because rpm_resume() tries to
+		 * resume the parent before the child, and here the parent's
+		 * own callback has not returned yet.
+		 */
+		if (dwc->xhci)
+			pm_request_resume(&dwc->xhci->dev);
+		break;
 	default:
 		/* do nothing */
 		break;
--
2.25.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.