ARM: orion5x: switch to DT interrupts and timer
authorThomas Petazzoni <thomas.petazzoni@free-electrons.com>
Tue, 22 Apr 2014 21:26:27 +0000 (23:26 +0200)
committerJason Cooper <jason@lakedaemon.net>
Sat, 26 Apr 2014 19:45:07 +0000 (19:45 +0000)
This commit switches the Orion5x platforms described through DT to use
a DT-defined interrupt controller and timer.

This involves:

 * Describing in the DT the bridge interrupt controller, which is a
   child interrupt controller to the main one, which is used for timer
   and watchdog interrupts.

 * Describing in the DT the timer.

 * Adding in the DT the interrupt specifications for the watchdog.

 * Selecting the ORION_IRQCHIP and ORION_TIMER drivers to be compiled.

 * Change board-dt.c to no longer have an ->init_time() callback,
   since the default callback will work fine: it calls
   clocksource_of_init() and of_clk_init(), as needed.

 * Implement a multi-IRQ handler for non-DT platforms in
   mach-orion5x/irq.c.

Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Acked-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
Link: https://lkml.kernel.org/r/1398202002-28530-24-git-send-email-thomas.petazzoni@free-electrons.com
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
arch/arm/boot/dts/orion5x.dtsi
arch/arm/mach-orion5x/Kconfig
arch/arm/mach-orion5x/board-dt.c
arch/arm/mach-orion5x/irq.c

index 88df8a811ad3614bd46a8b1a0a1ecd106b4cf497..b4c2234fda1e59b966c696674d68f2316e82cc3a 100644 (file)
                                status = "disabled";
                        };
 
+                       bridge_intc: bridge-interrupt-ctrl@20110 {
+                               compatible = "marvell,orion-bridge-intc";
+                               interrupt-controller;
+                               #interrupt-cells = <1>;
+                               reg = <0x20110 0x8>;
+                               interrupts = <0>;
+                               marvell,#interrupts = <4>;
+                       };
+
                        intc: interrupt-controller@20200 {
                                compatible = "marvell,orion-intc";
                                interrupt-controller;
                                reg = <0x20200 0x08>;
                        };
 
+                       timer: timer@20300 {
+                               compatible = "marvell,orion-timer";
+                               reg = <0x20300 0x20>;
+                               interrupt-parent = <&bridge_intc>;
+                               interrupts = <1>, <2>;
+                               clocks = <&core_clk 0>;
+                       };
+
                        wdt: wdt@20300 {
                                compatible = "marvell,orion-wdt";
                                reg = <0x20300 0x28>;
+                               interrupt-parent = <&bridge_intc>;
+                               interrupts = <3>;
                                status = "okay";
                        };
 
index 4f5113279352e0d654931ef3d50c8e2d3ea40745..bd65872f5e045826c04898aeb14fe3f248e4b0cd 100644 (file)
@@ -6,6 +6,8 @@ config ARCH_ORION5X_DT
        bool "Marvell Orion5x Flattened Device Tree"
        select USE_OF
        select ORION_CLK
+       select ORION_IRQCHIP
+       select ORION_TIMER
        help
          Say 'Y' here if you want your kernel to support the
          Marvell Orion5x using flattened device tree.
index 34286ef163208160e46ffe735faff2b20742ef28..6dc4846519ec62bee1c1e6827858a8224b6ebb6b 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/cpu.h>
 #include <linux/mbus.h>
 #include <linux/clk-provider.h>
+#include <linux/clocksource.h>
 #include <asm/system_misc.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -36,17 +37,6 @@ static struct of_dev_auxdata orion5x_auxdata_lookup[] __initdata = {
        {},
 };
 
-static void orion5x_dt_init_early(void)
-{
-       orion_time_set_base(TIMER_VIRT_BASE);
-}
-
-static void orion5x_dt_init_time(void)
-{
-       orion5x_timer_init();
-       of_clk_init(NULL);
-}
-
 static void __init orion5x_dt_init(void)
 {
        char *dev_name;
@@ -86,9 +76,6 @@ static const char *orion5x_dt_compat[] = {
 DT_MACHINE_START(ORION5X_DT, "Marvell Orion5x (Flattened Device Tree)")
        /* Maintainer: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> */
        .map_io         = orion5x_map_io,
-       .init_early     = orion5x_dt_init_early,
-       .init_irq       = orion_dt_init_irq,
-       .init_time      = orion5x_dt_init_time,
        .init_machine   = orion5x_dt_init,
        .restart        = orion5x_restart,
        .dt_compat      = orion5x_dt_compat,
index 9654b0cc58928741c13281eaf7c6b737411dd7ec..cd4bac4d7e43f194f8bf0306f7ed808d48caec3d 100644 (file)
@@ -16,6 +16,7 @@
 #include <mach/bridge-regs.h>
 #include <plat/orion-gpio.h>
 #include <plat/irq.h>
+#include <asm/exception.h>
 #include "common.h"
 
 static int __initdata gpio0_irqs[4] = {
@@ -25,10 +26,37 @@ static int __initdata gpio0_irqs[4] = {
        IRQ_ORION5X_GPIO_24_31,
 };
 
+#ifdef CONFIG_MULTI_IRQ_HANDLER
+/*
+ * Compiling with both non-DT and DT support enabled, will
+ * break asm irq handler used by non-DT boards. Therefore,
+ * we provide a C-style irq handler even for non-DT boards,
+ * if MULTI_IRQ_HANDLER is set.
+ */
+
+asmlinkage void
+__exception_irq_entry orion5x_legacy_handle_irq(struct pt_regs *regs)
+{
+       u32 stat;
+
+       stat = readl_relaxed(MAIN_IRQ_CAUSE);
+       stat &= readl_relaxed(MAIN_IRQ_MASK);
+       if (stat) {
+               unsigned int hwirq = __fls(stat);
+               handle_IRQ(hwirq, regs);
+               return;
+       }
+}
+#endif
+
 void __init orion5x_init_irq(void)
 {
        orion_irq_init(0, MAIN_IRQ_MASK);
 
+#ifdef CONFIG_MULTI_IRQ_HANDLER
+       set_handle_irq(orion5x_legacy_handle_irq);
+#endif
+
        /*
         * Initialize gpiolib for GPIOs 0-31.
         */