From 8f7445b6e804ecc0b5679c9914171247f096468a Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Mon, 1 Aug 2011 17:25:06 -0400 Subject: [PATCH] --- yaml --- r: 295316 b: refs/heads/master c: 4fa20439a80c008d33f2865b0db94dcb5da467e2 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/arch/arm/include/asm/system.h | 1 + trunk/arch/arm/kernel/process.c | 23 +++++++++++++++-------- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/[refs] b/[refs] index 83fb91235701..4c9955f47973 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 3c0b2cef913c8f92b15a5a1fe7b611836f7f80bf +refs/heads/master: 4fa20439a80c008d33f2865b0db94dcb5da467e2 diff --git a/trunk/arch/arm/include/asm/system.h b/trunk/arch/arm/include/asm/system.h index e4c96cc6ec0c..424aa458c487 100644 --- a/trunk/arch/arm/include/asm/system.h +++ b/trunk/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/trunk/arch/arm/kernel/process.c b/trunk/arch/arm/kernel/process.c index 971d65c253a9..ba9e7ef92bec 100644 --- a/trunk/arch/arm/kernel/process.c +++ b/trunk/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();