diff options
Diffstat (limited to 'drivers/base/power/main.c')
| -rw-r--r-- | drivers/base/power/main.c | 24 | 
1 files changed, 23 insertions, 1 deletions
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index eebe699fdf4f..7a50af416cac 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -1237,6 +1237,7 @@ void dpm_complete(pm_message_t state)  void dpm_resume_end(pm_message_t state)  {  	dpm_resume(state); +	pm_restore_gfp_mask();  	dpm_complete(state);  }  EXPORT_SYMBOL_GPL(dpm_resume_end); @@ -1279,6 +1280,22 @@ static void dpm_async_suspend_parent(struct device *dev, async_func_t func)  		dpm_async_with_cleanup(dev->parent, func);  } +static void dpm_async_suspend_complete_all(struct list_head *device_list) +{ +	struct device *dev; + +	guard(mutex)(&async_wip_mtx); + +	list_for_each_entry_reverse(dev, device_list, power.entry) { +		/* +		 * In case the device is being waited for and async processing +		 * has not started for it yet, let the waiters make progress. +		 */ +		if (!dev->power.work_in_progress) +			complete_all(&dev->power.completion); +	} +} +  /**   * resume_event - Return a "resume" message for given "suspend" sleep state.   * @sleep_state: PM message representing a sleep state. @@ -1455,6 +1472,7 @@ static int dpm_noirq_suspend_devices(pm_message_t state)  		mutex_lock(&dpm_list_mtx);  		if (error || async_error) { +			dpm_async_suspend_complete_all(&dpm_late_early_list);  			/*  			 * Move all devices to the target list to resume them  			 * properly. @@ -1657,6 +1675,7 @@ int dpm_suspend_late(pm_message_t state)  		mutex_lock(&dpm_list_mtx);  		if (error || async_error) { +			dpm_async_suspend_complete_all(&dpm_suspended_list);  			/*  			 * Move all devices to the target list to resume them  			 * properly. @@ -1950,6 +1969,7 @@ int dpm_suspend(pm_message_t state)  		mutex_lock(&dpm_list_mtx);  		if (error || async_error) { +			dpm_async_suspend_complete_all(&dpm_prepared_list);  			/*  			 * Move all devices to the target list to resume them  			 * properly. @@ -2176,8 +2196,10 @@ int dpm_suspend_start(pm_message_t state)  	error = dpm_prepare(state);  	if (error)  		dpm_save_failed_step(SUSPEND_PREPARE); -	else +	else { +		pm_restrict_gfp_mask();  		error = dpm_suspend(state); +	}  	dpm_show_time(starttime, state, error, "start");  	return error;  | 
