Skip to content

Commit 2b3a645

Browse files
committed
PM: sleep: core: Fix runtime PM enabling in device_resume_early()
JIRA: https://issues.redhat.com/browse/RHEL-109251 commit f384497 Author: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Date: Tue Nov 18 15:16:04 2025 +0100 Runtime PM should only be enabled in device_resume_early() if it has been disabled for the given device by device_suspend_late(). Otherwise, it may cause runtime PM callbacks to run prematurely in some cases which leads to further functional issues. Make two changes to address this problem. First, reorder device_suspend_late() to only disable runtime PM for a device when it is going to look for the device's callback or if the device is a "syscore" one. In all of the other cases, disabling runtime PM for the device is not in fact necessary. However, if the device's callback returns an error and the power.is_late_suspended flag is not going to be set, enable runtime PM so it only remains disabled when power.is_late_suspended is set. Second, make device_resume_early() only enable runtime PM for the devices with the power.is_late_suspended flag set. Fixes: 443046d ("PM: sleep: Make suspend of devices more asynchronous") Reported-by: Rose Wu <ya-jou.wu@mediatek.com> Closes: https://lore.kernel.org/linux-pm/70b25dca6f8c2756d78f076f4a7dee7edaaffc33.camel@mediatek.com/ Cc: 6.16+ <stable@vger.kernel.org> # 6.16+ Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Link: https://patch.msgid.link/12784270.O9o76ZdvQC@rafael.j.wysocki Signed-off-by: Mark Langsdorf <mlangsdo@redhat.com>
1 parent b103eec commit 2b3a645

File tree

1 file changed

+16
-9
lines changed

1 file changed

+16
-9
lines changed

drivers/base/power/main.c

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -878,12 +878,15 @@ static void device_resume_early(struct device *dev, pm_message_t state, bool asy
878878
TRACE_DEVICE(dev);
879879
TRACE_RESUME(0);
880880

881-
if (dev->power.syscore || dev->power.direct_complete)
881+
if (dev->power.direct_complete)
882882
goto Out;
883883

884884
if (!dev->power.is_late_suspended)
885885
goto Out;
886886

887+
if (dev->power.syscore)
888+
goto Skip;
889+
887890
if (!dpm_wait_for_superior(dev, async))
888891
goto Out;
889892

@@ -916,11 +919,11 @@ static void device_resume_early(struct device *dev, pm_message_t state, bool asy
916919

917920
Skip:
918921
dev->power.is_late_suspended = false;
922+
pm_runtime_enable(dev);
919923

920924
Out:
921925
TRACE_RESUME(error);
922926

923-
pm_runtime_enable(dev);
924927
complete_all(&dev->power.completion);
925928

926929
if (error) {
@@ -1604,12 +1607,6 @@ static void device_suspend_late(struct device *dev, pm_message_t state, bool asy
16041607
TRACE_DEVICE(dev);
16051608
TRACE_SUSPEND(0);
16061609

1607-
/*
1608-
* Disable runtime PM for the device without checking if there is a
1609-
* pending resume request for it.
1610-
*/
1611-
__pm_runtime_disable(dev, false);
1612-
16131610
dpm_wait_for_subordinate(dev, async);
16141611

16151612
if (READ_ONCE(async_error))
@@ -1620,9 +1617,18 @@ static void device_suspend_late(struct device *dev, pm_message_t state, bool asy
16201617
goto Complete;
16211618
}
16221619

1623-
if (dev->power.syscore || dev->power.direct_complete)
1620+
if (dev->power.direct_complete)
16241621
goto Complete;
16251622

1623+
/*
1624+
* Disable runtime PM for the device without checking if there is a
1625+
* pending resume request for it.
1626+
*/
1627+
__pm_runtime_disable(dev, false);
1628+
1629+
if (dev->power.syscore)
1630+
goto Skip;
1631+
16261632
if (dev->pm_domain) {
16271633
info = "late power domain ";
16281634
callback = pm_late_early_op(&dev->pm_domain->ops, state);
@@ -1653,6 +1659,7 @@ static void device_suspend_late(struct device *dev, pm_message_t state, bool asy
16531659
WRITE_ONCE(async_error, error);
16541660
dpm_save_failed_dev(dev_name(dev));
16551661
pm_dev_err(dev, state, async ? " async late" : " late", error);
1662+
pm_runtime_enable(dev);
16561663
goto Complete;
16571664
}
16581665
dpm_propagate_wakeup_to_parent(dev);

0 commit comments

Comments
 (0)