summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/cpuidle.c
diff options
context:
space:
mode:
authorTodd Poynor <toddpoynor@google.com>2011-02-07 13:42:34 -0800
committerDan Willemsen <dwillemsen@nvidia.com>2011-11-30 21:36:57 -0800
commit164357630ed18137e84a8275d31c96e1c7568236 (patch)
treea1e690be4f295b4e39d70120b03cd2a9bbdd38d5 /arch/arm/mach-tegra/cpuidle.c
parent5326cfa6f0200b5bb17ad6276de62fe676d45394 (diff)
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 <toddpoynor@google.com>
Diffstat (limited to 'arch/arm/mach-tegra/cpuidle.c')
-rw-r--r--arch/arm/mach-tegra/cpuidle.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/cpuidle.c b/arch/arm/mach-tegra/cpuidle.c
index 305c073f3e50..4bf6a601791e 100644
--- a/arch/arm/mach-tegra/cpuidle.c
+++ b/arch/arm/mach-tegra/cpuidle.c
@@ -103,6 +103,7 @@ static int tegra_idle_enter_lp2(struct cpuidle_device *dev,
s64 us;
local_irq_disable();
+ clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu);
local_fiq_disable();
enter = ktime_get();
@@ -116,6 +117,7 @@ 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();
smp_rmb();