From 2a793170d94f8970d504856f3acb06eeb1f99bc8 Mon Sep 17 00:00:00 2001 From: Krishna Kurapati Date: Mon, 14 Sep 2026 20:05:58 +0530 Subject: [PATCH] FROMLIST: usb: dwc3: qcom: Add support to skip phy management by USB core DWC3 driver does manage phys itself sufficiently for Qualcomm platforms. If xhci-skip-phy-init is not set, the HCD core does a phy_init and phy_ exit is done only when roothub is being destroyed. Due to this, during system suspend in host mode, although phy_exit is done by DWC3 core, the init_count on phy is never down to zero since HCD core also did an init. consequently causing phy's exit routine to not be called. Hence, add support to skip phy management by USB core. Some Exynos platforms still do rely on USB core for phy_calibrate calls, hence disable USB core management for Qualcomm platforms only. Signed-off-by: Krishna Kurapati Acked-by: Thinh Nguyen --- drivers/usb/dwc3/core.c | 3 +++ drivers/usb/dwc3/core.h | 1 + drivers/usb/dwc3/dwc3-qcom.c | 1 + drivers/usb/dwc3/glue.h | 2 ++ drivers/usb/dwc3/host.c | 5 ++++- 5 files changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index ceb49f2f80041..01f31113aec77 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -1694,6 +1694,9 @@ static void dwc3_get_software_properties(struct dwc3 *dwc, if (properties->needs_full_reinit) dwc->needs_full_reinit = true; + if (properties->skip_phy_init) + dwc->skip_phy_init = true; + dwc->gsbuscfg0_reqinfo = DWC3_GSBUSCFG0_REQINFO_UNSPECIFIED; if (properties->gsbuscfg0_reqinfo != diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index e0dee9d287401..86c407973241a 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -1415,6 +1415,7 @@ struct dwc3 { unsigned wakeup_configured:1; unsigned suspended:1; unsigned susphy_state:1; + unsigned skip_phy_init:1; u16 imod_interval; diff --git a/drivers/usb/dwc3/dwc3-qcom.c b/drivers/usb/dwc3/dwc3-qcom.c index f43f73ac36ff1..7d4798e635c1d 100644 --- a/drivers/usb/dwc3/dwc3-qcom.c +++ b/drivers/usb/dwc3/dwc3-qcom.c @@ -705,6 +705,7 @@ static int dwc3_qcom_probe(struct platform_device *pdev) probe_data.res = &res; probe_data.ignore_clocks_and_resets = true; probe_data.properties = DWC3_DEFAULT_PROPERTIES; + probe_data.properties.skip_phy_init = true; ret = dwc3_core_probe(&probe_data); if (ret) { ret = dev_err_probe(dev, ret, "failed to register DWC3 Core\n"); diff --git a/drivers/usb/dwc3/glue.h b/drivers/usb/dwc3/glue.h index d738e1739ae01..72c5593e657a9 100644 --- a/drivers/usb/dwc3/glue.h +++ b/drivers/usb/dwc3/glue.h @@ -14,10 +14,12 @@ * @gsbuscfg0_reqinfo: Value to be programmed in the GSBUSCFG0.REQINFO field * @needs_full_reinit: indicate the controller may not remain power during system * pm and need full initialization + * @skip_phy_init: skip xHCI PHY initialization on host init */ struct dwc3_properties { u32 gsbuscfg0_reqinfo; unsigned needs_full_reinit:1; + unsigned skip_phy_init:1; }; #define DWC3_DEFAULT_PROPERTIES ((struct dwc3_properties){ \ diff --git a/drivers/usb/dwc3/host.c b/drivers/usb/dwc3/host.c index 96b588bd08cdc..97bdd09abf271 100644 --- a/drivers/usb/dwc3/host.c +++ b/drivers/usb/dwc3/host.c @@ -129,7 +129,7 @@ static int dwc3_host_get_irq(struct dwc3 *dwc) int dwc3_host_init(struct dwc3 *dwc) { - struct property_entry props[6]; + struct property_entry props[7]; struct platform_device *xhci; int ret, irq; int prop_idx = 0; @@ -173,6 +173,9 @@ int dwc3_host_init(struct dwc3 *dwc) if (dwc->usb2_lpm_disable) props[prop_idx++] = PROPERTY_ENTRY_BOOL("usb2-lpm-disable"); + if (dwc->skip_phy_init) + props[prop_idx++] = PROPERTY_ENTRY_BOOL("xhci-skip-phy-init-quirk"); + /** * WORKAROUND: dwc3 revisions <=3.00a have a limitation * where Port Disable command doesn't work.