diff options
author | Stephen Warren <swarren@nvidia.com> | 2012-09-19 15:13:33 -0400 |
---|---|---|
committer | Stephen Warren <swarren@nvidia.com> | 2012-11-16 14:22:16 -0500 |
commit | 56415480e90a6ba31e9fdda2cc860c3fcaa80acc (patch) | |
tree | fc8711068fc88010755bb572a94ab4d5f079c575 /arch/arm/mach-tegra/timer.c | |
parent | 58664f90525f9f1cef63167ee9ae3d6100f58494 (diff) |
ARM: tegra: enhance timer.c to get IRQ info from device tree
Modify Tegra's timer code to parse the Tegra timer IRQ from device tree,
and to instantiate the TWD from device tree, rather than relying on hard-
coded values from <mach/irqs.h>.
Signed-off-by: Stephen Warren <swarren@nvidia.com>
Diffstat (limited to 'arch/arm/mach-tegra/timer.c')
-rw-r--r-- | arch/arm/mach-tegra/timer.c | 41 |
1 files changed, 23 insertions, 18 deletions
diff --git a/arch/arm/mach-tegra/timer.c b/arch/arm/mach-tegra/timer.c index afcd108f0f28..026bad4ac57a 100644 --- a/arch/arm/mach-tegra/timer.c +++ b/arch/arm/mach-tegra/timer.c | |||
@@ -26,13 +26,12 @@ | |||
26 | #include <linux/clocksource.h> | 26 | #include <linux/clocksource.h> |
27 | #include <linux/clk.h> | 27 | #include <linux/clk.h> |
28 | #include <linux/io.h> | 28 | #include <linux/io.h> |
29 | #include <linux/of_irq.h> | ||
29 | 30 | ||
30 | #include <asm/mach/time.h> | 31 | #include <asm/mach/time.h> |
31 | #include <asm/smp_twd.h> | 32 | #include <asm/smp_twd.h> |
32 | #include <asm/sched_clock.h> | 33 | #include <asm/sched_clock.h> |
33 | 34 | ||
34 | #include <mach/irqs.h> | ||
35 | |||
36 | #include "board.h" | 35 | #include "board.h" |
37 | #include "clock.h" | 36 | #include "clock.h" |
38 | #include "iomap.h" | 37 | #include "iomap.h" |
@@ -158,30 +157,32 @@ static struct irqaction tegra_timer_irq = { | |||
158 | .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_TRIGGER_HIGH, | 157 | .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_TRIGGER_HIGH, |
159 | .handler = tegra_timer_interrupt, | 158 | .handler = tegra_timer_interrupt, |
160 | .dev_id = &tegra_clockevent, | 159 | .dev_id = &tegra_clockevent, |
161 | .irq = INT_TMR3, | ||
162 | }; | 160 | }; |
163 | 161 | ||
164 | #ifdef CONFIG_HAVE_ARM_TWD | 162 | static const struct of_device_id timer_match[] __initconst = { |
165 | static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, | 163 | { .compatible = "nvidia,tegra20-timer" }, |
166 | TEGRA_ARM_PERIF_BASE + 0x600, | 164 | {} |
167 | IRQ_LOCALTIMER); | 165 | }; |
168 | |||
169 | static void __init tegra_twd_init(void) | ||
170 | { | ||
171 | int err = twd_local_timer_register(&twd_local_timer); | ||
172 | if (err) | ||
173 | pr_err("twd_local_timer_register failed %d\n", err); | ||
174 | } | ||
175 | #else | ||
176 | #define tegra_twd_init() do {} while(0) | ||
177 | #endif | ||
178 | 166 | ||
179 | static void __init tegra_init_timer(void) | 167 | static void __init tegra_init_timer(void) |
180 | { | 168 | { |
169 | struct device_node *np; | ||
181 | struct clk *clk; | 170 | struct clk *clk; |
182 | unsigned long rate; | 171 | unsigned long rate; |
183 | int ret; | 172 | int ret; |
184 | 173 | ||
174 | np = of_find_matching_node(NULL, timer_match); | ||
175 | if (!np) { | ||
176 | pr_err("Failed to find timer DT node\n"); | ||
177 | BUG(); | ||
178 | } | ||
179 | |||
180 | tegra_timer_irq.irq = irq_of_parse_and_map(np, 2); | ||
181 | if (tegra_timer_irq.irq <= 0) { | ||
182 | pr_err("Failed to map timer IRQ\n"); | ||
183 | BUG(); | ||
184 | } | ||
185 | |||
185 | clk = clk_get_sys("timer", NULL); | 186 | clk = clk_get_sys("timer", NULL); |
186 | if (IS_ERR(clk)) { | 187 | if (IS_ERR(clk)) { |
187 | pr_warn("Unable to get timer clock. Assuming 12Mhz input clock.\n"); | 188 | pr_warn("Unable to get timer clock. Assuming 12Mhz input clock.\n"); |
@@ -201,6 +202,8 @@ static void __init tegra_init_timer(void) | |||
201 | else | 202 | else |
202 | clk_prepare_enable(clk); | 203 | clk_prepare_enable(clk); |
203 | 204 | ||
205 | of_node_put(np); | ||
206 | |||
204 | switch (rate) { | 207 | switch (rate) { |
205 | case 12000000: | 208 | case 12000000: |
206 | timer_writel(0x000b, TIMERUS_USEC_CFG); | 209 | timer_writel(0x000b, TIMERUS_USEC_CFG); |
@@ -240,7 +243,9 @@ static void __init tegra_init_timer(void) | |||
240 | tegra_clockevent.cpumask = cpu_all_mask; | 243 | tegra_clockevent.cpumask = cpu_all_mask; |
241 | tegra_clockevent.irq = tegra_timer_irq.irq; | 244 | tegra_clockevent.irq = tegra_timer_irq.irq; |
242 | clockevents_register_device(&tegra_clockevent); | 245 | clockevents_register_device(&tegra_clockevent); |
243 | tegra_twd_init(); | 246 | #ifdef CONFIG_HAVE_ARM_TWD |
247 | twd_local_timer_of_register(); | ||
248 | #endif | ||
244 | register_persistent_clock(NULL, tegra_read_persistent_clock); | 249 | register_persistent_clock(NULL, tegra_read_persistent_clock); |
245 | } | 250 | } |
246 | 251 | ||