diff options
| -rw-r--r-- | arch/arm/include/asm/system.h | 1 | ||||
| -rw-r--r-- | arch/arm/kernel/process.c | 23 | 
2 files changed, 16 insertions, 8 deletions
| diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h index e4c96cc6ec0c..424aa458c487 100644 --- a/arch/arm/include/asm/system.h +++ b/arch/arm/include/asm/system.h @@ -110,6 +110,7 @@ extern void cpu_init(void);  void soft_restart(unsigned long);  extern void (*arm_pm_restart)(char str, const char *cmd); +extern void (*arm_pm_idle)(void);  #define UDBG_UNDEFINED	(1 << 0)  #define UDBG_SYSCALL	(1 << 1) diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 971d65c253a9..ba9e7ef92bec 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -181,12 +181,16 @@ void cpu_idle_wait(void)  EXPORT_SYMBOL_GPL(cpu_idle_wait);  /* - * This is our default idle handler.  We need to disable - * interrupts here to ensure we don't miss a wakeup call. + * This is our default idle handler.   */ + +void (*arm_pm_idle)(void); +  static void default_idle(void)  { -	if (!need_resched()) +	if (arm_pm_idle) +		arm_pm_idle(); +	else  		arch_idle();  	local_irq_enable();  } @@ -215,6 +219,10 @@ void cpu_idle(void)  				cpu_die();  #endif +			/* +			 * We need to disable interrupts here +			 * to ensure we don't miss a wakeup call. +			 */  			local_irq_disable();  #ifdef CONFIG_PL310_ERRATA_769419  			wmb(); @@ -222,19 +230,18 @@ void cpu_idle(void)  			if (hlt_counter) {  				local_irq_enable();  				cpu_relax(); -			} else { +			} else if (!need_resched()) {  				stop_critical_timings();  				if (cpuidle_idle_call())  					pm_idle();  				start_critical_timings();  				/* -				 * This will eventually be removed - pm_idle -				 * functions should always return with IRQs -				 * enabled. +				 * pm_idle functions must always +				 * return with IRQs enabled.  				 */  				WARN_ON(irqs_disabled()); +			} else  				local_irq_enable(); -			}  		}  		leds_event(led_idle_end);  		rcu_idle_exit(); | 
