diff options
author | Dan Willemsen <dwillemsen@nvidia.com> | 2011-07-25 14:34:22 -0700 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2011-11-30 21:46:54 -0800 |
commit | 57110c69e55510ff6157511080f4364bbb88a509 (patch) | |
tree | b36cf5334133f1c91e1707c237ce5ad4280a8751 /arch/arm/mach-tegra/timer-t2.c | |
parent | 51fd52a75de1c106104fb9ea655a9972e386d507 (diff) |
ARM: tegra2: Update LP2 timers
Clean up conditionals for LP2 timers
Register an interrupt handler for the LP2 timer
Change-Id: I6ee6b6971f45f33d5d9295a462778af1d1c9843b
Signed-off-by: Scott Williams <scwilliams@nvidia.com>
DW: Split into logical changes
Signed-off-by: Dan Willemsen <dwillemsen@nvidia.com>
Rebase-Id: R6cec04d1c66dc3af22cb9ab7afe0dffaba891cea
Diffstat (limited to 'arch/arm/mach-tegra/timer-t2.c')
-rw-r--r-- | arch/arm/mach-tegra/timer-t2.c | 63 |
1 files changed, 48 insertions, 15 deletions
diff --git a/arch/arm/mach-tegra/timer-t2.c b/arch/arm/mach-tegra/timer-t2.c index d433133474bc..f91528594371 100644 --- a/arch/arm/mach-tegra/timer-t2.c +++ b/arch/arm/mach-tegra/timer-t2.c @@ -40,6 +40,14 @@ #include "clock.h" #include "timer.h" +/* + * Timers usage: + * TMR1 - Free. + * TMR2 - used by AVP. + * TMR3 - used as general CPU timer. + * TMR4 - used for LP2 wakeup. +*/ + #define TIMER1_OFFSET (TEGRA_TMR1_BASE-TEGRA_TMR1_BASE) #define TIMER2_OFFSET (TEGRA_TMR2_BASE-TEGRA_TMR1_BASE) #define TIMER3_OFFSET (TEGRA_TMR3_BASE-TEGRA_TMR1_BASE) @@ -53,9 +61,41 @@ static void __iomem *timer_reg_base = IO_ADDRESS(TEGRA_TMR1_BASE); +#ifdef CONFIG_PM_SLEEP +static irqreturn_t tegra_lp2wake_interrupt(int irq, void *dev_id) +{ + timer_writel(1<<30, TIMER4_OFFSET + TIMER_PCR); + return IRQ_HANDLED; +} + +static struct irqaction tegra_lp2wake_irq = { + .name = "timer_lp2wake", + .flags = IRQF_DISABLED, + .handler = tegra_lp2wake_interrupt, + .dev_id = NULL, + .irq = INT_TMR4, +}; + +void tegra2_lp2_set_trigger(unsigned long cycles) +{ + timer_writel(0, TIMER4_OFFSET + TIMER_PTV); + if (cycles) { + u32 reg = 0x80000000ul | min(0x1ffffffful, cycles); + timer_writel(reg, TIMER4_OFFSET + TIMER_PTV); + } +} +EXPORT_SYMBOL(tegra2_lp2_set_trigger); + +unsigned long tegra2_lp2_timer_remain(void) +{ + return timer_readl(TIMER4_OFFSET + TIMER_PCR) & 0x1ffffffful; +} +#endif + void __init tegra2_init_timer(u32 *offset, int *irq) { unsigned long rate = clk_measure_input_freq(); + int ret; switch (rate) { case 12000000: @@ -74,21 +114,14 @@ void __init tegra2_init_timer(u32 *offset, int *irq) WARN(1, "Unknown clock rate"); } - *offset = TIMER3_OFFSET; - *irq = INT_TMR3; -} - -void tegra2_lp2_set_trigger(unsigned long cycles) -{ - timer_writel(0, TIMER4_OFFSET + TIMER_PTV); - if (cycles) { - u32 reg = 0x80000000ul | min(0x1ffffffful, cycles); - timer_writel(reg, TIMER4_OFFSET + TIMER_PTV); +#ifdef CONFIG_PM_SLEEP + ret = setup_irq(tegra_lp2wake_irq.irq, &tegra_lp2wake_irq); + if (ret) { + pr_err("Failed to register LP2 timer IRQ: %d\n", ret); + BUG(); } -} -EXPORT_SYMBOL(tegra2_lp2_set_trigger); +#endif -unsigned long tegra2_lp2_timer_remain(void) -{ - return timer_readl(TIMER4_OFFSET + TIMER_PCR) & 0x1ffffffful; + *offset = TIMER3_OFFSET; + *irq = INT_TMR3; } |