diff options
author | Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> | 2012-02-27 05:19:34 -0500 |
---|---|---|
committer | Nicolas Ferre <nicolas.ferre@atmel.com> | 2012-03-01 07:38:36 -0500 |
commit | 23fa648fd32658ca295de3ef2b7c883c7b8a6120 (patch) | |
tree | 987bbd0179c182faa455842cf66f63c054307ae5 /arch | |
parent | 8014d6f4dd074d4d248d3de7f63348fa2568476b (diff) |
ARM: at91: pit add DT support
Retreive registers address and IRQ from device tree entry.
Called from at91_dt_init_irq() so that timers are up-n-running
when timers initialization will occur.
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
[nicolas.ferre@atmel.com: change error path and interrupts property handling]
Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/boot/dts/at91sam9g20.dtsi | 6 | ||||
-rw-r--r-- | arch/arm/boot/dts/at91sam9g45.dtsi | 6 | ||||
-rw-r--r-- | arch/arm/mach-at91/at91sam926x_time.c | 63 | ||||
-rw-r--r-- | arch/arm/mach-at91/at91sam9x5.c | 2 |
4 files changed, 73 insertions, 4 deletions
diff --git a/arch/arm/boot/dts/at91sam9g20.dtsi b/arch/arm/boot/dts/at91sam9g20.dtsi index 325989a27a7a..04c56c41001f 100644 --- a/arch/arm/boot/dts/at91sam9g20.dtsi +++ b/arch/arm/boot/dts/at91sam9g20.dtsi | |||
@@ -57,6 +57,12 @@ | |||
57 | reg = <0xfffff000 0x200>; | 57 | reg = <0xfffff000 0x200>; |
58 | }; | 58 | }; |
59 | 59 | ||
60 | pit: timer@fffffd30 { | ||
61 | compatible = "atmel,at91sam9260-pit"; | ||
62 | reg = <0xfffffd30 0xf>; | ||
63 | interrupts = <1 4>; | ||
64 | }; | ||
65 | |||
60 | pioA: gpio@fffff400 { | 66 | pioA: gpio@fffff400 { |
61 | compatible = "atmel,at91rm9200-gpio"; | 67 | compatible = "atmel,at91rm9200-gpio"; |
62 | reg = <0xfffff400 0x100>; | 68 | reg = <0xfffff400 0x100>; |
diff --git a/arch/arm/boot/dts/at91sam9g45.dtsi b/arch/arm/boot/dts/at91sam9g45.dtsi index a9dbbb5b86f5..3881cab965fa 100644 --- a/arch/arm/boot/dts/at91sam9g45.dtsi +++ b/arch/arm/boot/dts/at91sam9g45.dtsi | |||
@@ -58,6 +58,12 @@ | |||
58 | reg = <0xfffff000 0x200>; | 58 | reg = <0xfffff000 0x200>; |
59 | }; | 59 | }; |
60 | 60 | ||
61 | pit: timer@fffffd30 { | ||
62 | compatible = "atmel,at91sam9260-pit"; | ||
63 | reg = <0xfffffd30 0xf>; | ||
64 | interrupts = <1 4>; | ||
65 | }; | ||
66 | |||
61 | dma: dma-controller@ffffec00 { | 67 | dma: dma-controller@ffffec00 { |
62 | compatible = "atmel,at91sam9g45-dma"; | 68 | compatible = "atmel,at91sam9g45-dma"; |
63 | reg = <0xffffec00 0x200>; | 69 | reg = <0xffffec00 0x200>; |
diff --git a/arch/arm/mach-at91/at91sam926x_time.c b/arch/arm/mach-at91/at91sam926x_time.c index d89ead740a99..5d71476a2832 100644 --- a/arch/arm/mach-at91/at91sam926x_time.c +++ b/arch/arm/mach-at91/at91sam926x_time.c | |||
@@ -14,6 +14,9 @@ | |||
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/clk.h> | 15 | #include <linux/clk.h> |
16 | #include <linux/clockchips.h> | 16 | #include <linux/clockchips.h> |
17 | #include <linux/of.h> | ||
18 | #include <linux/of_address.h> | ||
19 | #include <linux/of_irq.h> | ||
17 | 20 | ||
18 | #include <asm/mach/time.h> | 21 | #include <asm/mach/time.h> |
19 | 22 | ||
@@ -133,7 +136,8 @@ static irqreturn_t at91sam926x_pit_interrupt(int irq, void *dev_id) | |||
133 | static struct irqaction at91sam926x_pit_irq = { | 136 | static struct irqaction at91sam926x_pit_irq = { |
134 | .name = "at91_tick", | 137 | .name = "at91_tick", |
135 | .flags = IRQF_SHARED | IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, | 138 | .flags = IRQF_SHARED | IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, |
136 | .handler = at91sam926x_pit_interrupt | 139 | .handler = at91sam926x_pit_interrupt, |
140 | .irq = AT91_ID_SYS, | ||
137 | }; | 141 | }; |
138 | 142 | ||
139 | static void at91sam926x_pit_reset(void) | 143 | static void at91sam926x_pit_reset(void) |
@@ -149,6 +153,49 @@ static void at91sam926x_pit_reset(void) | |||
149 | pit_write(AT91_PIT_MR, (pit_cycle - 1) | AT91_PIT_PITEN); | 153 | pit_write(AT91_PIT_MR, (pit_cycle - 1) | AT91_PIT_PITEN); |
150 | } | 154 | } |
151 | 155 | ||
156 | #ifdef CONFIG_OF | ||
157 | static struct of_device_id pit_timer_ids[] = { | ||
158 | { .compatible = "atmel,at91sam9260-pit" }, | ||
159 | { /* sentinel */ } | ||
160 | }; | ||
161 | |||
162 | static int __init of_at91sam926x_pit_init(void) | ||
163 | { | ||
164 | struct device_node *np; | ||
165 | int ret; | ||
166 | |||
167 | np = of_find_matching_node(NULL, pit_timer_ids); | ||
168 | if (!np) | ||
169 | goto err; | ||
170 | |||
171 | pit_base_addr = of_iomap(np, 0); | ||
172 | if (!pit_base_addr) | ||
173 | goto node_err; | ||
174 | |||
175 | /* Get the interrupts property */ | ||
176 | ret = irq_of_parse_and_map(np, 0); | ||
177 | if (!ret) | ||
178 | goto ioremap_err; | ||
179 | at91sam926x_pit_irq.irq = ret; | ||
180 | |||
181 | of_node_put(np); | ||
182 | |||
183 | return 0; | ||
184 | |||
185 | ioremap_err: | ||
186 | iounmap(pit_base_addr); | ||
187 | node_err: | ||
188 | of_node_put(np); | ||
189 | err: | ||
190 | return -EINVAL; | ||
191 | } | ||
192 | #else | ||
193 | static int __init of_at91sam926x_pit_init(void) | ||
194 | { | ||
195 | return -EINVAL; | ||
196 | } | ||
197 | #endif | ||
198 | |||
152 | /* | 199 | /* |
153 | * Set up both clocksource and clockevent support. | 200 | * Set up both clocksource and clockevent support. |
154 | */ | 201 | */ |
@@ -157,6 +204,9 @@ static void __init at91sam926x_pit_init(void) | |||
157 | unsigned long pit_rate; | 204 | unsigned long pit_rate; |
158 | unsigned bits; | 205 | unsigned bits; |
159 | 206 | ||
207 | /* For device tree enabled device: initialize here */ | ||
208 | of_at91sam926x_pit_init(); | ||
209 | |||
160 | /* | 210 | /* |
161 | * Use our actual MCK to figure out how many MCK/16 ticks per | 211 | * Use our actual MCK to figure out how many MCK/16 ticks per |
162 | * 1/HZ period (instead of a compile-time constant LATCH). | 212 | * 1/HZ period (instead of a compile-time constant LATCH). |
@@ -177,7 +227,7 @@ static void __init at91sam926x_pit_init(void) | |||
177 | clocksource_register_hz(&pit_clk, pit_rate); | 227 | clocksource_register_hz(&pit_clk, pit_rate); |
178 | 228 | ||
179 | /* Set up irq handler */ | 229 | /* Set up irq handler */ |
180 | setup_irq(AT91_ID_SYS, &at91sam926x_pit_irq); | 230 | setup_irq(at91sam926x_pit_irq.irq, &at91sam926x_pit_irq); |
181 | 231 | ||
182 | /* Set up and register clockevents */ | 232 | /* Set up and register clockevents */ |
183 | pit_clkevt.mult = div_sc(pit_rate, NSEC_PER_SEC, pit_clkevt.shift); | 233 | pit_clkevt.mult = div_sc(pit_rate, NSEC_PER_SEC, pit_clkevt.shift); |
@@ -193,6 +243,15 @@ static void at91sam926x_pit_suspend(void) | |||
193 | 243 | ||
194 | void __init at91sam926x_ioremap_pit(u32 addr) | 244 | void __init at91sam926x_ioremap_pit(u32 addr) |
195 | { | 245 | { |
246 | #if defined(CONFIG_OF) | ||
247 | struct device_node *np = | ||
248 | of_find_matching_node(NULL, pit_timer_ids); | ||
249 | |||
250 | if (np) { | ||
251 | of_node_put(np); | ||
252 | return; | ||
253 | } | ||
254 | #endif | ||
196 | pit_base_addr = ioremap(addr, 16); | 255 | pit_base_addr = ioremap(addr, 16); |
197 | 256 | ||
198 | if (!pit_base_addr) | 257 | if (!pit_base_addr) |
diff --git a/arch/arm/mach-at91/at91sam9x5.c b/arch/arm/mach-at91/at91sam9x5.c index d17d4262665b..a34d96afa746 100644 --- a/arch/arm/mach-at91/at91sam9x5.c +++ b/arch/arm/mach-at91/at91sam9x5.c | |||
@@ -301,8 +301,6 @@ static void __init at91sam9x5_map_io(void) | |||
301 | 301 | ||
302 | static void __init at91sam9x5_ioremap_registers(void) | 302 | static void __init at91sam9x5_ioremap_registers(void) |
303 | { | 303 | { |
304 | if (of_at91sam926x_pit_init() < 0) | ||
305 | panic("Impossible to find PIT\n"); | ||
306 | at91_ioremap_ramc(0, AT91SAM9X5_BASE_DDRSDRC0, 512); | 304 | at91_ioremap_ramc(0, AT91SAM9X5_BASE_DDRSDRC0, 512); |
307 | } | 305 | } |
308 | 306 | ||