[PATCH v1 2/5] PM: sleep: Rearrange dpm_async_fn() and async state clearing

From: Rafael J. Wysocki
Date: Tue Feb 25 2025 - 11:51:08 EST


From: Rafael J. Wysocki <rafael.j.wysocki@xxxxxxxxx>

In preparation for subsequent changes, move the power.completion
reinitialization along with clearing power.work_in_progress into a
separate function called dpm_clear_async_state() and rearrange
dpm_async_fn() to get rid of unnecessary indentation.

No intentional functional impact.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@xxxxxxxxx>
---
drivers/base/power/main.c | 44 ++++++++++++++++++++++++++++++--------------
1 file changed, 30 insertions(+), 14 deletions(-)

--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -599,27 +599,34 @@

static bool dpm_async_fn(struct device *dev, async_func_t func)
{
- reinit_completion(&dev->power.completion);
+ if (!is_async(dev))
+ return false;

- if (is_async(dev)) {
- dev->power.work_in_progress = true;
+ dev->power.work_in_progress = true;

- get_device(dev);
+ get_device(dev);

- if (async_schedule_dev_nocall(func, dev))
- return true;
+ if (async_schedule_dev_nocall(func, dev))
+ return true;
+
+ put_device(dev);

- put_device(dev);
- }
/*
- * Because async_schedule_dev_nocall() above has returned false or it
- * has not been called at all, func() is not running and it is safe to
- * update the work_in_progress flag without extra synchronization.
+ * async_schedule_dev_nocall() above has returned false, so func() is
+ * not running and it is safe to update power.work_in_progress without
+ * extra synchronization.
*/
dev->power.work_in_progress = false;
+
return false;
}

+static void dpm_clear_async_state(struct device *dev)
+{
+ reinit_completion(&dev->power.completion);
+ dev->power.work_in_progress = false;
+}
+
/**
* device_resume_noirq - Execute a "noirq resume" callback for given device.
* @dev: Device to handle.
@@ -729,8 +736,10 @@
* Trigger the resume of "async" devices upfront so they don't have to
* wait for the "non-async" ones they don't depend on.
*/
- list_for_each_entry(dev, &dpm_noirq_list, power.entry)
+ list_for_each_entry(dev, &dpm_noirq_list, power.entry) {
+ dpm_clear_async_state(dev);
dpm_async_fn(dev, async_resume_noirq);
+ }

while (!list_empty(&dpm_noirq_list)) {
dev = to_device(dpm_noirq_list.next);
@@ -869,8 +878,10 @@
* Trigger the resume of "async" devices upfront so they don't have to
* wait for the "non-async" ones they don't depend on.
*/
- list_for_each_entry(dev, &dpm_late_early_list, power.entry)
+ list_for_each_entry(dev, &dpm_late_early_list, power.entry) {
+ dpm_clear_async_state(dev);
dpm_async_fn(dev, async_resume_early);
+ }

while (!list_empty(&dpm_late_early_list)) {
dev = to_device(dpm_late_early_list.next);
@@ -1035,8 +1046,10 @@
* Trigger the resume of "async" devices upfront so they don't have to
* wait for the "non-async" ones they don't depend on.
*/
- list_for_each_entry(dev, &dpm_suspended_list, power.entry)
+ list_for_each_entry(dev, &dpm_suspended_list, power.entry) {
+ dpm_clear_async_state(dev);
dpm_async_fn(dev, async_resume);
+ }

while (!list_empty(&dpm_suspended_list)) {
dev = to_device(dpm_suspended_list.next);
@@ -1314,6 +1327,7 @@

list_move(&dev->power.entry, &dpm_noirq_list);

+ dpm_clear_async_state(dev);
if (dpm_async_fn(dev, async_suspend_noirq))
continue;

@@ -1491,6 +1505,7 @@

list_move(&dev->power.entry, &dpm_late_early_list);

+ dpm_clear_async_state(dev);
if (dpm_async_fn(dev, async_suspend_late))
continue;

@@ -1758,6 +1773,7 @@

list_move(&dev->power.entry, &dpm_suspended_list);

+ dpm_clear_async_state(dev);
if (dpm_async_fn(dev, async_suspend))
continue;