diff options
| -rw-r--r-- | drivers/acpi/processor_idle.c | 30 | ||||
| -rw-r--r-- | drivers/base/power/main.c | 4 | ||||
| -rw-r--r-- | drivers/cpuidle/cpuidle.c | 16 | ||||
| -rw-r--r-- | include/linux/cpuidle.h | 4 | 
4 files changed, 24 insertions, 30 deletions
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 47a8caa89db..d8366ee7571 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -221,10 +221,6 @@ static void lapic_timer_state_broadcast(struct acpi_processor *pr,  #endif -/* - * Suspend / resume control - */ -static int acpi_idle_suspend;  static u32 saved_bm_rld;  static void acpi_idle_bm_rld_save(void) @@ -243,21 +239,13 @@ static void acpi_idle_bm_rld_restore(void)  int acpi_processor_suspend(struct acpi_device * device, pm_message_t state)  { -	if (acpi_idle_suspend == 1) -		return 0; -  	acpi_idle_bm_rld_save(); -	acpi_idle_suspend = 1;  	return 0;  }  int acpi_processor_resume(struct acpi_device * device)  { -	if (acpi_idle_suspend == 0) -		return 0; -  	acpi_idle_bm_rld_restore(); -	acpi_idle_suspend = 0;  	return 0;  } @@ -763,11 +751,6 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev,  	local_irq_disable(); -	if (acpi_idle_suspend) { -		local_irq_enable(); -		cpu_relax(); -		return -EBUSY; -	}  	lapic_timer_state_broadcast(pr, cx, 1);  	kt1 = ktime_get_real(); @@ -838,11 +821,6 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,  	local_irq_disable(); -	if (acpi_idle_suspend) { -		local_irq_enable(); -		cpu_relax(); -		return -EBUSY; -	}  	if (cx->entry_method != ACPI_CSTATE_FFH) {  		current_thread_info()->status &= ~TS_POLLING; @@ -928,8 +906,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,  						drv, drv->safe_state_index);  		} else {  			local_irq_disable(); -			if (!acpi_idle_suspend) -				acpi_safe_halt(); +			acpi_safe_halt();  			local_irq_enable();  			return -EBUSY;  		} @@ -937,11 +914,6 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,  	local_irq_disable(); -	if (acpi_idle_suspend) { -		local_irq_enable(); -		cpu_relax(); -		return -EBUSY; -	}  	if (cx->entry_method != ACPI_CSTATE_FFH) {  		current_thread_info()->status &= ~TS_POLLING; diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 9cb845e4933..63048f79de5 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" @@ -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)) { diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index 04e4b7674a4..efa9a2ca30e 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c @@ -201,6 +201,22 @@ void cpuidle_resume_and_unlock(void)  EXPORT_SYMBOL_GPL(cpuidle_resume_and_unlock); +/* Currently used in suspend/resume path to suspend cpuidle */ +void cpuidle_pause(void) +{ +	mutex_lock(&cpuidle_lock); +	cpuidle_uninstall_idle_handler(); +	mutex_unlock(&cpuidle_lock); +} + +/* Currently used in suspend/resume path to resume cpuidle */ +void cpuidle_resume(void) +{ +	mutex_lock(&cpuidle_lock); +	cpuidle_install_idle_handler(); +	mutex_unlock(&cpuidle_lock); +} +  /**   * cpuidle_wrap_enter - performs timekeeping and irqen around enter function   * @dev: pointer to a valid cpuidle_device object diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h index 524bb6f3b6c..ca6cdf55eb1 100644 --- a/include/linux/cpuidle.h +++ b/include/linux/cpuidle.h @@ -145,6 +145,8 @@ extern void cpuidle_unregister_device(struct cpuidle_device *dev);  extern void cpuidle_pause_and_lock(void);  extern void cpuidle_resume_and_unlock(void); +extern void cpuidle_pause(void); +extern void cpuidle_resume(void);  extern int cpuidle_enable_device(struct cpuidle_device *dev);  extern void cpuidle_disable_device(struct cpuidle_device *dev);  extern int cpuidle_wrap_enter(struct cpuidle_device *dev, @@ -168,6 +170,8 @@ static inline void cpuidle_unregister_device(struct cpuidle_device *dev) { }  static inline void cpuidle_pause_and_lock(void) { }  static inline void cpuidle_resume_and_unlock(void) { } +static inline void cpuidle_pause(void) { } +static inline void cpuidle_resume(void) { }  static inline int cpuidle_enable_device(struct cpuidle_device *dev)  {return -ENODEV; }  static inline void cpuidle_disable_device(struct cpuidle_device *dev) { }  |