diff options
author | Alex Frid <afrid@nvidia.com> | 2012-01-31 22:48:34 -0800 |
---|---|---|
committer | Rohan Somvanshi <rsomvanshi@nvidia.com> | 2012-02-17 07:14:44 -0800 |
commit | 676518dbd35c737a59205e9611a92e32146d461b (patch) | |
tree | 9f762e0f90bdd1372713f62900e9a91a1435e44e /arch/arm/mach-tegra/timer-t3.c | |
parent | 39af9f4c2c3cf0d9b8026986db5d73b9ad3ffe11 (diff) |
ARM: tegra: power: Add external LP2 wake timers on secondary CPUs
Add an option to use external timer as Tegra3 secondary CPU wake
source from lp2 (power gated) state. This is a follow up to commit
51e6be9ce103fbeb2b73fa2a9d2b6528a6941e81 that disabled wake from
external timer, since its interrupt is registered too late - after
secondary CPU is brought on-line, and already had a chance to enter
lp2. With this commit, secondary CPU is not allowed to enter lp2 in
idle until wake timer is registered (clock-gated lp3 state is entered
instead).
External timer wake up mechanism is enabled on Tegra3 only if option
HAVE_ARM_TWD is not selected. Otherwise, continue to use local CPU
timers as lp2 wake sources.
Change-Id: Ic8c33f55e77174717bfa6525041e1263d3232dd5
Signed-off-by: Alex Frid <afrid@nvidia.com>
Reviewed-on: http://git-master/r/83546
Reviewed-by: Rohan Somvanshi <rsomvanshi@nvidia.com>
Tested-by: Rohan Somvanshi <rsomvanshi@nvidia.com>
Diffstat (limited to 'arch/arm/mach-tegra/timer-t3.c')
-rw-r--r-- | arch/arm/mach-tegra/timer-t3.c | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/arch/arm/mach-tegra/timer-t3.c b/arch/arm/mach-tegra/timer-t3.c index 0f6afc831dd5..15c607dfbea7 100644 --- a/arch/arm/mach-tegra/timer-t3.c +++ b/arch/arm/mach-tegra/timer-t3.c @@ -69,6 +69,7 @@ #define TIMER6_OFFSET (TEGRA_TMR6_BASE-TEGRA_TMR1_BASE) static void __iomem *timer_reg_base = IO_ADDRESS(TEGRA_TMR1_BASE); +static cpumask_t wake_timer_ready; #define timer_writel(value, reg) \ __raw_writel(value, (u32)timer_reg_base + (reg)) @@ -177,8 +178,8 @@ static void tegra3_register_wake_timer(unsigned int cpu) goto fail; } #endif - test_lp2_wake_timer(cpu); + cpumask_set_cpu(cpu, &wake_timer_ready); return; fail: tegra_lp2_in_idle(false); @@ -187,6 +188,7 @@ fail: #if defined(CONFIG_PM_SLEEP) && defined(CONFIG_HOTPLUG_CPU) static void tegra3_unregister_wake_timer(unsigned int cpu) { + cpumask_clear_cpu(cpu, &wake_timer_ready); #ifdef CONFIG_SMP /* Reassign the affinity of the wake IRQ to CPU 0. */ (void)irq_set_affinity(tegra_lp2wake_irq[cpu].irq, cpumask_of(0)); @@ -217,6 +219,11 @@ unsigned long tegra3_lp2_timer_remain(void) return timer_readl(lp2_wake_timers[cpu] + TIMER_PCR) & 0x1ffffffful; } + +int tegra3_is_lp2_timer_ready(unsigned int cpu) +{ + return cpumask_test_cpu(cpu, &wake_timer_ready); +} #endif void __init tegra3_init_timer(u32 *offset, int *irq) |