[PATCH v2 0/7] usb: dwc3: qcom: Add firmware-managed resource support for SA8255P

From: Faisal Hassan

Date: Thu Sep 03 2026 - 12:26:16 EST


On Qualcomm automotive SoCs such as SA8255P, the USB controller runs in
a Linux VM while the platform resources that the controller depends on
(clocks, interconnects, resets, regulators and the GDSC) are owned and
sequenced by firmware running in a separate VM:

+----------------+ SCMI +------------------+
| Linux VM | <------------------> | Firmware VM |
| | | |
| dwc3-qcom.c | | clocks |
| "power" PD |----------------------->| interconnects |
| "bus" PD |----------------------->| resets |
| | | regulators/GDSC |
+----------------+ +------------------+

Linux has no direct access to these resources; it can only vote for
two abstracted power domains exposed over the SCMI power-domain
protocol:

- "power": gates the power supply (GDSC) to the USB controller
- "bus": gates the clocks and interconnects used for data transfer

Register accesses through the controller require "power" to be voted
on; "bus" additionally requires "power". The vote policy implemented
in this series is:

- Enable order: power, then bus
- Disable order: bus, then power
- Runtime suspend/resume vote only "bus" -- "power" stays on so that
accesses that can legitimately happen while runtime suspended
keep working.
- System suspend/resume vote both domains.

The two domains are attached with PD_FLAG_NO_DEV_LINK because runtime
suspend and system suspend require different supplier states for the
same consumer, which a plain device-link cannot express; the driver
manages the runtime PM references for each attached domain explicitly
instead.

SA8255P also requires a few platform-specific fixups on top of this,
handled by this series:

- "Broken suspend": APPS/system suspend causes the clock controller
to cut all clocks to the controller, putting it into a Power-On
Reset state and losing Qscratch programming. Resume must reset the
controller, reselect the UTMI clock as the PIPE clock when no SS
PHY is present, and reassert VBUS_VALID so the PHYs don't fall
back into suspend.
- The loss of power across system suspend also leaves the xHC in an
error state on resume, which the existing XHCI_RESET_ON_RESUME
quirk handles once dwc3 is taught to request it via a device
property.

Patch overview:

Patch 1: Re-enable wakeup interrupts if dwc3_qcom_resume() fails
partway through, fixing a pre-existing leak on the error
path this series' resume changes build on top of.
Patch 2: Refactor dwc3_qcom_suspend()/dwc3_qcom_resume() to take a
pm_message_t instead of a bool, so the runtime-PM vs
system-PM path can be told apart with PMSG_IS_AUTO(), which
later patches rely on.
Patch 3: New devicetree binding, qcom,sa8255p-dwc3.yaml, requiring
"power"/"bus" power-domains and excluding clocks/
interconnects for firmware-managed platforms.
Patch 4: Teach xhci-plat to set XHCI_RESET_ON_RESUME from a device
property.
Patch 5: Teach dwc3 core to forward an "xhci-reset-on-resume" device
property through to the xhci-plat software node.
Patch 6: SA8255P broken-suspend handling (reset + PIPE_UTMI_CLK_SEL +
VBUS_VALID fixups on resume, xhci-reset-on-resume enabled
via software node).
Patch 7: Firmware-managed "power"/"bus" domain voting for SA8255P,
wired into probe/remove/suspend/resume, plus hardening of
dwc3_qcom_remove() and the probe error-unwind path shared by
all qcom,snps-dwc3 platforms.

Testing:

Tested on SA8255P:
- Driver probe, unbind and rebind
- Runtime suspend and resume
- System suspend and resume
- Host mode enumeration across system suspend/resume

Changes in v2:
- Reworked the resource model from OPP-based performance-state
voting to plain power-domain ON/OFF voting via "power" and "bus"
domains, addressing Bjorn's objection that OPP levels conflate
performance-state selection with power-state signaling. [Bjorn]
- Documented the PD_FLAG_NO_DEV_LINK rationale (asymmetric runtime
suspend vs system suspend supplier state) in patch 7.
- Validate the number of attached domains against what was
requested instead of assuming attach always returns exactly two.
- Fixed an unwind bug where a "bus" domain enable failure during
probe would return without dropping the "power" domain vote.
- Added the new qcom,sa8255p-dwc3.yaml binding (patch 3).
- Terminated the broken-suspend software node's property array and
fixed a bug where the software-property walk in dwc3 core did not
continue past the first match.
- Fixed dwc3_qcom_resume()'s broken-suspend reset to only fire on
system resume, not runtime resume, since runtime suspend now
deliberately keeps "power" voted on and the controller state that
reset was meant to recover was never lost on that path.
- Link to v1: https://lore.kernel.org/r/20251127-controller_scmi_upstream-v1-0-38bcca513c28@xxxxxxxxxxxxxxxx

Faisal Hassan (7):
usb: dwc3: qcom: re-enable wakeup interrupts on failed resume
usb: dwc3: qcom: Distinguish PM and runtime suspend/resume paths
dt-bindings: usb: Add qcom,sa8255p-dwc3 for firmware-managed resources
usb: host: xhci-plat: Support XHCI_RESET_ON_RESUME via device property
usb: dwc3: add xhci-reset-on-resume property for power-loss resume
usb: dwc3: qcom: Support broken suspend for SA8255P
usb: dwc3: qcom: Support firmware-managed resource states for power
management

.../bindings/usb/qcom,sa8255p-dwc3.yaml | 123 +++++
drivers/usb/dwc3/core.c | 4 +
drivers/usb/dwc3/core.h | 5 +
drivers/usb/dwc3/dwc3-qcom.c | 473 +++++++++++++++---
drivers/usb/dwc3/host.c | 5 +-
drivers/usb/host/xhci-plat.c | 3 +
6 files changed, 552 insertions(+), 61 deletions(-)
create mode 100644 Documentation/devicetree/bindings/usb/qcom,sa8255p-dwc3.yaml

--
2.34.1