aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorJean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>2012-02-27 05:19:34 -0500
committerNicolas Ferre <nicolas.ferre@atmel.com>2012-03-01 07:38:36 -0500
commit23fa648fd32658ca295de3ef2b7c883c7b8a6120 (patch)
tree987bbd0179c182faa455842cf66f63c054307ae5 /arch
parent8014d6f4dd074d4d248d3de7f63348fa2568476b (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.dtsi6
-rw-r--r--arch/arm/boot/dts/at91sam9g45.dtsi6
-rw-r--r--arch/arm/mach-at91/at91sam926x_time.c63
-rw-r--r--arch/arm/mach-at91/at91sam9x5.c2
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)
133static struct irqaction at91sam926x_pit_irq = { 136static 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
139static void at91sam926x_pit_reset(void) 143static 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
157static struct of_device_id pit_timer_ids[] = {
158 { .compatible = "atmel,at91sam9260-pit" },
159 { /* sentinel */ }
160};
161
162static 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
185ioremap_err:
186 iounmap(pit_base_addr);
187node_err:
188 of_node_put(np);
189err:
190 return -EINVAL;
191}
192#else
193static 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
194void __init at91sam926x_ioremap_pit(u32 addr) 244void __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
302static void __init at91sam9x5_ioremap_registers(void) 302static 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