From 6b825e9aaa011f01e433c57db9f191cb99f30709 Mon Sep 17 00:00:00 2001 From: Todd Poynor Date: Mon, 7 Feb 2011 13:42:34 -0800 Subject: [PATCH] ARM: tegra: Handle timers during LP2 idle ticks 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 --- arch/arm/mach-tegra/cpuidle.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-tegra/cpuidle.c b/arch/arm/mach-tegra/cpuidle.c index a063c34ecf60..23cb9acc588c 100644 --- a/arch/arm/mach-tegra/cpuidle.c +++ b/arch/arm/mach-tegra/cpuidle.c @@ -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 + -- 2.34.1