Re: [PATCH 3/5] usb: dwc3: xilinx: fix system suspend and resume PHY handling
From: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
Date: 2026-08-26 00:13:25
Also in:
linux-usb, lkml
On Mon, Aug 10, 2026, Radhey Shyam Pandey wrote:
System suspend and resume error paths do not handle PHY and clock
resources correctly. Suspend calls phy_exit() without first powering
off the PHY and ignores failures, while resume can leave clocks
enabled if PHY reinitialization fails.
Propagate errors to the PM core and unwind resources to ensure a
consistent state on suspend and resume failures.
Fixes: d6edcdc1ef06 ("usb: dwc3: xilinx: fix usb3 non-wakeup source resume failure")Does this need to be backported to stable? BR, Thinh
quoted hunk ↗ jump to hunk
Signed-off-by: Radhey Shyam Pandey <radhey.shyam.pandey@amd.com> --- drivers/usb/dwc3/dwc3-xilinx.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-)diff --git a/drivers/usb/dwc3/dwc3-xilinx.c b/drivers/usb/dwc3/dwc3-xilinx.c index 4a04d158f872..894f5f5e8b7a 100644 --- a/drivers/usb/dwc3/dwc3-xilinx.c +++ b/drivers/usb/dwc3/dwc3-xilinx.c@@ -403,13 +403,25 @@ static int __maybe_unused dwc3_xlnx_runtime_idle(struct device *dev) static int __maybe_unused dwc3_xlnx_suspend(struct device *dev) { struct dwc3_xlnx *priv_data = dev_get_drvdata(dev); + int ret; - phy_exit(priv_data->usb3_phy); + ret = phy_power_off(priv_data->usb3_phy); + if (ret < 0) + return ret; + + ret = phy_exit(priv_data->usb3_phy); + if (ret < 0) + goto err_phy_power_on; /* Disable the clocks */ clk_bulk_disable(priv_data->num_clocks, priv_data->clks); return 0; + +err_phy_power_on: + phy_power_on(priv_data->usb3_phy); + + return ret; } static int __maybe_unused dwc3_xlnx_resume(struct device *dev)@@ -423,15 +435,20 @@ static int __maybe_unused dwc3_xlnx_resume(struct device *dev) ret = phy_init(priv_data->usb3_phy); if (ret < 0) - return ret; + goto err_clk_disable; ret = phy_power_on(priv_data->usb3_phy); if (ret < 0) { phy_exit(priv_data->usb3_phy); - return ret; + goto err_clk_disable; } return 0; + +err_clk_disable: + clk_bulk_disable(priv_data->num_clocks, priv_data->clks); + + return ret; } static const struct dev_pm_ops dwc3_xlnx_dev_pm_ops = {-- 2.43.0