Skip to content

Commit be82483

Browse files
committed
PM: sleep: core: Clear power.must_resume in noirq suspend error path
If system suspend is aborted in the "noirq" phase (for instance, due to an error returned by one of the device callbacks), power.is_noirq_suspended will not be set for some devices and device_resume_noirq() will return early for them. Consequently, noirq resume callbacks will not run for them at all because the noirq suspend callbacks have not run for them yet. If any of them has power.must_resume set and late suspend has been skipped for it (due to power.smart_suspend), early resume should be skipped for it either, or its state may become inconsistent (for instance, if the early resume assumes that it will always follow noirq resume). Make that happen by clearing power.must_resume in device_resume_noirq() for devices with power.is_noirq_suspended clear that have been left in suspend by device_suspend_late(), which will subsequently cause device_resume_early() to leave the device in suspend and avoid changing its state. Fixes: 0d4b54c ("PM / core: Add LEAVE_SUSPENDED driver flag") Link: https://lore.kernel.org/linux-pm/5d692b81-6f58-4e86-9cb0-ede69a09d799@rowland.harvard.edu/ Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org> Link: https://patch.msgid.link/3381776.aeNJFYEL58@rafael.j.wysocki
1 parent 56a232d commit be82483

File tree

1 file changed

+13
-1
lines changed

1 file changed

+13
-1
lines changed

drivers/base/power/main.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -724,8 +724,20 @@ static void device_resume_noirq(struct device *dev, pm_message_t state, bool asy
724724
if (dev->power.syscore || dev->power.direct_complete)
725725
goto Out;
726726

727-
if (!dev->power.is_noirq_suspended)
727+
if (!dev->power.is_noirq_suspended) {
728+
/*
729+
* This means that system suspend has been aborted in the noirq
730+
* phase before invoking the noirq suspend callback for the
731+
* device, so if device_suspend_late() has left it in suspend,
732+
* device_resume_early() should leave it in suspend either in
733+
* case the early resume of it depends on the noirq resume that
734+
* has not run.
735+
*/
736+
if (dev_pm_skip_suspend(dev))
737+
dev->power.must_resume = false;
738+
728739
goto Out;
740+
}
729741

730742
if (!dpm_wait_for_superior(dev, async))
731743
goto Out;

0 commit comments

Comments
 (0)