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

From: Faisal Hassan

Date: Sat Oct 10 2026 - 01:33:17 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.

Dependency: this series applies on top of usb-next plus
"usb: dwc3: qcom: Add support to skip phy management by USB core" [2]
from Krishna Kurapati (Acked-by: Thinh Nguyen, not yet applied). Patch 5
sets the skip_phy_init property introduced there and will not build
without it, so that patch needs to be applied first.

Patch overview:

Patch 1: Track whether the wakeup interrupts are armed so enable and
disable stay balanced across runtime and system PM, and
always disarm them on resume. They stay disarmed if the
resume fails.
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: SA8255P broken-suspend handling (reset + PIPE_UTMI_CLK_SEL +
VBUS_VALID fixups on resume). The xhci_reset_on_resume
property is added to struct dwc3_properties and forwarded to
xhci-plat, and the glue driver sets it, together with
needs_full_reinit, through its probe data.
Patch 6: Firmware-managed "power"/"bus" domain voting for SA8255P,
wired into probe/remove/suspend/resume, with the probe
error paths and the system-suspend-after-runtime-suspend
case keeping the votes and reset balanced.
Patch 7: Enable the VBUS override at probe when the default role is
peripheral.

Testing:

Tested on SA8255P Ride:
- Driver probe, unbind and rebind
- Runtime suspend and resume
- System suspend and resume
- Host mode enumeration across system suspend/resume
- 20x system suspend/resume with a host attached to the peripheral
port: UDC returns to configured, no soft reset failures
- 20x driver unbind/bind with the gadget enumerated and on the host
port

Changes in v3:
- Dropped the software node used to pass xhci-reset-on-resume from
dwc3-qcom to the dwc3 core, together with its probe/remove
handling. The flag is now a field in struct dwc3_properties
(xhci_reset_on_resume), set through the glue driver's probe data
and forwarded to xhci-plat by dwc3 host.c. This avoids the software
node lifetime problems that led to the revert of the earlier
approach. The old patch 5 is merged into the broken-suspend patch.
[Thinh]
- Renamed the flag to xhci_reset_on_resume and placed it with the
other quirk bits in struct dwc3. [Thinh]
- Depend on Krishna's skip-phy patch [2]; the property array in dwc3
host.c now has 9 slots (8 properties plus the terminator) to cover
all quirks that can be set together.
- Patch 1: changed approach. Instead of re-enabling the wakeup
interrupts when resume fails, track whether they are armed
(wakeup_irqs_armed) so enable/disable are idempotent, and always
disarm them on resume, not only for host mode with wakeup enabled.
On a failed resume they stay disarmed, since a level-triggered
wakeup line could otherwise keep firing.
- Patch 2: dropped the wakeup value derived from the PM message in
the resume path, as patch 1 now disarms the interrupts
unconditionally.
- Patch 3: interrupts were minItems 1/maxItems 6 and are now
minItems 5 with the names listed in the schema; added dma-coherent;
dropped the free-form descriptions of power-domains,
power-domain-names and resets.
- Patch 5: also set needs_full_reinit so dwc3 core re-initializes the
controller on system resume even in host mode with wakeup enabled;
restore Qscratch (PIPE_UTMI_CLK_SEL, VBUS_VALID) on every system
resume rather than depending on wakeup, only forcing VBUS_VALID
outside host mode, and never on runtime resume; skip
dwc3_pm_prepare() so the resume callback always runs.
- Patch 6: dwc3_qcom_domains_put() no longer returns an error: the
runtime PM usage count is dropped even when put_sync() fails, so
failures are only warned about and cannot unbalance the next vote.
System suspend of a runtime-suspended device now also drops the
"power" vote that runtime suspend keeps, so system resume stays
balanced. Probe error paths now assert the reset again. The
remove path is simplified accordingly.
- Patch 7: new.
- Link to v2: https://lore.kernel.org/all/20260903153827.3463313-1-faisal.hassan@xxxxxxxxxxxxxxxx/

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 the firmware-managed
patch.
- 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.
- 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.
- Link to v1: https://lore.kernel.org/r/20251127-controller_scmi_upstream-v1-0-38bcca513c28@xxxxxxxxxxxxxxxx

[1] v2: https://lore.kernel.org/all/20260903153827.3463313-1-faisal.hassan@xxxxxxxxxxxxxxxx/
[2] https://lore.kernel.org/all/20260914-xhci-skip-phy-init-v1-1-9c46b31a5a39@xxxxxxxxxxxxxxxx/

Faisal Hassan (7):
usb: dwc3: qcom: Keep wakeup IRQ enable/disable balanced 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: qcom: Support broken suspend for SA8255P
usb: dwc3: qcom: Support firmware-managed resource states for power
management
usb: dwc3: qcom: Enable VBUS override at probe for default peripheral
role

.../bindings/usb/qcom,sa8255p-dwc3.yaml | 119 +++++
drivers/usb/dwc3/core.c | 3 +
drivers/usb/dwc3/core.h | 3 +
drivers/usb/dwc3/dwc3-qcom.c | 411 +++++++++++++++---
drivers/usb/dwc3/glue.h | 2 +
drivers/usb/dwc3/host.c | 5 +-
drivers/usb/host/xhci-plat.c | 3 +
7 files changed, 487 insertions(+), 59 deletions(-)
create mode 100644 Documentation/devicetree/bindings/usb/qcom,sa8255p-dwc3.yaml

--
2.34.1