ARM: tegra: Handle timers during LP2 idle ticks
authorTodd Poynor <toddpoynor@google.com>
Mon, 7 Feb 2011 21:42:34 +0000 (13:42 -0800)
committerTodd Poynor <toddpoynor@google.com>
Wed, 9 Feb 2011 02:50:26 +0000 (18:50 -0800)
Timer ticks aren't properly serviced while a CPU is in LP2 idle.
Although the Tegra LP2 idle code calls hrtimer_peek_ahead_timers,
because no IRQ regs have been saved, update_process_times is not
called, and thus the timer list is not serviced (and neither is
SMP rebalancing, etc.)  This can cause significant delays
scheduling timer-based activity, especially on CPU 1 (which is
not servicing most other IRQs).

Colin Cross suggested a patch based on upstream review feedback
that uses clock notifiers to switch to the "broadcast" clock event
source ("timer0" Tegra timer 3) during LP2, which has a real
interrupt handler defined that calls the clock event handler in
IRQ context, allowing timers to be checked.

Change-Id: Ifa3f4ec662f07dc9636e433f278358f75b65d10c
Signed-off-by: Todd Poynor <toddpoynor@google.com>
arch/arm/mach-tegra/cpuidle.c

index a063c34ecf60aa142df1652ecb6b274794fe528e..23cb9acc588cad1e0625bed04a208759d46fbdae 100644 (file)
@@ -445,6 +445,7 @@ static int tegra_idle_enter_lp2(struct cpuidle_device *dev,
                return tegra_idle_enter_lp3(dev, state);
 
        local_irq_disable();
+       clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu);
        local_fiq_disable();
        enter = ktime_get();
 
@@ -463,11 +464,9 @@ static int tegra_idle_enter_lp2(struct cpuidle_device *dev,
        us = ktime_to_us(exit);
 
        local_fiq_enable();
+       clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu);
        local_irq_enable();
 
-       /* cpu clockevents may have been reset by powerdown */
-       hrtimer_peek_ahead_timers();
-
        smp_rmb();
        state->exit_latency = tegra_lp2_exit_latency;
        state->target_residency = tegra_lp2_exit_latency +