diff options
Diffstat (limited to 'drivers/base/power/main.c')
| -rw-r--r-- | drivers/base/power/main.c | 32 | 
1 files changed, 22 insertions, 10 deletions
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index e0fb5b0435a..0113adc310d 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -28,7 +28,7 @@  #include <linux/sched.h>  #include <linux/async.h>  #include <linux/suspend.h> - +#include <linux/cpuidle.h>  #include "../base.h"  #include "power.h" @@ -45,10 +45,10 @@ typedef int (*pm_callback_t)(struct device *);   */  LIST_HEAD(dpm_list); -LIST_HEAD(dpm_prepared_list); -LIST_HEAD(dpm_suspended_list); -LIST_HEAD(dpm_late_early_list); -LIST_HEAD(dpm_noirq_list); +static LIST_HEAD(dpm_prepared_list); +static LIST_HEAD(dpm_suspended_list); +static LIST_HEAD(dpm_late_early_list); +static LIST_HEAD(dpm_noirq_list);  struct suspend_stats suspend_stats;  static DEFINE_MUTEX(dpm_list_mtx); @@ -166,7 +166,7 @@ static ktime_t initcall_debug_start(struct device *dev)  {  	ktime_t calltime = ktime_set(0, 0); -	if (initcall_debug) { +	if (pm_print_times_enabled) {  		pr_info("calling  %s+ @ %i, parent: %s\n",  			dev_name(dev), task_pid_nr(current),  			dev->parent ? dev_name(dev->parent) : "none"); @@ -181,7 +181,7 @@ static void initcall_debug_report(struct device *dev, ktime_t calltime,  {  	ktime_t delta, rettime; -	if (initcall_debug) { +	if (pm_print_times_enabled) {  		rettime = ktime_get();  		delta = ktime_sub(rettime, calltime);  		pr_info("call %s+ returned %d after %Ld usecs\n", dev_name(dev), @@ -467,6 +467,7 @@ static void dpm_resume_noirq(pm_message_t state)  	mutex_unlock(&dpm_list_mtx);  	dpm_show_time(starttime, state, "noirq");  	resume_device_irqs(); +	cpuidle_resume();  }  /** @@ -867,6 +868,7 @@ static int dpm_suspend_noirq(pm_message_t state)  	ktime_t starttime = ktime_get();  	int error = 0; +	cpuidle_pause();  	suspend_device_irqs();  	mutex_lock(&dpm_list_mtx);  	while (!list_empty(&dpm_late_early_list)) { @@ -989,8 +991,16 @@ static int dpm_suspend_late(pm_message_t state)  int dpm_suspend_end(pm_message_t state)  {  	int error = dpm_suspend_late(state); +	if (error) +		return error; + +	error = dpm_suspend_noirq(state); +	if (error) { +		dpm_resume_early(state); +		return error; +	} -	return error ? : dpm_suspend_noirq(state); +	return 0;  }  EXPORT_SYMBOL_GPL(dpm_suspend_end); @@ -1031,7 +1041,7 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)  	dpm_wait_for_children(dev, async);  	if (async_error) -		return 0; +		goto Complete;  	pm_runtime_get_noresume(dev);  	if (pm_runtime_barrier(dev) && device_may_wakeup(dev)) @@ -1040,7 +1050,7 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)  	if (pm_wakeup_pending()) {  		pm_runtime_put_sync(dev);  		async_error = -EBUSY; -		return 0; +		goto Complete;  	}  	device_lock(dev); @@ -1097,6 +1107,8 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)  	}  	device_unlock(dev); + + Complete:  	complete_all(&dev->power.completion);  	if (error) {  |