ARM: at91: PIT: Rework probe functions
authorMaxime Ripard <maxime.ripard@free-electrons.com>
Tue, 1 Jul 2014 09:33:18 +0000 (11:33 +0200)
committerNicolas Ferre <nicolas.ferre@atmel.com>
Wed, 3 Sep 2014 08:55:22 +0000 (10:55 +0200)
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>
arch/arm/mach-at91/Kconfig
arch/arm/mach-at91/at91sam926x_time.c
arch/arm/mach-at91/board-dt-sam9.c
arch/arm/mach-at91/board-dt-sama5.c

index 6eb3c658761d617084bd0f5ec92662860b9c5b59..c3f9ebc5f9f52fd9956682535a96a11c5404488f 100644 (file)
@@ -34,6 +34,7 @@ config OLD_IRQ_AT91
        select SPARSE_IRQ
 
 config AT91_SAM9_TIME
+       select CLKSRC_OF if OF
        bool
 
 config HAVE_AT91_SMD
index b87a12f055402a9edaeda17653de629ab5588edc..af466eb6862455d886abeae90ba38cb2783863dd 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
 
-#include <asm/mach/time.h>
 #include <mach/hardware.h>
 
 #define AT91_PIT_MR            0x00                    /* Mode Register */
@@ -176,81 +175,21 @@ static struct irqaction at91sam926x_pit_irq = {
        .name           = "at91_tick",
        .flags          = IRQF_SHARED | IRQF_TIMER | IRQF_IRQPOLL,
        .handler        = at91sam926x_pit_interrupt,
-       .irq            = NR_IRQS_LEGACY + AT91_ID_SYS,
 };
 
-#ifdef CONFIG_OF
-static struct of_device_id pit_timer_ids[] = {
-       { .compatible = "atmel,at91sam9260-pit" },
-       { /* sentinel */ }
-};
-
-static int __init of_at91sam926x_pit_init(void)
-{
-       struct device_node      *np;
-       int                     ret;
-
-       np = of_find_matching_node(NULL, pit_timer_ids);
-       if (!np)
-               goto err;
-
-       pit_base_addr = of_iomap(np, 0);
-       if (!pit_base_addr)
-               goto node_err;
-
-       mck = of_clk_get(np, 0);
-
-       /* Get the interrupts property */
-       ret = irq_of_parse_and_map(np, 0);
-       if (!ret) {
-               pr_crit("AT91: PIT: Unable to get IRQ from DT\n");
-               if (!IS_ERR(mck))
-                       clk_put(mck);
-               goto ioremap_err;
-       }
-       at91sam926x_pit_irq.irq = ret;
-
-       of_node_put(np);
-
-       return 0;
-
-ioremap_err:
-       iounmap(pit_base_addr);
-node_err:
-       of_node_put(np);
-err:
-       return -EINVAL;
-}
-#else
-static int __init of_at91sam926x_pit_init(void)
-{
-       return -EINVAL;
-}
-#endif
-
 /*
  * Set up both clocksource and clockevent support.
  */
-void __init at91sam926x_pit_init(void)
+static void __init at91sam926x_pit_common_init(void)
 {
        unsigned long   pit_rate;
        unsigned        bits;
        int             ret;
 
-       mck = ERR_PTR(-ENOENT);
-
-       /* For device tree enabled device: initialize here */
-       of_at91sam926x_pit_init();
-
        /*
         * Use our actual MCK to figure out how many MCK/16 ticks per
         * 1/HZ period (instead of a compile-time constant LATCH).
         */
-       if (IS_ERR(mck))
-               mck = clk_get(NULL, "mck");
-
-       if (IS_ERR(mck))
-               panic("AT91: PIT: Unable to get mck clk\n");
        pit_rate = clk_get_rate(mck) / 16;
        pit_cycle = DIV_ROUND_CLOSEST(pit_rate, HZ);
        WARN_ON(((pit_cycle - 1) & ~AT91_PIT_PIV) != 0);
@@ -277,6 +216,51 @@ void __init at91sam926x_pit_init(void)
        clockevents_register_device(&pit_clkevt);
 }
 
+static void __init at91sam926x_pit_dt_init(struct device_node *node)
+{
+       unsigned int irq;
+
+       pit_base_addr = of_iomap(node, 0);
+       if (!pit_base_addr)
+               return;
+
+       mck = of_clk_get(node, 0);
+       if (IS_ERR(mck))
+               /* Fallback on clkdev for !CCF-based boards */
+               mck = clk_get(NULL, "mck");
+
+       if (IS_ERR(mck))
+               panic("AT91: PIT: Unable to get mck clk\n");
+
+       /* Get the interrupts property */
+       irq = irq_of_parse_and_map(node, 0);
+       if (!irq) {
+               pr_crit("AT91: PIT: Unable to get IRQ from DT\n");
+               goto clk_err;
+       }
+
+       at91sam926x_pit_irq.irq = irq;
+
+       at91sam926x_pit_common_init();
+
+clk_err:
+       clk_put(mck);
+       iounmap(pit_base_addr);
+}
+CLOCKSOURCE_OF_DECLARE(at91sam926x_pit, "atmel,at91sam9260-pit",
+                      at91sam926x_pit_dt_init);
+
+void __init at91sam926x_pit_init(void)
+{
+       mck = clk_get(NULL, "mck");
+       if (IS_ERR(mck))
+               panic("AT91: PIT: Unable to get mck clk\n");
+
+       at91sam926x_pit_irq.irq = NR_IRQS_LEGACY + AT91_ID_SYS;
+
+       at91sam926x_pit_common_init();
+}
+
 void __init at91sam926x_ioremap_pit(u32 addr)
 {
        if (of_have_populated_dt())
index dfa8d48146fe57d93c6c522f1ca36cf32a1df565..78962fd238595f74ffa30bae1ec32ba0f1211be6 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/of.h>
 #include <linux/of_irq.h>
 #include <linux/clk-provider.h>
+#include <linux/clocksource.h>
 
 #include <asm/setup.h>
 #include <asm/irq.h>
@@ -31,7 +32,7 @@ static void __init sam9_dt_timer_init(void)
 #if defined(CONFIG_COMMON_CLK)
        of_clk_init(NULL);
 #endif
-       at91sam926x_pit_init();
+       clocksource_of_init();
 }
 
 static const char *at91_dt_board_compat[] __initdata = {
index d6fe04bcaabd3ba5a688955b86ea1b270a8a25ab..4f01e34fae0ada19e4bb1b693cf4c3ab1c7b22b6 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/of_platform.h>
 #include <linux/phy.h>
 #include <linux/clk-provider.h>
+#include <linux/clocksource.h>
 
 #include <asm/setup.h>
 #include <asm/irq.h>
@@ -32,7 +33,7 @@ static void __init sama5_dt_timer_init(void)
 #if defined(CONFIG_COMMON_CLK)
        of_clk_init(NULL);
 #endif
-       at91sam926x_pit_init();
+       clocksource_of_init();
 }
 
 static int ksz9021rn_phy_fixup(struct phy_device *phy)