Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

usb: dwc3: Skip resume if pm_runtime_set_active() fails

When the system begins to enter suspend mode, dwc3_suspend() is called
by PM suspend. There is a problem that if someone interrupt the system
suspend process between dwc3_suspend() and pm_suspend() of its parent
device, PM suspend will be canceled and attempt to resume suspended
devices so that dwc3_resume() will be called. However, dwc3 and its
parent device (like the power domain or glue driver) may already be
suspended by runtime PM in fact. If this sutiation happened, the
pm_runtime_set_active() in dwc3_resume() will return an error since
parent device was suspended. This can lead to unexpected behavior if
DWC3 proceeds to execute dwc3_resume_common().

EX.
RPM suspend: ... -> dwc3_runtime_suspend()
-> rpm_suspend() of parent device
...
PM suspend: ... -> dwc3_suspend() -> pm_suspend of parent device
^ interrupt, so resume suspended device
... <- dwc3_resume() <-/
^ pm_runtime_set_active() returns error

To prevent the problem, this commit will skip dwc3_resume_common() and
return the error if pm_runtime_set_active() fails.

Fixes: 68c26fe58182 ("usb: dwc3: set pm runtime active before resume common")
Cc: stable <stable@kernel.org>
Signed-off-by: Ray Chi <raychi@google.com>
Acked-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
Link: https://lore.kernel.org/r/20250106082240.3822059-1-raychi@google.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Ray Chi and committed by
Greg Kroah-Hartman
e3a9bd24 a181c8ef

+4 -1
+4 -1
drivers/usb/dwc3/core.c
··· 2609 2609 pinctrl_pm_select_default_state(dev); 2610 2610 2611 2611 pm_runtime_disable(dev); 2612 - pm_runtime_set_active(dev); 2612 + ret = pm_runtime_set_active(dev); 2613 + if (ret) 2614 + goto out; 2613 2615 2614 2616 ret = dwc3_resume_common(dwc, PMSG_RESUME); 2615 2617 if (ret) 2616 2618 pm_runtime_set_suspended(dev); 2617 2619 2620 + out: 2618 2621 pm_runtime_enable(dev); 2619 2622 2620 2623 return ret;