提交 4fa20439 编写于 作者: N Nicolas Pitre 提交者: Nicolas Pitre

ARM: clean up idle handlers

Let's factor out the need_resched() check instead of having it duplicated
in every pm_idle implementations to avoid inconsistencies (omap2_pm_idle
is missing it already).

The forceful re-enablement of IRQs after pm_idle has returned can go.
The warning certainly doesn't trigger for existing users.

To get rid of the pm_idle calling convention oddity, let's introduce
arm_pm_idle() allowing for the local_irq_enable() to be factored out
from SOC specific implementations. The default pm_idle function becomes
a wrapper for arm_pm_idle and it takes care of enabling IRQs closer to
where they are initially disabled.

And finally move the comment explaining the reason for that turning off
of IRQs to a more proper location.
Signed-off-by: NNicolas Pitre <nicolas.pitre@linaro.org>
Acked-and-tested-by: NJamie Iles <jamie@jamieiles.com>
上级 3c0b2cef
...@@ -110,6 +110,7 @@ extern void cpu_init(void); ...@@ -110,6 +110,7 @@ extern void cpu_init(void);
void soft_restart(unsigned long); void soft_restart(unsigned long);
extern void (*arm_pm_restart)(char str, const char *cmd); extern void (*arm_pm_restart)(char str, const char *cmd);
extern void (*arm_pm_idle)(void);
#define UDBG_UNDEFINED (1 << 0) #define UDBG_UNDEFINED (1 << 0)
#define UDBG_SYSCALL (1 << 1) #define UDBG_SYSCALL (1 << 1)
......
...@@ -181,12 +181,16 @@ void cpu_idle_wait(void) ...@@ -181,12 +181,16 @@ void cpu_idle_wait(void)
EXPORT_SYMBOL_GPL(cpu_idle_wait); EXPORT_SYMBOL_GPL(cpu_idle_wait);
/* /*
* This is our default idle handler. We need to disable * This is our default idle handler.
* interrupts here to ensure we don't miss a wakeup call.
*/ */
void (*arm_pm_idle)(void);
static void default_idle(void) static void default_idle(void)
{ {
if (!need_resched()) if (arm_pm_idle)
arm_pm_idle();
else
arch_idle(); arch_idle();
local_irq_enable(); local_irq_enable();
} }
...@@ -215,6 +219,10 @@ void cpu_idle(void) ...@@ -215,6 +219,10 @@ void cpu_idle(void)
cpu_die(); cpu_die();
#endif #endif
/*
* We need to disable interrupts here
* to ensure we don't miss a wakeup call.
*/
local_irq_disable(); local_irq_disable();
#ifdef CONFIG_PL310_ERRATA_769419 #ifdef CONFIG_PL310_ERRATA_769419
wmb(); wmb();
...@@ -222,20 +230,19 @@ void cpu_idle(void) ...@@ -222,20 +230,19 @@ void cpu_idle(void)
if (hlt_counter) { if (hlt_counter) {
local_irq_enable(); local_irq_enable();
cpu_relax(); cpu_relax();
} else { } else if (!need_resched()) {
stop_critical_timings(); stop_critical_timings();
if (cpuidle_idle_call()) if (cpuidle_idle_call())
pm_idle(); pm_idle();
start_critical_timings(); start_critical_timings();
/* /*
* This will eventually be removed - pm_idle * pm_idle functions must always
* functions should always return with IRQs * return with IRQs enabled.
* enabled.
*/ */
WARN_ON(irqs_disabled()); WARN_ON(irqs_disabled());
} else
local_irq_enable(); local_irq_enable();
} }
}
leds_event(led_idle_end); leds_event(led_idle_end);
rcu_idle_exit(); rcu_idle_exit();
tick_nohz_idle_exit(); tick_nohz_idle_exit();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册