Skip to content

Commit 96db0f9

Browse files
committed
PM: sleep: Move devices to new lists earlier in each suspend phase
During a system-wide suspend of devices, dpm_noirq_suspend_devices(), dpm_suspend_late() and dpm_suspend() move devices from one list to another. They do it with each device after its PM callback in the given suspend phase has run or has been scheduled for asynchronous execution, in case it is deleted from the current list in the meantime. However, devices can be moved to a new list before invoking their PM callbacks (which usually is the case for the devices whose callbacks are executed asynchronously anyway), because doing so does not affect the ordering of that list. In either case, each device is moved to the new list after the previous device has been moved to it or gone away, and if a device is removed, it does not matter which list it is in at that point, because deleting an entry from a list does not change the ordering of the other entries in it. Accordingly, modify the functions mentioned above to move devices to new lists without waiting for their PM callbacks to run regardless of whether or not they run asynchronously. No intentional functional impact. Signed-off-by: Rafael J. Wysocki <[email protected]> Reviewed-by: Stanislaw Gruszka <[email protected]> Reviewed-by: Ulf Hansson <[email protected]>
1 parent a4b64b8 commit 96db0f9

File tree

1 file changed

+3
-21
lines changed

1 file changed

+3
-21
lines changed

drivers/base/power/main.c

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1304,18 +1304,12 @@ static int dpm_noirq_suspend_devices(pm_message_t state)
13041304
while (!list_empty(&dpm_late_early_list)) {
13051305
struct device *dev = to_device(dpm_late_early_list.prev);
13061306

1307+
list_move(&dev->power.entry, &dpm_noirq_list);
13071308
get_device(dev);
13081309
mutex_unlock(&dpm_list_mtx);
13091310

13101311
error = device_suspend_noirq(dev);
13111312

1312-
mutex_lock(&dpm_list_mtx);
1313-
1314-
if (!error && !list_empty(&dev->power.entry))
1315-
list_move(&dev->power.entry, &dpm_noirq_list);
1316-
1317-
mutex_unlock(&dpm_list_mtx);
1318-
13191313
put_device(dev);
13201314

13211315
mutex_lock(&dpm_list_mtx);
@@ -1486,19 +1480,13 @@ int dpm_suspend_late(pm_message_t state)
14861480
while (!list_empty(&dpm_suspended_list)) {
14871481
struct device *dev = to_device(dpm_suspended_list.prev);
14881482

1483+
list_move(&dev->power.entry, &dpm_late_early_list);
14891484
get_device(dev);
14901485

14911486
mutex_unlock(&dpm_list_mtx);
14921487

14931488
error = device_suspend_late(dev);
14941489

1495-
mutex_lock(&dpm_list_mtx);
1496-
1497-
if (!list_empty(&dev->power.entry))
1498-
list_move(&dev->power.entry, &dpm_late_early_list);
1499-
1500-
mutex_unlock(&dpm_list_mtx);
1501-
15021490
put_device(dev);
15031491

15041492
mutex_lock(&dpm_list_mtx);
@@ -1763,19 +1751,13 @@ int dpm_suspend(pm_message_t state)
17631751
while (!list_empty(&dpm_prepared_list)) {
17641752
struct device *dev = to_device(dpm_prepared_list.prev);
17651753

1754+
list_move(&dev->power.entry, &dpm_suspended_list);
17661755
get_device(dev);
17671756

17681757
mutex_unlock(&dpm_list_mtx);
17691758

17701759
error = device_suspend(dev);
17711760

1772-
mutex_lock(&dpm_list_mtx);
1773-
1774-
if (!error && !list_empty(&dev->power.entry))
1775-
list_move(&dev->power.entry, &dpm_suspended_list);
1776-
1777-
mutex_unlock(&dpm_list_mtx);
1778-
17791761
put_device(dev);
17801762

17811763
mutex_lock(&dpm_list_mtx);

0 commit comments

Comments
 (0)