|
@@ -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
|
|
|
|
- * 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)
|
|
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)
|
|
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,19 +230,18 @@ 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
|
|
|
|
- * functions should always return with IRQs
|
|
|
|
- * enabled.
|
|
|
|
|
|
+ * pm_idle functions must always
|
|
|
|
+ * return with IRQs 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();
|