@@ -599,27 +599,34 @@ static bool is_async(struct device *dev)
599599
600600static bool dpm_async_fn (struct device * dev , async_func_t func )
601601{
602- reinit_completion (& dev -> power .completion );
602+ if (!is_async (dev ))
603+ return false;
603604
604- if (is_async (dev )) {
605- dev -> power .work_in_progress = true;
605+ dev -> power .work_in_progress = true;
606606
607- get_device (dev );
607+ get_device (dev );
608608
609- if (async_schedule_dev_nocall (func , dev ))
610- return true;
609+ if (async_schedule_dev_nocall (func , dev ))
610+ return true;
611+
612+ put_device (dev );
611613
612- put_device (dev );
613- }
614614 /*
615- * Because async_schedule_dev_nocall() above has returned false or it
616- * has not been called at all, func() is not running and it is safe to
617- * update the work_in_progress flag without extra synchronization.
615+ * async_schedule_dev_nocall() above has returned false, so func() is
616+ * not running and it is safe to update power.work_in_progress without
617+ * extra synchronization.
618618 */
619619 dev -> power .work_in_progress = false;
620+
620621 return false;
621622}
622623
624+ static void dpm_clear_async_state (struct device * dev )
625+ {
626+ reinit_completion (& dev -> power .completion );
627+ dev -> power .work_in_progress = false;
628+ }
629+
623630/**
624631 * device_resume_noirq - Execute a "noirq resume" callback for given device.
625632 * @dev: Device to handle.
@@ -729,8 +736,10 @@ static void dpm_noirq_resume_devices(pm_message_t state)
729736 * Trigger the resume of "async" devices upfront so they don't have to
730737 * wait for the "non-async" ones they don't depend on.
731738 */
732- list_for_each_entry (dev , & dpm_noirq_list , power .entry )
739+ list_for_each_entry (dev , & dpm_noirq_list , power .entry ) {
740+ dpm_clear_async_state (dev );
733741 dpm_async_fn (dev , async_resume_noirq );
742+ }
734743
735744 while (!list_empty (& dpm_noirq_list )) {
736745 dev = to_device (dpm_noirq_list .next );
@@ -869,8 +878,10 @@ void dpm_resume_early(pm_message_t state)
869878 * Trigger the resume of "async" devices upfront so they don't have to
870879 * wait for the "non-async" ones they don't depend on.
871880 */
872- list_for_each_entry (dev , & dpm_late_early_list , power .entry )
881+ list_for_each_entry (dev , & dpm_late_early_list , power .entry ) {
882+ dpm_clear_async_state (dev );
873883 dpm_async_fn (dev , async_resume_early );
884+ }
874885
875886 while (!list_empty (& dpm_late_early_list )) {
876887 dev = to_device (dpm_late_early_list .next );
@@ -1042,8 +1053,10 @@ void dpm_resume(pm_message_t state)
10421053 * Trigger the resume of "async" devices upfront so they don't have to
10431054 * wait for the "non-async" ones they don't depend on.
10441055 */
1045- list_for_each_entry (dev , & dpm_suspended_list , power .entry )
1056+ list_for_each_entry (dev , & dpm_suspended_list , power .entry ) {
1057+ dpm_clear_async_state (dev );
10461058 dpm_async_fn (dev , async_resume );
1059+ }
10471060
10481061 while (!list_empty (& dpm_suspended_list )) {
10491062 dev = to_device (dpm_suspended_list .next );
@@ -1320,6 +1333,7 @@ static int dpm_noirq_suspend_devices(pm_message_t state)
13201333
13211334 list_move (& dev -> power .entry , & dpm_noirq_list );
13221335
1336+ dpm_clear_async_state (dev );
13231337 if (dpm_async_fn (dev , async_suspend_noirq ))
13241338 continue ;
13251339
@@ -1497,6 +1511,7 @@ int dpm_suspend_late(pm_message_t state)
14971511
14981512 list_move (& dev -> power .entry , & dpm_late_early_list );
14991513
1514+ dpm_clear_async_state (dev );
15001515 if (dpm_async_fn (dev , async_suspend_late ))
15011516 continue ;
15021517
@@ -1764,6 +1779,7 @@ int dpm_suspend(pm_message_t state)
17641779
17651780 list_move (& dev -> power .entry , & dpm_suspended_list );
17661781
1782+ dpm_clear_async_state (dev );
17671783 if (dpm_async_fn (dev , async_suspend ))
17681784 continue ;
17691785
0 commit comments