drivers/usb/dwc3/core.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
Issue description:
The parent device dwc3_glue has runtime PM enabled and is in the
runtime suspended state. The system enters the deep sleep process
but is interrupted by another task. When resuming dwc3,
console outputs the log 'runtime PM trying to activate child device
xxx.dwc3 but parent is not active'.
However, the child device dwc3 continues to sleep pm_resume, calling
phy_init and phy_power_on, which sets phy->init_count and
phy->power_count to 1. Later when the system meets the conditions
for deep sleep again, it attempts another 'PM: suspend entry (deep)'.
dwc3 driver executes sleep pm_suspend function but dwc3
already in suspended state, skipping the suspend process in
commit 0227cc84c4441 ("usb: dwc3: core: don't do suspend for device mode
if already suspended"), so phy_exit and phy_power_off are not executed,
keeping phy->init_count and phy->power_count at 1.
During the next deep resume, phy_init and phy_power_on will not be called
due to non-zero count, but the count still increments, preventing recovery.
Eventually, this leads to USB device phy cannot be reinitialized.
Log:
[ 130.284870][C5 t2624] PM: suspend entry (deep)
[ 130.391369][C3 t2624] dwc3 51600000.dwc3: dwc3_suspend
[ 130.406326][C3 t2624] alarmtimer.0.auto: PM: dpm_run_callback():
platform_pm_suspend+0x0/0x90 returns -16
[ 130.407873][C3 t2624] alarmtimer.0.auto: PM: failed to suspend: error -16
[ 130.417756][C3 t2624] PM: Some devices failed to suspend, or early wake
event detected
[ 130.438254][C3 t2624] [asr_drm_resume][726]: ==debug==
[ 130.440178][C3 t2624] dwc3 51600000.dwc3: dwc3_resume
[ 130.440950][C3 t2624] dwc3 51600000.dwc3: runtime PM trying to activate
child device 51600000.dwc3 but parent (51600000.usb) is not active
Solution: During the dwc3 suspend process, check the runtime state of dwc3
to ensure it enters the suspend process only when in the runtime active
state. This way, even if the system suspend process is interrupted,
the parent device will remain in the active state when resuming dwc3 from
deep suspend, allowing successful resumption of the dwc3 device.
Signed-off-by: Ryan Zhou <ryanzhou54@gmail.com>
---
drivers/usb/dwc3/core.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 8002c23a5a02..20945cad29a1 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -2439,8 +2439,6 @@ static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg)
switch (dwc->current_dr_role) {
case DWC3_GCTL_PRTCAP_DEVICE:
- if (pm_runtime_suspended(dwc->dev))
- break;
ret = dwc3_gadget_suspend(dwc);
if (ret)
return ret;
@@ -2671,6 +2669,9 @@ int dwc3_pm_suspend(struct dwc3 *dwc)
struct device *dev = dwc->dev;
int ret;
+ if (pm_runtime_suspended(dev))
+ pm_runtime_resume(dev);
+
ret = dwc3_suspend_common(dwc, PMSG_SUSPEND);
if (ret)
return ret;
--
2.25.1
On Tue, Aug 26, 2025 at 8:12 AM Ryan Zhou <ryanzhou54@gmail.com> wrote: > > Issue description: > The parent device dwc3_glue has runtime PM enabled and is in the > runtime suspended state. The system enters the deep sleep process > but is interrupted by another task. When resuming dwc3, > console outputs the log 'runtime PM trying to activate child device > xxx.dwc3 but parent is not active'. > Wouldn't the parent glue dev already resume before resuming the child dwc3? Why would 'runtime PM trying to activate child device xxx.dwc3 but parent is not active' happen in the first place? What is the glue driver that's being used here? Knowing what's being done in the glue driver pm callbacks would help in understanding the issue. Regards, Roy
Hi Roy, Thank you for reviewing my patch. > > Wouldn't the parent glue dev already resume before resuming the child dwc3? > No, in the following case, the parent device will not be reviewed before resuming the child device. Taking the 'imx8mp-dwc3' driver as an example. Step 1.usb disconnect trigger: the child device dwc3 enter runtime suspend state firstly, followed by the parent device imx8mp-dwc3 enters runtime suspend flow:dwc3_runtime_suspend->dwc3_imx8mp_runtime_suspend Step2.system deep trigger:consistent with the runtime suspend flow, child enters pm suspend and followed by parent flow: dwc3_pm_suspend->dwc3_imx8mp_pm_suspend Step3: After dwc3_pm_suspend, and before dwc3_imx8mp_pm_suspend, a task terminated the system suspend process . The system will resume from the checkpoint, and resume devices in the suspended state in the reverse of pm suspend, but excluding the parent device imx8mp-dwc3 since it did not execute the suspend process. > >Why would 'runtime PM trying to activate child device xxx.dwc3 but parent is not active' happen in the first place? > Following the above analysis, dwc3_resume calls pm_runtime_set_active(dev), it checks the parent.power->runtime_status is not RPM_ACTIVE and outputs the error log. > >What is the glue driver that's being used here? Knowing what's being done in the glue driver pm callbacks >would help in understanding the issue. > Refer to the driver 'dwc3-imx8mp.c' please, maybe you could help me find a better solution. Thanks, ryan Roy Luo <royluo@google.com> 于2025年8月27日周三 02:38写道: > > On Tue, Aug 26, 2025 at 8:12 AM Ryan Zhou <ryanzhou54@gmail.com> wrote: > > > > Issue description: > > The parent device dwc3_glue has runtime PM enabled and is in the > > runtime suspended state. The system enters the deep sleep process > > but is interrupted by another task. When resuming dwc3, > > console outputs the log 'runtime PM trying to activate child device > > xxx.dwc3 but parent is not active'. > > > > Wouldn't the parent glue dev already resume before resuming the child dwc3? > Why would 'runtime PM trying to activate child device xxx.dwc3 but parent is > not active' happen in the first place? > What is the glue driver that's being used here? Knowing what's being done in > the glue driver pm callbacks would help in understanding the issue. > > Regards, > Roy
Ryan: You should present your questions to the maintainer of the kernel's Power Management subsystem, Rafael Wysocki (added to the To: list for this email). Alan Stern On Wed, Aug 27, 2025 at 10:09:10PM +0800, ryan zhou wrote: > Hi Roy, > Thank you for reviewing my patch. > > > > Wouldn't the parent glue dev already resume before resuming the child dwc3? > > > No, in the following case, the parent device will not be reviewed > before resuming the child device. > Taking the 'imx8mp-dwc3' driver as an example. > Step 1.usb disconnect trigger: the child device dwc3 enter runtime > suspend state firstly, followed by > the parent device imx8mp-dwc3 enters runtime suspend > flow:dwc3_runtime_suspend->dwc3_imx8mp_runtime_suspend > Step2.system deep trigger:consistent with the runtime suspend flow, > child enters pm suspend and followed > by parent > flow: dwc3_pm_suspend->dwc3_imx8mp_pm_suspend > Step3: After dwc3_pm_suspend, and before dwc3_imx8mp_pm_suspend, a > task terminated the system suspend process > . The system will resume from the checkpoint, and resume devices in > the suspended state in the reverse > of pm suspend, but excluding the parent device imx8mp-dwc3 since it > did not execute the suspend process. > > > > >Why would 'runtime PM trying to activate child device xxx.dwc3 but parent is not active' happen in the first place? > > > Following the above analysis, dwc3_resume calls > pm_runtime_set_active(dev), it checks the > parent.power->runtime_status is not RPM_ACTIVE and outputs the error log. > > > > >What is the glue driver that's being used here? Knowing what's being done in the glue driver pm callbacks > >would help in understanding the issue. > > > Refer to the driver 'dwc3-imx8mp.c' please, maybe you could help me > find a better solution. > > > Thanks, > ryan > > Roy Luo <royluo@google.com> 于2025年8月27日周三 02:38写道: > > > > On Tue, Aug 26, 2025 at 8:12 AM Ryan Zhou <ryanzhou54@gmail.com> wrote: > > > > > > Issue description: > > > The parent device dwc3_glue has runtime PM enabled and is in the > > > runtime suspended state. The system enters the deep sleep process > > > but is interrupted by another task. When resuming dwc3, > > > console outputs the log 'runtime PM trying to activate child device > > > xxx.dwc3 but parent is not active'. > > > > > > > Wouldn't the parent glue dev already resume before resuming the child dwc3? > > Why would 'runtime PM trying to activate child device xxx.dwc3 but parent is > > not active' happen in the first place? > > What is the glue driver that's being used here? Knowing what's being done in > > the glue driver pm callbacks would help in understanding the issue. > > > > Regards, > > Roy >
On Wed, Aug 27, 2025 at 4:52 PM Alan Stern <stern@rowland.harvard.edu> wrote: > > Ryan: > > You should present your questions to the maintainer of the kernel's > Power Management subsystem, Rafael Wysocki (added to the To: list for > this email). Thanks Alan! > On Wed, Aug 27, 2025 at 10:09:10PM +0800, ryan zhou wrote: > > Hi Roy, > > Thank you for reviewing my patch. > > > > > > Wouldn't the parent glue dev already resume before resuming the child dwc3? > > > > > No, in the following case, the parent device will not be reviewed > > before resuming the child device. > > Taking the 'imx8mp-dwc3' driver as an example. > > Step 1.usb disconnect trigger: the child device dwc3 enter runtime > > suspend state firstly, followed by > > the parent device imx8mp-dwc3 enters runtime suspend > > flow:dwc3_runtime_suspend->dwc3_imx8mp_runtime_suspend > > Step2.system deep trigger:consistent with the runtime suspend flow, > > child enters pm suspend and followed > > by parent > > flow: dwc3_pm_suspend->dwc3_imx8mp_pm_suspend > > Step3: After dwc3_pm_suspend, and before dwc3_imx8mp_pm_suspend, a > > task terminated the system suspend process > > . The system will resume from the checkpoint, and resume devices in > > the suspended state in the reverse > > of pm suspend, but excluding the parent device imx8mp-dwc3 since it > > did not execute the suspend process. > > > > > > > >Why would 'runtime PM trying to activate child device xxx.dwc3 but parent is not active' happen in the first place? > > > > > Following the above analysis, dwc3_resume calls I assume that dwc3_pm_resume() is meant here. > > pm_runtime_set_active(dev), it checks the > > parent.power->runtime_status is not RPM_ACTIVE and outputs the error log. And it does so because enabling runtime PM for the child with runtime_status == RPM_ACTIVE does not make sense when the parent has runtime PM enabled and its status is not RPM_ACTIVE. It looks like the runtime PM status of the parent is not as expected, but quite frankly I don't quite follow the logic in dwc3_pm_resume(). Why does it disable runtime PM just for the duration of dwc3_resume_common()? If runtime PM is functional before the pm_runtime_disable() call in dwc3_pm_resume(), the device may as well be resumed by calling pm_runtime_resume() on it without disabling runtime PM. In turn, if runtime PM is not functional at that point, it should not be enabled.
© 2016 - 2025 Red Hat, Inc.