aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMaxime Ripard <maxime.ripard@free-electrons.com>2014-07-01 05:33:18 -0400
committerNicolas Ferre <nicolas.ferre@atmel.com>2014-09-03 04:55:22 -0400
commitf807a89cfe3e7379ec501810d67a5888edbb94f1 (patch)
tree43882348a1236b368ab46c5c15929087757ebdc9
parenta7d84d73b9ca32871da8fc05e95ca47c04fbb110 (diff)
ARM: at91: PIT: Rework probe functions
The PIT timer driver until now had a single probe function, disregarding wether it was probed through DT or in the old-style way. This code later on was calling some DT function to retrieve the proper values for its base address, interrupts and clocks. While this was working, it was preventing the usage of CLOCKSOURCE_OF_DECLARE, and the two different probe path were not as clearly separated as they could be. Rework the probe path to take this into account, and switch to CLOCKSOURCE_OF_DECLARE. Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> Acked-by: Boris BREZILLON <boris.brezillon@free-electrons.com> Acked-by: Alexandre Belloni <alexandre.belloni@free-electrons.com> Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org> Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
-rw-r--r--arch/arm/mach-at91/Kconfig1
-rw-r--r--arch/arm/mach-at91/at91sam926x_time.c108
-rw-r--r--arch/arm/mach-at91/board-dt-sam9.c3
-rw-r--r--arch/arm/mach-at91/board-dt-sama5.c3
4 files changed, 51 insertions, 64 deletions
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 6eb3c658761d..c3f9ebc5f9f5 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -34,6 +34,7 @@ config OLD_IRQ_AT91
34 select SPARSE_IRQ 34 select SPARSE_IRQ
35 35
36config AT91_SAM9_TIME 36config AT91_SAM9_TIME
37 select CLKSRC_OF if OF
37 bool 38 bool
38 39
39config HAVE_AT91_SMD 40config HAVE_AT91_SMD
diff --git a/arch/arm/mach-at91/at91sam926x_time.c b/arch/arm/mach-at91/at91sam926x_time.c
index b87a12f05540..af466eb68624 100644
--- a/arch/arm/mach-at91/at91sam926x_time.c
+++ b/arch/arm/mach-at91/at91sam926x_time.c
@@ -19,7 +19,6 @@
19#include <linux/of_address.h> 19#include <linux/of_address.h>
20#include <linux/of_irq.h> 20#include <linux/of_irq.h>
21 21
22#include <asm/mach/time.h>
23#include <mach/hardware.h> 22#include <mach/hardware.h>
24 23
25#define AT91_PIT_MR 0x00 /* Mode Register */ 24#define AT91_PIT_MR 0x00 /* Mode Register */
@@ -176,81 +175,21 @@ static struct irqaction at91sam926x_pit_irq = {
176 .name = "at91_tick", 175 .name = "at91_tick",
177 .flags = IRQF_SHARED | IRQF_TIMER | IRQF_IRQPOLL, 176 .flags = IRQF_SHARED | IRQF_TIMER | IRQF_IRQPOLL,
178 .handler = at91sam926x_pit_interrupt, 177 .handler = at91sam926x_pit_interrupt,
179 .irq = NR_IRQS_LEGACY + AT91_ID_SYS,
180}; 178};
181 179
182#ifdef CONFIG_OF
183static struct of_device_id pit_timer_ids[] = {
184 { .compatible = "atmel,at91sam9260-pit" },
185 { /* sentinel */ }
186};
187
188static int __init of_at91sam926x_pit_init(void)
189{
190 struct device_node *np;
191 int ret;
192
193 np = of_find_matching_node(NULL, pit_timer_ids);
194 if (!np)
195 goto err;
196
197 pit_base_addr = of_iomap(np, 0);
198 if (!pit_base_addr)
199 goto node_err;
200
201 mck = of_clk_get(np, 0);
202
203 /* Get the interrupts property */
204 ret = irq_of_parse_and_map(np, 0);
205 if (!ret) {
206 pr_crit("AT91: PIT: Unable to get IRQ from DT\n");
207 if (!IS_ERR(mck))
208 clk_put(mck);
209 goto ioremap_err;
210 }
211 at91sam926x_pit_irq.irq = ret;
212
213 of_node_put(np);
214
215 return 0;
216
217ioremap_err:
218 iounmap(pit_base_addr);
219node_err:
220 of_node_put(np);
221err:
222 return -EINVAL;
223}
224#else
225static int __init of_at91sam926x_pit_init(void)
226{
227 return -EINVAL;
228}
229#endif
230
231/* 180/*
232 * Set up both clocksource and clockevent support. 181 * Set up both clocksource and clockevent support.
233 */ 182 */
234void __init at91sam926x_pit_init(void) 183static void __init at91sam926x_pit_common_init(void)
235{ 184{
236 unsigned long pit_rate; 185 unsigned long pit_rate;
237 unsigned bits; 186 unsigned bits;
238 int ret; 187 int ret;
239 188
240 mck = ERR_PTR(-ENOENT);
241
242 /* For device tree enabled device: initialize here */
243 of_at91sam926x_pit_init();
244
245 /* 189 /*
246 * Use our actual MCK to figure out how many MCK/16 ticks per 190 * Use our actual MCK to figure out how many MCK/16 ticks per
247 * 1/HZ period (instead of a compile-time constant LATCH). 191 * 1/HZ period (instead of a compile-time constant LATCH).
248 */ 192 */
249 if (IS_ERR(mck))
250 mck = clk_get(NULL, "mck");
251
252 if (IS_ERR(mck))
253 panic("AT91: PIT: Unable to get mck clk\n");
254 pit_rate = clk_get_rate(mck) / 16; 193 pit_rate = clk_get_rate(mck) / 16;
255 pit_cycle = DIV_ROUND_CLOSEST(pit_rate, HZ); 194 pit_cycle = DIV_ROUND_CLOSEST(pit_rate, HZ);
256 WARN_ON(((pit_cycle - 1) & ~AT91_PIT_PIV) != 0); 195 WARN_ON(((pit_cycle - 1) & ~AT91_PIT_PIV) != 0);
@@ -277,6 +216,51 @@ void __init at91sam926x_pit_init(void)
277 clockevents_register_device(&pit_clkevt); 216 clockevents_register_device(&pit_clkevt);
278} 217}
279 218
219static void __init at91sam926x_pit_dt_init(struct device_node *node)
220{
221 unsigned int irq;
222
223 pit_base_addr = of_iomap(node, 0);
224 if (!pit_base_addr)
225 return;
226
227 mck = of_clk_get(node, 0);
228 if (IS_ERR(mck))
229 /* Fallback on clkdev for !CCF-based boards */
230 mck = clk_get(NULL, "mck");
231
232 if (IS_ERR(mck))
233 panic("AT91: PIT: Unable to get mck clk\n");
234
235 /* Get the interrupts property */
236 irq = irq_of_parse_and_map(node, 0);
237 if (!irq) {
238 pr_crit("AT91: PIT: Unable to get IRQ from DT\n");
239 goto clk_err;
240 }
241
242 at91sam926x_pit_irq.irq = irq;
243
244 at91sam926x_pit_common_init();
245
246clk_err:
247 clk_put(mck);
248 iounmap(pit_base_addr);
249}
250CLOCKSOURCE_OF_DECLARE(at91sam926x_pit, "atmel,at91sam9260-pit",
251 at91sam926x_pit_dt_init);
252
253void __init at91sam926x_pit_init(void)
254{
255 mck = clk_get(NULL, "mck");
256 if (IS_ERR(mck))
257 panic("AT91: PIT: Unable to get mck clk\n");
258
259 at91sam926x_pit_irq.irq = NR_IRQS_LEGACY + AT91_ID_SYS;
260
261 at91sam926x_pit_common_init();
262}
263
280void __init at91sam926x_ioremap_pit(u32 addr) 264void __init at91sam926x_ioremap_pit(u32 addr)
281{ 265{
282 if (of_have_populated_dt()) 266 if (of_have_populated_dt())
diff --git a/arch/arm/mach-at91/board-dt-sam9.c b/arch/arm/mach-at91/board-dt-sam9.c
index dfa8d48146fe..78962fd23859 100644
--- a/arch/arm/mach-at91/board-dt-sam9.c
+++ b/arch/arm/mach-at91/board-dt-sam9.c
@@ -14,6 +14,7 @@
14#include <linux/of.h> 14#include <linux/of.h>
15#include <linux/of_irq.h> 15#include <linux/of_irq.h>
16#include <linux/clk-provider.h> 16#include <linux/clk-provider.h>
17#include <linux/clocksource.h>
17 18
18#include <asm/setup.h> 19#include <asm/setup.h>
19#include <asm/irq.h> 20#include <asm/irq.h>
@@ -31,7 +32,7 @@ static void __init sam9_dt_timer_init(void)
31#if defined(CONFIG_COMMON_CLK) 32#if defined(CONFIG_COMMON_CLK)
32 of_clk_init(NULL); 33 of_clk_init(NULL);
33#endif 34#endif
34 at91sam926x_pit_init(); 35 clocksource_of_init();
35} 36}
36 37
37static const char *at91_dt_board_compat[] __initdata = { 38static const char *at91_dt_board_compat[] __initdata = {
diff --git a/arch/arm/mach-at91/board-dt-sama5.c b/arch/arm/mach-at91/board-dt-sama5.c
index d6fe04bcaabd..4f01e34fae0a 100644
--- a/arch/arm/mach-at91/board-dt-sama5.c
+++ b/arch/arm/mach-at91/board-dt-sama5.c
@@ -17,6 +17,7 @@
17#include <linux/of_platform.h> 17#include <linux/of_platform.h>
18#include <linux/phy.h> 18#include <linux/phy.h>
19#include <linux/clk-provider.h> 19#include <linux/clk-provider.h>
20#include <linux/clocksource.h>
20 21
21#include <asm/setup.h> 22#include <asm/setup.h>
22#include <asm/irq.h> 23#include <asm/irq.h>
@@ -32,7 +33,7 @@ static void __init sama5_dt_timer_init(void)
32#if defined(CONFIG_COMMON_CLK) 33#if defined(CONFIG_COMMON_CLK)
33 of_clk_init(NULL); 34 of_clk_init(NULL);
34#endif 35#endif
35 at91sam926x_pit_init(); 36 clocksource_of_init();
36} 37}
37 38
38static int ksz9021rn_phy_fixup(struct phy_device *phy) 39static int ksz9021rn_phy_fixup(struct phy_device *phy)