diff options
author | Joachim Eastwood <manabian@gmail.com> | 2012-10-28 14:31:07 -0400 |
---|---|---|
committer | Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> | 2012-11-18 18:51:08 -0500 |
commit | 454c46df83945602f1cbc86efcfd063c6945d869 (patch) | |
tree | 4c358a73f3163dbf28caf2932a86daf37165119e /arch/arm/mach-at91/at91rm9200_time.c | |
parent | 35ed3c7a3dda78e9dd0c75a31290b27520e4a99b (diff) |
ARM: AT91: Add DT support to AT91RM9200 System Timer
Based on AT91 PIT DT patch from Jean-Christophe PLAGNIOL-VILLARD.
Signed-off-by: Joachim Eastwood <manabian@gmail.com>
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Diffstat (limited to 'arch/arm/mach-at91/at91rm9200_time.c')
-rw-r--r-- | arch/arm/mach-at91/at91rm9200_time.c | 63 |
1 files changed, 61 insertions, 2 deletions
diff --git a/arch/arm/mach-at91/at91rm9200_time.c b/arch/arm/mach-at91/at91rm9200_time.c index aaa443b48c91..cafe98836c8a 100644 --- a/arch/arm/mach-at91/at91rm9200_time.c +++ b/arch/arm/mach-at91/at91rm9200_time.c | |||
@@ -24,6 +24,9 @@ | |||
24 | #include <linux/irq.h> | 24 | #include <linux/irq.h> |
25 | #include <linux/clockchips.h> | 25 | #include <linux/clockchips.h> |
26 | #include <linux/export.h> | 26 | #include <linux/export.h> |
27 | #include <linux/of.h> | ||
28 | #include <linux/of_address.h> | ||
29 | #include <linux/of_irq.h> | ||
27 | 30 | ||
28 | #include <asm/mach/time.h> | 31 | #include <asm/mach/time.h> |
29 | 32 | ||
@@ -91,7 +94,8 @@ static irqreturn_t at91rm9200_timer_interrupt(int irq, void *dev_id) | |||
91 | static struct irqaction at91rm9200_timer_irq = { | 94 | static struct irqaction at91rm9200_timer_irq = { |
92 | .name = "at91_tick", | 95 | .name = "at91_tick", |
93 | .flags = IRQF_SHARED | IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, | 96 | .flags = IRQF_SHARED | IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, |
94 | .handler = at91rm9200_timer_interrupt | 97 | .handler = at91rm9200_timer_interrupt, |
98 | .irq = NR_IRQS_LEGACY + AT91_ID_SYS, | ||
95 | }; | 99 | }; |
96 | 100 | ||
97 | static cycle_t read_clk32k(struct clocksource *cs) | 101 | static cycle_t read_clk32k(struct clocksource *cs) |
@@ -179,8 +183,60 @@ static struct clock_event_device clkevt = { | |||
179 | void __iomem *at91_st_base; | 183 | void __iomem *at91_st_base; |
180 | EXPORT_SYMBOL_GPL(at91_st_base); | 184 | EXPORT_SYMBOL_GPL(at91_st_base); |
181 | 185 | ||
186 | #ifdef CONFIG_OF | ||
187 | static struct of_device_id at91rm9200_st_timer_ids[] = { | ||
188 | { .compatible = "atmel,at91rm9200-st" }, | ||
189 | { /* sentinel */ } | ||
190 | }; | ||
191 | |||
192 | static int __init of_at91rm9200_st_init(void) | ||
193 | { | ||
194 | struct device_node *np; | ||
195 | int ret; | ||
196 | |||
197 | np = of_find_matching_node(NULL, at91rm9200_st_timer_ids); | ||
198 | if (!np) | ||
199 | goto err; | ||
200 | |||
201 | at91_st_base = of_iomap(np, 0); | ||
202 | if (!at91_st_base) | ||
203 | goto node_err; | ||
204 | |||
205 | /* Get the interrupts property */ | ||
206 | ret = irq_of_parse_and_map(np, 0); | ||
207 | if (!ret) | ||
208 | goto ioremap_err; | ||
209 | at91rm9200_timer_irq.irq = ret; | ||
210 | |||
211 | of_node_put(np); | ||
212 | |||
213 | return 0; | ||
214 | |||
215 | ioremap_err: | ||
216 | iounmap(at91_st_base); | ||
217 | node_err: | ||
218 | of_node_put(np); | ||
219 | err: | ||
220 | return -EINVAL; | ||
221 | } | ||
222 | #else | ||
223 | static int __init of_at91rm9200_st_init(void) | ||
224 | { | ||
225 | return -EINVAL; | ||
226 | } | ||
227 | #endif | ||
228 | |||
182 | void __init at91rm9200_ioremap_st(u32 addr) | 229 | void __init at91rm9200_ioremap_st(u32 addr) |
183 | { | 230 | { |
231 | #ifdef CONFIG_OF | ||
232 | struct device_node *np; | ||
233 | |||
234 | np = of_find_matching_node(NULL, at91rm9200_st_timer_ids); | ||
235 | if (np) { | ||
236 | of_node_put(np); | ||
237 | return; | ||
238 | } | ||
239 | #endif | ||
184 | at91_st_base = ioremap(addr, 256); | 240 | at91_st_base = ioremap(addr, 256); |
185 | if (!at91_st_base) | 241 | if (!at91_st_base) |
186 | panic("Impossible to ioremap ST\n"); | 242 | panic("Impossible to ioremap ST\n"); |
@@ -191,13 +247,16 @@ void __init at91rm9200_ioremap_st(u32 addr) | |||
191 | */ | 247 | */ |
192 | void __init at91rm9200_timer_init(void) | 248 | void __init at91rm9200_timer_init(void) |
193 | { | 249 | { |
250 | /* For device tree enabled device: initialize here */ | ||
251 | of_at91rm9200_st_init(); | ||
252 | |||
194 | /* Disable all timer interrupts, and clear any pending ones */ | 253 | /* Disable all timer interrupts, and clear any pending ones */ |
195 | at91_st_write(AT91_ST_IDR, | 254 | at91_st_write(AT91_ST_IDR, |
196 | AT91_ST_PITS | AT91_ST_WDOVF | AT91_ST_RTTINC | AT91_ST_ALMS); | 255 | AT91_ST_PITS | AT91_ST_WDOVF | AT91_ST_RTTINC | AT91_ST_ALMS); |
197 | at91_st_read(AT91_ST_SR); | 256 | at91_st_read(AT91_ST_SR); |
198 | 257 | ||
199 | /* Make IRQs happen for the system timer */ | 258 | /* Make IRQs happen for the system timer */ |
200 | setup_irq(NR_IRQS_LEGACY + AT91_ID_SYS, &at91rm9200_timer_irq); | 259 | setup_irq(at91rm9200_timer_irq.irq, &at91rm9200_timer_irq); |
201 | 260 | ||
202 | /* The 32KiHz "Slow Clock" (tick every 30517.58 nanoseconds) is used | 261 | /* The 32KiHz "Slow Clock" (tick every 30517.58 nanoseconds) is used |
203 | * directly for the clocksource and all clockevents, after adjusting | 262 | * directly for the clocksource and all clockevents, after adjusting |