Skip to contentSkip to conversation

ARM: Orion: Hoist bridge interrupt handling out of the timer

PATCH New Jason Gunthorpe 5 participants 15 messages Dec 11, 2012 – Jan 11, 2013

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

PATCH v2 1/3 ARM: Orion: Hoist bridge interrupt handling out of the timer

The intent of this patch is to expose the other bridge cause interrupts to users in the kernel.

- Add orion_bridge_irq_init to create a new edge triggered interrupt chip based on the bridge cause register
- Remove all interrupt register code from time.c and use normal interrupt functions instead
- Update the machines that use orion_time_init to call orion_bridge_irq_init and use the new signature

Tested on a Kirkwood platform.

I'm skeptical that MV78xx0 has a bridge interrupt cause/mask register, it was setup so the timer code would touch those registers, so I've preserved that, but prior to this patch the 'bridge cause register' was only written to, never read. If it is wired-to-zero because it doesn't exist then the timer will fail to function.

---
 arch/arm/mach-dove/common.c                       |    7 ++-
 arch/arm/mach-dove/include/mach/bridge-regs.h     |    2 +-
 arch/arm/mach-dove/include/mach/irqs.h            |    9 +++-
 arch/arm/mach-kirkwood/common.c                   |    8 ++-
 arch/arm/mach-kirkwood/include/mach/bridge-regs.h |    2 -
 arch/arm/mach-kirkwood/include/mach/irqs.h        |   14 ++++-
 arch/arm/mach-mv78xx0/common.c                    |   12 +++-
 arch/arm/mach-mv78xx0/include/mach/bridge-regs.h  |    2 +-
 arch/arm/mach-mv78xx0/include/mach/irqs.h         |    9 +++-
 arch/arm/mach-orion5x/common.c                    |    8 ++-
 arch/arm/mach-orion5x/include/mach/bridge-regs.h  |    2 -
 arch/arm/mach-orion5x/include/mach/irqs.h         |    9 +++-
 arch/arm/plat-orion/include/plat/irq.h            |    3 +
 arch/arm/plat-orion/include/plat/time.h           |    4 +-
 arch/arm/plat-orion/irq.c                         |   70 +++++++++++++++++++++
 arch/arm/plat-orion/time.c                        |   46 +++-----------
 16 files changed, 149 insertions(+), 58 deletions(-)

v2 changes
- Defines for BRIDGE registers
- Re-order the bridge IRQs to follow the GPIO irqs, otherwise there will be problems when switching to DT
- Make orion_bridge_irq_init suitable for being DT bound, call irq_alloc_descs to get a dynamic range allocation.
- Use "orion_bridge" as the chip name
- I left orion_bridge_irq_init in the timer_init functions. For the DT boards there is no better place for it at this point, putting it in eg, kirkwood_init_irq, will not call it on the DT case and the board won't boot. The next patch provides a solution for the DT case so then we can safely move it.

arch/arm/mach-dove/common.c +5 -2
index f723fe1..6bad21b 100644
@@ -243,8 +243,11 @@ static int __init dove_find_tclk(void)
 static void __init dove_timer_init(void)
 {
 	dove_tclk = dove_find_tclk();
-	orion_time_init(BRIDGE_VIRT_BASE, BRIDGE_INT_TIMER1_CLR,
-			IRQ_DOVE_BRIDGE, dove_tclk);
+	if (orion_bridge_irq_init(IRQ_DOVE_BRIDGE,
+				  IRQ_DOVE_BRIDGE_START,
+				  BRIDGE_CAUSE, NULL))
+		panic("Unable to setup bridge irqs");
+	orion_time_init(IRQ_DOVE_BRIDGE_TIMER1, dove_tclk);
 }
 
 struct sys_timer dove_timer = {
arch/arm/mach-dove/include/mach/bridge-regs.h +1 -1
index 99f259e..3bd4656 100644
@@ -26,7 +26,7 @@
 #define SYSTEM_SOFT_RESET	(BRIDGE_VIRT_BASE + 0x010c)
 #define  SOFT_RESET		0x00000001
 
-#define  BRIDGE_INT_TIMER1_CLR	(~0x0004)
+#define BRIDGE_CAUSE            (BRIDGE_VIRT_BASE + 0x0110)
 
 #define IRQ_VIRT_BASE		(BRIDGE_VIRT_BASE + 0x0200)
 #define IRQ_CAUSE_LOW_OFF	0x0000
arch/arm/mach-dove/include/mach/irqs.h +8 -1
index 03d401d..f153de0 100644
@@ -90,7 +90,14 @@
 #define NR_PMU_IRQS		7
 #define IRQ_DOVE_RTC		(IRQ_DOVE_PMU_START + 5)
 
-#define NR_IRQS			(IRQ_DOVE_PMU_START + NR_PMU_IRQS)
+/*
+ * Bridge Interrupt Controller
+ */
+#define IRQ_DOVE_BRIDGE_START   (IRQ_DOVE_PMU_START + NR_PMU_IRQS)
+#define IRQ_DOVE_BRIDGE_TIMER1  (IRQ_DOVE_BRIDGE_START + 2)
+#define NR_BRIDGE_IRQS          6
+
+#define NR_IRQS			(IRQ_DOVE_BRIDGE_START + NR_BRIDGE_IRQS)
 
 
 #endif
arch/arm/mach-kirkwood/common.c +6 -2
index 906c22e..ccd3ed5 100644
@@ -35,6 +35,7 @@
 #include <plat/time.h>
 #include <plat/addr-map.h>
 #include <linux/platform_data/dma-mv_xor.h>
+#include <plat/irq.h>
 #include "common.h"
 
 /*****************************************************************************
@@ -534,8 +535,11 @@ static void __init kirkwood_timer_init(void)
 {
 	kirkwood_tclk = kirkwood_find_tclk();
 
-	orion_time_init(BRIDGE_VIRT_BASE, BRIDGE_INT_TIMER1_CLR,
-			IRQ_KIRKWOOD_BRIDGE, kirkwood_tclk);
+	if (orion_bridge_irq_init(IRQ_KIRKWOOD_BRIDGE,
+				  IRQ_KIRKWOOD_BRIDGE_START,
+				  BRIDGE_CAUSE, NULL))
+		panic("Unable to setup bridge irqs");
+	orion_time_init(IRQ_KIRKWOOD_BRIDGE_TIMER1, kirkwood_tclk);
 }
 
 struct sys_timer kirkwood_timer = {
arch/arm/mach-kirkwood/include/mach/bridge-regs.h +0 -2
index 5c82b7d..fd66a56 100644
@@ -29,8 +29,6 @@
 #define BRIDGE_CAUSE		(BRIDGE_VIRT_BASE + 0x0110)
 #define WDT_INT_REQ		0x0008
 
-#define BRIDGE_INT_TIMER1_CLR	(~0x0004)
-
 #define IRQ_VIRT_BASE		(BRIDGE_VIRT_BASE + 0x0200)
 #define IRQ_CAUSE_LOW_OFF	0x0000
 #define IRQ_MASK_LOW_OFF	0x0004
arch/arm/mach-kirkwood/include/mach/irqs.h +13 -1
index 2bf8161..82c5984 100644
@@ -59,7 +59,19 @@
 #define IRQ_KIRKWOOD_GPIO_START	64
 #define NR_GPIO_IRQS		50
 
-#define NR_IRQS			(IRQ_KIRKWOOD_GPIO_START + NR_GPIO_IRQS)
+/*
+ * Bridge Interrupt Controller
+ */
+#define IRQ_KIRKWOOD_BRIDGE_START (IRQ_KIRKWOOD_GPIO_START + NR_GPIO_IRQS)
+#define IRQ_KIRKWOOD_BRIDGE_SELFINT   (IRQ_KIRKWOOD_BRIDGE_START + 0)
+#define IRQ_KIRKWOOD_BRIDGE_TIMER0    (IRQ_KIRKWOOD_BRIDGE_START + 1)
+#define IRQ_KIRKWOOD_BRIDGE_TIMER1    (IRQ_KIRKWOOD_BRIDGE_START + 2)
+#define IRQ_KIRKWOOD_BRIDGE_TIMERWD   (IRQ_KIRKWOOD_BRIDGE_START + 3)
+#define IRQ_KIRKWOOD_BRIDGE_ACCESSERR (IRQ_KIRKWOOD_BRIDGE_START + 4)
+#define IRQ_KIRKWOOD_BRIDGE_BIT64ERR  (IRQ_KIRKWOOD_BRIDGE_START + 5)
+#define NR_BRIDGE_IRQS          6
+
+#define NR_IRQS			(IRQ_KIRKWOOD_BRIDGE_START + NR_BRIDGE_IRQS)
 
 
 #endif
arch/arm/mach-mv78xx0/common.c +10 -2
index d0cb485..e9c9ef7 100644
@@ -25,6 +25,7 @@
 #include <plat/time.h>
 #include <plat/common.h>
 #include <plat/addr-map.h>
+#include <plat/irq.h>
 #include "common.h"
 
 static int get_tclk(void);
@@ -338,8 +339,15 @@ void __init mv78xx0_init_early(void)
 
 static void __init_refok mv78xx0_timer_init(void)
 {
-	orion_time_init(BRIDGE_VIRT_BASE, BRIDGE_INT_TIMER1_CLR,
-			IRQ_MV78XX0_TIMER_1, get_tclk());
+	/*
+	 * FIXME: MV78XX0 may not have a bridge cause register, in which case
+	 * the timer should run directly from IRQ_MV78XX0_TIMER_1
+	 */
+	if (orion_bridge_irq_init(IRQ_MV78XX0_TIMER_1,
+				  IRQ_MV78XX0_BRIDGE_START,
+				  BRIDGE_CAUSE, NULL))
+		panic("Unable to setup bridge irqs");
+	orion_time_init(IRQ_MV78XX0_BRIDGE_TIMER1, get_tclk());
 }
 
 struct sys_timer mv78xx0_timer = {
arch/arm/mach-mv78xx0/include/mach/bridge-regs.h +1 -1
index 5f03484..787bd2a 100644
@@ -20,7 +20,7 @@
 #define SYSTEM_SOFT_RESET	(BRIDGE_VIRT_BASE + 0x010c)
 #define SOFT_RESET		0x00000001
 
-#define BRIDGE_INT_TIMER1_CLR	(~0x0004)
+#define BRIDGE_CAUSE            (BRIDGE_VIRT_BASE + 0x0110)
 
 #define IRQ_VIRT_BASE		(BRIDGE_VIRT_BASE + 0x0200)
 #define IRQ_CAUSE_ERR_OFF	0x0000
arch/arm/mach-mv78xx0/include/mach/irqs.h +8 -1
index fa1d422..1d70936 100644
@@ -88,7 +88,14 @@
 #define IRQ_MV78XX0_GPIO_START	96
 #define NR_GPIO_IRQS		32
 
-#define NR_IRQS			(IRQ_MV78XX0_GPIO_START + NR_GPIO_IRQS)
+/*
+ * Bridge Interrupt Controller
+ */
+#define IRQ_MV78XX0_BRIDGE_START   (IRQ_MV78XX0_GPIO_START + NR_GPIO_IRQS)
+#define IRQ_MV78XX0_BRIDGE_TIMER1  (IRQ_MV78XX0_BRIDGE_START + 2)
+#define NR_BRIDGE_IRQS             6
+
+#define NR_IRQS			(IRQ_MV78XX0_BRIDGE_START + NR_BRIDGE_IRQS)
 
 
 #endif
arch/arm/mach-orion5x/common.c +6 -2
index b3eb3da..c95c6c1 100644
@@ -35,6 +35,7 @@
 #include <plat/time.h>
 #include <plat/common.h>
 #include <plat/addr-map.h>
+#include <plat/irq.h>
 #include "common.h"
 
 /*****************************************************************************
@@ -221,8 +222,11 @@ static void __init orion5x_timer_init(void)
 {
 	orion5x_tclk = orion5x_find_tclk();
 
-	orion_time_init(ORION5X_BRIDGE_VIRT_BASE, BRIDGE_INT_TIMER1_CLR,
-			IRQ_ORION5X_BRIDGE, orion5x_tclk);
+	if (orion_bridge_irq_init(IRQ_ORION5X_BRIDGE,
+				  IRQ_ORION5X_BRIDGE_START,
+				  BRIDGE_CAUSE, NULL))
+		panic("Unable to setup bridge irqs");
+	orion_time_init(IRQ_ORION5X_BRIDGE_TIMER1, orion5x_tclk);
 }
 
 struct sys_timer orion5x_timer = {
arch/arm/mach-orion5x/include/mach/bridge-regs.h +0 -2
index 461fd69..0847182 100644
@@ -28,8 +28,6 @@
 
 #define WDT_INT_REQ		0x0008
 
-#define BRIDGE_INT_TIMER1_CLR	(~0x0004)
-
 #define MAIN_IRQ_CAUSE		(ORION5X_BRIDGE_VIRT_BASE + 0x200)
 
 #define MAIN_IRQ_MASK		(ORION5X_BRIDGE_VIRT_BASE + 0x204)
arch/arm/mach-orion5x/include/mach/irqs.h +8 -1
index a6fa9d8..b8d53e6 100644
@@ -54,7 +54,14 @@
 #define IRQ_ORION5X_GPIO_START	32
 #define NR_GPIO_IRQS		32
 
-#define NR_IRQS			(IRQ_ORION5X_GPIO_START + NR_GPIO_IRQS)
+/*
+ * Bridge Interrupt Controller
+ */
+#define IRQ_ORION5X_BRIDGE_START   (IRQ_ORION5X_GPIO_START + NR_GPIO_IRQS)
+#define IRQ_ORION5X_BRIDGE_TIMER1  (IRQ_ORION5X_BRIDGE_START + 2)
+#define NR_BRIDGE_IRQS          6
+
+#define NR_IRQS			(IRQ_ORION5X_BRIDGE_START + NR_BRIDGE_IRQS)
 
 
 #endif
arch/arm/plat-orion/include/plat/irq.h +3 -0
index 50547e4..d86ae85 100644
@@ -12,5 +12,8 @@
 #define __PLAT_IRQ_H
 
 void orion_irq_init(unsigned int irq_start, void __iomem *maskaddr);
+int __init orion_bridge_irq_init(unsigned int bridge_irq, int irq_start,
+				 void __iomem *causeaddr,
+				 struct device_node *np);
 void __init orion_dt_init_irq(void);
 #endif
arch/arm/plat-orion/include/plat/time.h +1 -3
index 07527e4..c5ccc0a 100644
@@ -13,8 +13,6 @@
 
 void orion_time_set_base(void __iomem *timer_base);
 
-void orion_time_init(void __iomem *bridge_base, u32 bridge_timer1_clr_mask,
-		     unsigned int irq, unsigned int tclk);
-
+void orion_time_init(unsigned int irq, unsigned int tclk);
 
 #endif
arch/arm/plat-orion/irq.c +70 -0

82 lines not on this page · raw message

arch/arm/plat-orion/time.c +9 -37

107 lines not on this page · raw message

Signature · 1 line
1.7.5.4
#1 lore raw

PATCH 2/3 ARM: Orion: Bind the orion bridge interrupt controller through DT

This adds the common DT code and board support for kirkwood and dove

- Add the marvell,orion-bridge-intc DT node to the DTSI file
- Make the call to orion_bridge_irq_init happen only in the non-DT case

---
 .../devicetree/bindings/arm/mrvl/intc.txt          |   21 ++++++++++++++++++++
 arch/arm/boot/dts/dove.dtsi                        |   10 +++++++++
 arch/arm/boot/dts/kirkwood.dtsi                    |   12 +++++++++++
 arch/arm/mach-dove/common.c                        |    4 ---
 arch/arm/mach-dove/irq.c                           |    5 ++++
 arch/arm/mach-kirkwood/common.c                    |    4 ---
 arch/arm/mach-kirkwood/irq.c                       |    5 ++++
 arch/arm/plat-orion/irq.c                          |   20 +++++++++++++++++++
 8 files changed, 73 insertions(+), 8 deletions(-)
Documentation/devicetree/bindings/arm/mrvl/intc.txt +21 -0
index 8b53273..cf633f1 100644
@@ -58,3 +58,24 @@ Example:
                 reg = <0xfed20204 0x04>,
 		      <0xfed20214 0x04>;
         };
+
+* Marvell Orion Bridge Interrupt controller
+
+Required properties
+- compatible :  Should be "marvell,orion-bridge-intc".
+- #interrupt-cells: Specifies the number of cells needed to encode an
+  interrupt source. Supported value is <1>.
+- interrupt-controller : Declare this node to be an interrupt controller.
+- interrupts: The interrupt number the bridge is attached to on the main
+              controller.
+- reg : Interrupt cause address.
+
+Example:
+
+	bridge_intc: bridge_intc at 20110 {
+		compatible = "marvell,orion-bridge-intc";
+		interrupt-controller;
+		#interrupt-cells = <1>;
+		interrupts = <1>;
+		reg = <0x20110 0x08>;
+        };
arch/arm/boot/dts/dove.dtsi +10 -0
index 5a00022..b726ba8 100644
@@ -67,6 +67,8 @@
 			status = "disabled";
 		};
 
+		/* The interrupt controller stanzas are in an
+		 * order that matches irqs.h */
 		gpio0: gpio at d0400 {
 			compatible = "marvell,orion-gpio";
 			#gpio-cells = <2>;
@@ -93,6 +95,14 @@
 			ngpio = <8>;
 		};
 
+		bridge_intc: bridge_intc at 20110 {
+			compatible = "marvell,orion-bridge-intc";
+			interrupt-controller;
+			#interrupt-cells = <1>;
+			interrupts = <0>;
+			reg = <0x20110 0x08>;
+		};
+
 		spi0: spi at 10600 {
 			compatible = "marvell,orion-spi";
 			#address-cells = <1>;
arch/arm/boot/dts/kirkwood.dtsi +12 -0
index 4e5b815..854e532 100644
@@ -19,6 +19,8 @@
 		#address-cells = <1>;
 		#size-cells = <1>;
 
+		/* The interrupt controller stanzas are in an
+		 * order that matches irqs.h */
 		gpio0: gpio at 10100 {
 			compatible = "marvell,orion-gpio";
 			#gpio-cells = <2>;
@@ -37,6 +39,14 @@
 			interrupts = <39>, <40>, <41>;
 		};
 
+		bridge_intc: bridge_intc at 20110 {
+			compatible = "marvell,orion-bridge-intc";
+			interrupt-controller;
+			#interrupt-cells = <1>;
+			interrupts = <1>;
+			reg = <0x20110 0x08>;
+		};
+
 		serial at 12000 {
 			compatible = "ns16550a";
 			reg = <0x12000 0x100>;
@@ -73,6 +83,8 @@
 
 		wdt at 20300 {
 			compatible = "marvell,orion-wdt";
+			interrupt-parent = <&bridge_intc>;
+			interrupts = <3>;
 			reg = <0x20300 0x28>;
 			status = "okay";
 		};
arch/arm/mach-dove/common.c +0 -4
index 6bad21b..b570211 100644
@@ -243,10 +243,6 @@ static int __init dove_find_tclk(void)
 static void __init dove_timer_init(void)
 {
 	dove_tclk = dove_find_tclk();
-	if (orion_bridge_irq_init(IRQ_DOVE_BRIDGE,
-				  IRQ_DOVE_BRIDGE_START,
-				  BRIDGE_CAUSE, NULL))
-		panic("Unable to setup bridge irqs");
 	orion_time_init(IRQ_DOVE_BRIDGE_TIMER1, dove_tclk);
 }
 
arch/arm/mach-dove/irq.c +5 -0
index bc4344a..bcb193f 100644
@@ -139,4 +139,9 @@ void __init dove_init_irq(void)
 		set_irq_flags(i, IRQF_VALID);
 	}
 	irq_set_chained_handler(IRQ_DOVE_PMU, pmu_irq_handler);
+
+	if (orion_bridge_irq_init(IRQ_DOVE_BRIDGE,
+				  IRQ_DOVE_BRIDGE_START,
+				  BRIDGE_CAUSE, NULL))
+		panic("Unable to setup bridge irqs");
 }
arch/arm/mach-kirkwood/common.c +0 -4
index ccd3ed5..7398f8b 100644
@@ -535,10 +535,6 @@ static void __init kirkwood_timer_init(void)
 {
 	kirkwood_tclk = kirkwood_find_tclk();
 
-	if (orion_bridge_irq_init(IRQ_KIRKWOOD_BRIDGE,
-				  IRQ_KIRKWOOD_BRIDGE_START,
-				  BRIDGE_CAUSE, NULL))
-		panic("Unable to setup bridge irqs");
 	orion_time_init(IRQ_KIRKWOOD_BRIDGE_TIMER1, kirkwood_tclk);
 }
 
arch/arm/mach-kirkwood/irq.c +5 -0
index 8847035..a1388ef 100644
@@ -41,4 +41,9 @@ void __init kirkwood_init_irq(void)
 			IRQ_KIRKWOOD_GPIO_START, gpio0_irqs);
 	orion_gpio_init(NULL, 32, 18, GPIO_HIGH_VIRT_BASE, 0,
 			IRQ_KIRKWOOD_GPIO_START + 32, gpio1_irqs);
+
+	if (orion_bridge_irq_init(IRQ_KIRKWOOD_BRIDGE,
+				  IRQ_KIRKWOOD_BRIDGE_START,
+				  BRIDGE_CAUSE, NULL))
+		panic("Unable to setup bridge irqs");
 }
arch/arm/plat-orion/irq.c +20 -0
index a903012..2dcccda 100644
@@ -131,9 +131,29 @@ static int __init orion_add_irq_domain(struct device_node *np,
 	return 0;
 }
 
+static int __init orion_add_bridge_irq_domain(
+	struct device_node *np, struct device_node *interrupt_parent)
+{
+	void __iomem *base;
+	int bridge_irq;
+
+	base = of_iomap(np, 0);
+	if (!base)
+		return -ENODEV;
+	bridge_irq = irq_of_parse_and_map(np, 0);
+	/* FIXME: irq_of_parse_and_map returns 0 on error, but on Dove the
+	 * bridge IRQ is 0.
+	if (!bridge_irq)
+		return -ENODEV;*/
+
+	return orion_bridge_irq_init(bridge_irq, -1, base, np);
+}
+
 static const struct of_device_id orion_irq_match[] = {
 	{ .compatible = "marvell,orion-intc",
 	  .data = orion_add_irq_domain, },
+	{ .compatible = "marvell,orion-bridge-intc",
+	  .data = orion_add_bridge_irq_domain, },
 	{},
 };
 
Signature · 1 line
1.7.5.4
maintainer
#2 lore raw

PATCH 2/3 ARM: Orion: Bind the orion bridge interrupt controller through DT

Quoted 184 lines · Jason Gunthorpe

This adds the common DT code and board support for kirkwood and dove

- Add the marvell,orion-bridge-intc DT node to the DTSI file
- Make the call to orion_bridge_irq_init happen only in the non-DT case

---
 .../devicetree/bindings/arm/mrvl/intc.txt          |   21 ++++++++++++++++++++
 arch/arm/boot/dts/dove.dtsi                        |   10 +++++++++
 arch/arm/boot/dts/kirkwood.dtsi                    |   12 +++++++++++
 arch/arm/mach-dove/common.c                        |    4 ---
 arch/arm/mach-dove/irq.c                           |    5 ++++
 arch/arm/mach-kirkwood/common.c                    |    4 ---
 arch/arm/mach-kirkwood/irq.c                       |    5 ++++
 arch/arm/plat-orion/irq.c                          |   20 +++++++++++++++++++
 8 files changed, 73 insertions(+), 8 deletions(-)
Documentation/devicetree/bindings/arm/mrvl/intc.txt +21 -0
index 8b53273..cf633f1 100644
@@ -58,3 +58,24 @@ Example:
                 reg = <0xfed20204 0x04>,
 		      <0xfed20214 0x04>;
         };
+
+* Marvell Orion Bridge Interrupt controller
+
+Required properties
+- compatible :  Should be "marvell,orion-bridge-intc".
+- #interrupt-cells: Specifies the number of cells needed to encode an
+  interrupt source. Supported value is <1>.
+- interrupt-controller : Declare this node to be an interrupt controller.
+- interrupts: The interrupt number the bridge is attached to on the main
+              controller.
+- reg : Interrupt cause address.
+
+Example:
+
+	bridge_intc: bridge_intc at 20110 {
+		compatible = "marvell,orion-bridge-intc";
+		interrupt-controller;
+		#interrupt-cells = <1>;
+		interrupts = <1>;
+		reg = <0x20110 0x08>;
+        };
arch/arm/boot/dts/dove.dtsi +10 -0
index 5a00022..b726ba8 100644
@@ -67,6 +67,8 @@
 			status = "disabled";
 		};
 
+		/* The interrupt controller stanzas are in an
+		 * order that matches irqs.h */
 		gpio0: gpio at d0400 {
 			compatible = "marvell,orion-gpio";
 			#gpio-cells = <2>;
@@ -93,6 +95,14 @@
 			ngpio = <8>;
 		};
 
+		bridge_intc: bridge_intc at 20110 {
+			compatible = "marvell,orion-bridge-intc";
+			interrupt-controller;
+			#interrupt-cells = <1>;
+			interrupts = <0>;
+			reg = <0x20110 0x08>;
+		};
+
 		spi0: spi at 10600 {
 			compatible = "marvell,orion-spi";
 			#address-cells = <1>;
arch/arm/boot/dts/kirkwood.dtsi +12 -0
index 4e5b815..854e532 100644
@@ -19,6 +19,8 @@
 		#address-cells = <1>;
 		#size-cells = <1>;
 
+		/* The interrupt controller stanzas are in an
+		 * order that matches irqs.h */
 		gpio0: gpio at 10100 {
 			compatible = "marvell,orion-gpio";
 			#gpio-cells = <2>;
@@ -37,6 +39,14 @@
 			interrupts = <39>, <40>, <41>;
 		};
 
+		bridge_intc: bridge_intc at 20110 {
+			compatible = "marvell,orion-bridge-intc";
+			interrupt-controller;
+			#interrupt-cells = <1>;
+			interrupts = <1>;
+			reg = <0x20110 0x08>;
+		};
+
 		serial at 12000 {
 			compatible = "ns16550a";
 			reg = <0x12000 0x100>;
@@ -73,6 +83,8 @@
 
 		wdt at 20300 {
 			compatible = "marvell,orion-wdt";
+			interrupt-parent = <&bridge_intc>;
+			interrupts = <3>;
 			reg = <0x20300 0x28>;
 			status = "okay";
 		};
arch/arm/mach-dove/common.c +0 -4
index 6bad21b..b570211 100644
@@ -243,10 +243,6 @@ static int __init dove_find_tclk(void)
 static void __init dove_timer_init(void)
 {
 	dove_tclk = dove_find_tclk();
-	if (orion_bridge_irq_init(IRQ_DOVE_BRIDGE,
-				  IRQ_DOVE_BRIDGE_START,
-				  BRIDGE_CAUSE, NULL))
-		panic("Unable to setup bridge irqs");
 	orion_time_init(IRQ_DOVE_BRIDGE_TIMER1, dove_tclk);
 }
 
arch/arm/mach-dove/irq.c +5 -0
index bc4344a..bcb193f 100644
@@ -139,4 +139,9 @@ void __init dove_init_irq(void)
 		set_irq_flags(i, IRQF_VALID);
 	}
 	irq_set_chained_handler(IRQ_DOVE_PMU, pmu_irq_handler);
+
+	if (orion_bridge_irq_init(IRQ_DOVE_BRIDGE,
+				  IRQ_DOVE_BRIDGE_START,
+				  BRIDGE_CAUSE, NULL))
+		panic("Unable to setup bridge irqs");
 }
arch/arm/mach-kirkwood/common.c +0 -4
index ccd3ed5..7398f8b 100644
@@ -535,10 +535,6 @@ static void __init kirkwood_timer_init(void)
 {
 	kirkwood_tclk = kirkwood_find_tclk();
 
-	if (orion_bridge_irq_init(IRQ_KIRKWOOD_BRIDGE,
-				  IRQ_KIRKWOOD_BRIDGE_START,
-				  BRIDGE_CAUSE, NULL))
-		panic("Unable to setup bridge irqs");
 	orion_time_init(IRQ_KIRKWOOD_BRIDGE_TIMER1, kirkwood_tclk);
 }
 
arch/arm/mach-kirkwood/irq.c +5 -0
index 8847035..a1388ef 100644
@@ -41,4 +41,9 @@ void __init kirkwood_init_irq(void)
 			IRQ_KIRKWOOD_GPIO_START, gpio0_irqs);
 	orion_gpio_init(NULL, 32, 18, GPIO_HIGH_VIRT_BASE, 0,
 			IRQ_KIRKWOOD_GPIO_START + 32, gpio1_irqs);
+
+	if (orion_bridge_irq_init(IRQ_KIRKWOOD_BRIDGE,
+				  IRQ_KIRKWOOD_BRIDGE_START,
+				  BRIDGE_CAUSE, NULL))
+		panic("Unable to setup bridge irqs");
 }
arch/arm/plat-orion/irq.c +6 -0
index a903012..2dcccda 100644
@@ -131,9 +131,29 @@ static int __init orion_add_irq_domain(struct device_node *np,
 	return 0;
 }
 
+static int __init orion_add_bridge_irq_domain(
+	struct device_node *np, struct device_node *interrupt_parent)
+{
+	void __iomem *base;
+	int bridge_irq;
+

arch/arm/plat-orion/irq.c static int __init orion_add_irq_domain(struct device_node *np, · line 149

Quoted 10 lines
arch/arm/plat-orion/irq.c +10 -0
+	base = of_iomap(np, 0);
+	if (!base)
+		return -ENODEV;
+	bridge_irq = irq_of_parse_and_map(np, 0);
+	/* FIXME: irq_of_parse_and_map returns 0 on error, but on Dove the
+	 * bridge IRQ is 0.
+	if (!bridge_irq)
+		return -ENODEV;*/
+
+	return orion_bridge_irq_init(bridge_irq, -1, base, np);

Hi Jason

So does this mean for Dove it will currently always fail?

Thanks
Andrew

#3 lore raw

PATCH 2/3 ARM: Orion: Bind the orion bridge interrupt controller through DT

Quoted 9 lines

arch/arm/plat-orion/irq.c static int __init orion_add_irq_domain(struct device_node *np, · line 149

Quoted 7 lines
arch/arm/plat-orion/irq.c +7 -0
+	bridge_irq = irq_of_parse_and_map(np, 0);
+	/* FIXME: irq_of_parse_and_map returns 0 on error, but on Dove the
+	 * bridge IRQ is 0.
+	if (!bridge_irq)
+		return -ENODEV;*/
+
+	return orion_bridge_irq_init(bridge_irq, -1, base, np);

So does this mean for Dove it will currently always fail?

I guess that is hard to read without syntax hi-lighting, the 'if' is also commented out.

I was hopefull it would work as is, but looking deeper at irq_of_parse_and_map and its call tree makes me doubtfull now..

Fixing irq_of_parse_and_map is way to big a job for me :(

What to do from here? Add a dummy 0 interrupt to dove? Take dove out of this patch series?

Jason

maintainer
#4 lore raw

PATCH 2/3 ARM: Orion: Bind the orion bridge interrupt controller through DT

Quoted 10 lines · Jason Gunthorpe
Quoted 9 lines

arch/arm/plat-orion/irq.c static int __init orion_add_irq_domain(struct device_node *np, · line 149

Quoted 7 lines
arch/arm/plat-orion/irq.c +7 -0
+	bridge_irq = irq_of_parse_and_map(np, 0);
+	/* FIXME: irq_of_parse_and_map returns 0 on error, but on Dove the
+	 * bridge IRQ is 0.
+	if (!bridge_irq)
+		return -ENODEV;*/
+
+	return orion_bridge_irq_init(bridge_irq, -1, base, np);

So does this mean for Dove it will currently always fail?

Quoted 7 lines

I guess that is hard to read without syntax hi-lighting, the 'if' is also commented out.

I was hopefull it would work as is, but looking deeper at irq_of_parse_and_map and its call tree makes me doubtfull now..

Fixing irq_of_parse_and_map is way to big a job for me :(

Hi Jason

https://lwn.net/Articles/470820/

I don't think its fixable.

Quoted 2 lines

What to do from here? Add a dummy 0 interrupt to dove? Take dove out of this patch series?

We need to see how other machine remap 0 to some other value and implement that for Dove.

Andrew

#5 lore raw

PATCH 2/3 ARM: Orion: Bind the orion bridge interrupt controller through DT

Quoted 17 lines · Andrew Lunn
Quoted 16 lines · Jason Gunthorpe
Quoted 9 lines

arch/arm/plat-orion/irq.c static int __init orion_add_irq_domain(struct device_node *np, · line 149

Quoted 7 lines
arch/arm/plat-orion/irq.c +7 -0
+	bridge_irq = irq_of_parse_and_map(np, 0);
+	/* FIXME: irq_of_parse_and_map returns 0 on error, but on Dove the
+	 * bridge IRQ is 0.
+	if (!bridge_irq)
+		return -ENODEV;*/
+
+	return orion_bridge_irq_init(bridge_irq, -1, base, np);

So does this mean for Dove it will currently always fail?

I guess that is hard to read without syntax hi-lighting, the 'if' is also commented out.

I was hopefull it would work as is, but looking deeper at irq_of_parse_and_map and its call tree makes me doubtfull now..

Quoted 7 lines
Quoted 1 line

Fixing irq_of_parse_and_map is way to big a job for me :(

Hi Jason

https://lwn.net/Articles/470820/

I don't think its fixable.

Oh right. That.

Looking at this some more, I think it should work, but not for very good reasons.. irq_of_parse_and_map will return 0 on dove. It returns 0 because it is going through its error paths because it saw a 0 deep inside, but it still returns 0.

orion_bridge_irq_init will work with 0 as a bridge_irq, we know this because the timer code was using those code paths for a long time

Quoted 2 lines

We need to see how other machine remap 0 to some other value and implement that for Dove.

It looks like it is straightforward to adjust Dove's get_irqnr_and_base to add 1 to all the interrupt numbers, adjust irqs.h to add 1, and adjust the irq setup. There would be no performance penalty to doing this, but testing would be need to be sure 100% of changes were made. If the above works it would be better to do that sort of change after, or maybe after the non-DT code is purged...

Kirkwood is already OK WRT the 0 IRQ, it is handled internally to get_irqnr_and_base.

So, I will suggest to please test on dove as-is...

Did the other patches look OK?

I threw together an interrupt panic patch for the wdt, and that works OK as well, so the kirkwood configuration is tested with this series.

116:    4995890  orion_bridge  orion_tick
117:          0  orion_bridge  orion_wdt

Thanks,
Jason

#6 lore raw

PATCH 2/3 ARM: Orion: Bind the orion bridge interrupt controller through DT

Sebastian,

Quoted 47 lines · Jason Gunthorpe
Quoted 17 lines · Andrew Lunn
Quoted 16 lines · Jason Gunthorpe
Quoted 9 lines

arch/arm/plat-orion/irq.c static int __init orion_add_irq_domain(struct device_node *np, · line 149

Quoted 7 lines
arch/arm/plat-orion/irq.c +7 -0
+	bridge_irq = irq_of_parse_and_map(np, 0);
+	/* FIXME: irq_of_parse_and_map returns 0 on error, but on Dove the
+	 * bridge IRQ is 0.
+	if (!bridge_irq)
+		return -ENODEV;*/
+
+	return orion_bridge_irq_init(bridge_irq, -1, base, np);

So does this mean for Dove it will currently always fail?

I guess that is hard to read without syntax hi-lighting, the 'if' is also commented out.

I was hopefull it would work as is, but looking deeper at irq_of_parse_and_map and its call tree makes me doubtfull now..

Quoted 7 lines
Quoted 1 line

Fixing irq_of_parse_and_map is way to big a job for me :(

Hi Jason

https://lwn.net/Articles/470820/

I don't think its fixable.

Oh right. That.

Looking at this some more, I think it should work, but not for very good reasons.. irq_of_parse_and_map will return 0 on dove. It returns 0 because it is going through its error paths because it saw a 0 deep inside, but it still returns 0.

orion_bridge_irq_init will work with 0 as a bridge_irq, we know this because the timer code was using those code paths for a long time

Quoted 2 lines

We need to see how other machine remap 0 to some other value and implement that for Dove.

It looks like it is straightforward to adjust Dove's get_irqnr_and_base to add 1 to all the interrupt numbers, adjust irqs.h to add 1, and adjust the irq setup. There would be no performance penalty to doing this, but testing would be need to be sure 100% of changes were made. If the above works it would be better to do that sort of change after, or maybe after the non-DT code is purged...

Quoted 4 lines

Kirkwood is already OK WRT the 0 IRQ, it is handled internally to get_irqnr_and_base.

So, I will suggest to please test on dove as-is...

Did you have a chance to test this on dove?

thx,

Jason.

maintainer
#7 lore raw

PATCH 2/3 ARM: Orion: Bind the orion bridge interrupt controller through DT

Quoted 50 lines · Jason Cooper

Sebastian,

Quoted 47 lines · Jason Gunthorpe
Quoted 17 lines · Andrew Lunn
Quoted 16 lines · Jason Gunthorpe
Quoted 9 lines

arch/arm/plat-orion/irq.c static int __init orion_add_irq_domain(struct device_node *np, · line 149

Quoted 7 lines
arch/arm/plat-orion/irq.c +7 -0
+	bridge_irq = irq_of_parse_and_map(np, 0);
+	/* FIXME: irq_of_parse_and_map returns 0 on error, but on Dove the
+	 * bridge IRQ is 0.
+	if (!bridge_irq)
+		return -ENODEV;*/
+
+	return orion_bridge_irq_init(bridge_irq, -1, base, np);

So does this mean for Dove it will currently always fail?

I guess that is hard to read without syntax hi-lighting, the 'if' is also commented out.

I was hopefull it would work as is, but looking deeper at irq_of_parse_and_map and its call tree makes me doubtfull now..

Quoted 7 lines
Quoted 1 line

Fixing irq_of_parse_and_map is way to big a job for me :(

Hi Jason

https://lwn.net/Articles/470820/

I don't think its fixable.

Oh right. That.

Looking at this some more, I think it should work, but not for very good reasons.. irq_of_parse_and_map will return 0 on dove. It returns 0 because it is going through its error paths because it saw a 0 deep inside, but it still returns 0.

orion_bridge_irq_init will work with 0 as a bridge_irq, we know this because the timer code was using those code paths for a long time

Quoted 2 lines

We need to see how other machine remap 0 to some other value and implement that for Dove.

It looks like it is straightforward to adjust Dove's get_irqnr_and_base to add 1 to all the interrupt numbers, adjust irqs.h to add 1, and adjust the irq setup. There would be no performance penalty to doing this, but testing would be need to be sure 100% of changes were made. If the above works it would be better to do that sort of change after, or maybe after the non-DT code is purged...

Quoted 6 lines
Quoted 4 lines

Kirkwood is already OK WRT the 0 IRQ, it is handled internally to get_irqnr_and_base.

So, I will suggest to please test on dove as-is...

Did you have a chance to test this on dove?

Hi Jason

We discussed this a little and I prefer Sebastians implementation.

Sebastian, do you have time to work on your code and get it ready?

Thanks
Andrew

#8 lore raw

PATCH 2/3 ARM: Orion: Bind the orion bridge interrupt controller through DT

Quoted 56 lines · Andrew Lunn
Quoted 55 lines · Jason Cooper

Sebastian,

Quoted 51 lines · Jason Gunthorpe
Quoted 17 lines · Andrew Lunn
Quoted 16 lines · Jason Gunthorpe
Quoted 9 lines

Review

Quoted 7 lines
(quoted diff) +7 -0
+	bridge_irq = irq_of_parse_and_map(np, 0);
+	/* FIXME: irq_of_parse_and_map returns 0 on error, but on Dove the
+	 * bridge IRQ is 0.
+	if (!bridge_irq)
+		return -ENODEV;*/
+
+	return orion_bridge_irq_init(bridge_irq, -1, base, np);

So does this mean for Dove it will currently always fail?

I guess that is hard to read without syntax hi-lighting, the 'if' is also commented out.

I was hopefull it would work as is, but looking deeper at irq_of_parse_and_map and its call tree makes me doubtfull now..

Quoted 7 lines
Quoted 1 line

Fixing irq_of_parse_and_map is way to big a job for me :(

Hi Jason

https://lwn.net/Articles/470820/

I don't think its fixable.

Oh right. That.

Looking at this some more, I think it should work, but not for very good reasons.. irq_of_parse_and_map will return 0 on dove. It returns 0 because it is going through its error paths because it saw a 0 deep inside, but it still returns 0.

orion_bridge_irq_init will work with 0 as a bridge_irq, we know this because the timer code was using those code paths for a long time

Quoted 2 lines

We need to see how other machine remap 0 to some other value and implement that for Dove.

It looks like it is straightforward to adjust Dove's get_irqnr_and_base to add 1 to all the interrupt numbers, adjust irqs.h to add 1, and adjust the irq setup. There would be no performance penalty to doing this, but testing would be need to be sure 100% of changes were made. If the above works it would be better to do that sort of change after, or maybe after the non-DT code is purged...

Kirkwood is already OK WRT the 0 IRQ, it is handled internally to get_irqnr_and_base.

So, I will suggest to please test on dove as-is...

Quoted 7 lines
Quoted 1 line

Did you have a chance to test this on dove?

Hi Jason

We discussed this a little and I prefer Sebastians implementation.

Sebastian, do you have time to work on your code and get it ready?

Jason, Andrew,

we chose to jump to irqchip instead of fixing old code. I thought Jason Gunthorpe volunteered to get it ready? Moving to irqchip also requires clksrc-orion or reimplementing orion into clksrc-mvebu.

I can do it but it depends on when it should be ready?

Sebastian

#9 lore raw

PATCH 2/3 ARM: Orion: Bind the orion bridge interrupt controller through DT

Quoted 11 lines · Sebastian Hesselbarth
Quoted 11 lines
Quoted 6 lines
Quoted 4 lines

Kirkwood is already OK WRT the 0 IRQ, it is handled internally to get_irqnr_and_base.

So, I will suggest to please test on dove as-is...

Did you have a chance to test this on dove?

Hi Jason

We discussed this a little and I prefer Sebastians implementation.

Quoted 7 lines
Quoted 1 line

Sebastian, do you have time to work on your code and get it ready?

Jason, Andrew,

we chose to jump to irqchip instead of fixing old code. I thought Jason Gunthorpe volunteered to get it ready? Moving to irqchip also requires clksrc-orion or reimplementing orion into clksrc-mvebu.

I looked into it, but at the time there was so much churn going into the merge window that it was too much to tackle, then there was/is holidays for me :) Feburary would probably be the soonest I could actually get my systems running the latest kernels and do any work on this subject.

The drivers Sebastian posted looked close to what I posted, a few things like edge interrupts should be copied over from my patches though..

The irqchip can be done prior to the timer, if the bridge cause decoding is left disabled in the DT then the existing timer should still work..

There is a bunch of prep stuff that may still be pending:
- Fixup remaining drivers (usb? ethernet?) to have DT bindings and get the IRQ number through DT
- Fixup the GPIO driver to dynamically allocate IRQs rather than having a hardwired start (did the pinctl change fix this?)
- Separate the non-DT and DT IRQ related stuff, the IRQ numbering changes with the irqchip driver's dynamic allocation. This solves the 0 IRQ problem..
- Remove non-DT code? Andrew was talking about this..

Jason

#10 lore raw

PATCH 2/3 ARM: Orion: Bind the orion bridge interrupt controller through DT

Jason,

Quoted 3 lines · Jason Gunthorpe

There is a bunch of prep stuff that may still be pending:
- Fixup remaining drivers (usb? ethernet?) to have DT bindings and get the IRQ number through DT

any chance I could get you post your changes to the ethernet driver (DT bindings)? iirc, you said you had based them off of Ian Molton's work. Even if you posted them RFC, it'd be a good place to start from, reignite conversation and so forth.

thx,

Jason.

#11 lore raw

PATCH 2/3 ARM: Orion: Bind the orion bridge interrupt controller through DT

Quoted 11 lines · Jason Cooper

Jason,

Quoted 3 lines · Jason Gunthorpe

There is a bunch of prep stuff that may still be pending:
- Fixup remaining drivers (usb? ethernet?) to have DT bindings and get the IRQ number through DT

any chance I could get you post your changes to the ethernet driver (DT bindings)? iirc, you said you had based them off of Ian Molton's work. Even if you posted them RFC, it'd be a good place to start from, reignite conversation and so forth.

I've attached the main mv dt patch as a MIME, sorry for the awkwardness, I am travelling and won't be available... Please feel free to re-post/alter as necessary. As I said before, I'm not happy with it because it doesn't follow the standard convention for MDIO phys.

Jason
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-mv643xx.c-Add-basic-device-tree-support.patch
Type: text/x-diff
Size: 8357 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20130110/4e6ac12c/attachment-0001.bin>

#12 lore raw

PATCH 2/3 ARM: Orion: Bind the orion bridge interrupt controller through DT

Dear Jason Gunthorpe,

Quoted 5 lines · Jason Gunthorpe

I've attached the main mv dt patch as a MIME, sorry for the awkwardness, I am travelling and won't be available... Please feel free to re-post/alter as necessary. As I said before, I'm not happy with it because it doesn't follow the standard convention for MDIO phys.

The MDIO registers for the mv643xx_eth hardware are the same as the ones for the mvneta hardware. Therefore, I've splitted this into the mvmdio driver (available in mainline since 3.8, drivers/net/ethernet/marvell). This allows to have a nicely separated driver for the MDIO interface.

My plan was ultimately to modify the mv643xx_eth driver to use the mvmdio driver, and then do a nice DT binding on top of that.

Does this sounds like a good plan?

Best regards,

Thomas

Signature · 4 lines
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
#13 lore raw

PATCH 2/3 ARM: Orion: Bind the orion bridge interrupt controller through DT

Quoted 16 lines · Thomas Petazzoni

Dear Jason Gunthorpe,

Quoted 5 lines · Jason Gunthorpe

I've attached the main mv dt patch as a MIME, sorry for the awkwardness, I am travelling and won't be available... Please feel free to re-post/alter as necessary. As I said before, I'm not happy with it because it doesn't follow the standard convention for MDIO phys.

The MDIO registers for the mv643xx_eth hardware are the same as the ones for the mvneta hardware. Therefore, I've splitted this into the mvmdio driver (available in mainline since 3.8, drivers/net/ethernet/marvell). This allows to have a nicely separated driver for the MDIO interface.

Quoted 4 lines

My plan was ultimately to modify the mv643xx_eth driver to use the mvmdio driver, and then do a nice DT binding on top of that.

Does this sounds like a good plan?

I like it. If you haven't already, please review the thread at

http://www.spinics.net/lists/arm-kernel/msg186742.html

to see some of the concerns already raised.

thx,

Jason.

#14 lore raw

PATCH 3/3 ARM: Orion: Bind the orion timer through DT

In reply to Jason Gunthorpe

This adds the common DT code and board support for kirkwood and dove

- Add the marvell,orion-timer DT node to the DTSI file
- Adjust the call paths for dove/kirkwood_timer_init so it only happens on non-dt
- Eliminate redundant logging calls of kirkwood_tclk for simplicity. These days the tclk frequency is logged here:
sched_clock: 32 bits at 200MHz, resolution 5ns, wraps every 21474ms
- The DT stanza was choosen to simplify future merging with time-armada-370-xp.c

---
 arch/arm/boot/dts/dove.dtsi             |    8 ++++++
 arch/arm/boot/dts/kirkwood-dns320.dts   |    3 ++
 arch/arm/boot/dts/kirkwood-lschlv2.dts  |    3 ++
 arch/arm/boot/dts/kirkwood.dtsi         |    9 ++++++
 arch/arm/mach-dove/common.c             |   30 +++++++++++-----------
 arch/arm/mach-kirkwood/board-dt.c       |   10 ++++++-
 arch/arm/mach-kirkwood/common.c         |   42 ++++++++++++++-----------------
 arch/arm/mach-kirkwood/common.h         |    1 -
 arch/arm/plat-orion/include/plat/time.h |    1 +
 arch/arm/plat-orion/time.c              |   32 +++++++++++++++++++++++
 10 files changed, 98 insertions(+), 41 deletions(-)
arch/arm/boot/dts/dove.dtsi +8 -0
index b726ba8..da6539b 100644
@@ -31,6 +31,14 @@
 			reg = <0x20204 0x04>, <0x20214 0x04>;
 		};
 
+		timer at 20300 {
+			compatible = "marvell,orion-timer";
+			reg = <0x20300 0x20>;
+			interrupt-parent = <&bridge_intc>;
+			interrupts = <1>, <2>;
+			clock-frequency = <166666667>;
+                };
+
 		uart0: serial at 12000 {
 			compatible = "ns16550a";
 			reg = <0x12000 0x100>;
arch/arm/boot/dts/kirkwood-dns320.dts +3 -0
index 5bb0bf3..5bffd7c 100644
@@ -41,6 +41,9 @@
 	};
 
 	ocp at f1000000 {
+		timer at 20300 {
+			clock-frequency = <166666667>;
+		};
 		serial at 12000 {
 			clock-frequency = <166666667>;
 			status = "okay";
arch/arm/boot/dts/kirkwood-lschlv2.dts +3 -0
index 9510c9e..3b68d92 100644
@@ -12,6 +12,9 @@
 	};
 
 	ocp at f1000000 {
+		timer at 20300 {
+			clock-frequency = <166666667>;
+		};
 		serial at 12000 {
 			clock-frequency = <166666667>;
 			status = "okay";
arch/arm/boot/dts/kirkwood.dtsi +9 -0
index 854e532..278f8ac 100644
@@ -47,6 +47,15 @@
 			reg = <0x20110 0x08>;
 		};
 
+		timer at 20300 {
+			compatible = "marvell,orion-timer";
+			reg = <0x20300 0x20>;
+			interrupt-parent = <&bridge_intc>;
+			interrupts = <1>, <2>;
+			/* override clock-frequency in board dts */
+			clock-frequency = <200000000>;
+                };
+
 		serial at 12000 {
 			compatible = "ns16550a";
 			reg = <0x12000 0x100>;
arch/arm/mach-dove/common.c +15 -15
index b570211..43062ea 100644
@@ -62,7 +62,6 @@ void __init dove_map_io(void)
 /*****************************************************************************
  * CLK tree
  ****************************************************************************/
-static int dove_tclk;
 
 static DEFINE_SPINLOCK(gating_lock);
 static struct clk *tclk;
@@ -75,6 +74,11 @@ static struct clk __init *dove_register_gate(const char *name,
 				 bit_idx, 0, &gating_lock);
 }
 
+static int __init dove_find_tclk(void)
+{
+	return 166666667;
+}
+
 static void __init dove_clk_init(void)
 {
 	struct clk *usb0, *usb1, *sata, *pex0, *pex1, *sdio0, *sdio1;
@@ -82,7 +86,7 @@ static void __init dove_clk_init(void)
 	struct clk *xor0, *xor1, *ge, *gephy;
 
 	tclk = clk_register_fixed_rate(NULL, "tclk", NULL, CLK_IS_ROOT,
-				       dove_tclk);
+				       dove_find_tclk());
 
 	usb0 = dove_register_gate("usb0", "tclk", CLOCK_GATING_BIT_USB0);
 	usb1 = dove_register_gate("usb1", "tclk", CLOCK_GATING_BIT_USB1);
@@ -232,18 +236,12 @@ void __init dove_i2c_init(void)
  ****************************************************************************/
 void __init dove_init_early(void)
 {
-	orion_time_set_base(TIMER_VIRT_BASE);
-}
-
-static int __init dove_find_tclk(void)
-{
-	return 166666667;
 }
 
 static void __init dove_timer_init(void)
 {
-	dove_tclk = dove_find_tclk();
-	orion_time_init(IRQ_DOVE_BRIDGE_TIMER1, dove_tclk);
+	orion_time_set_base(TIMER_VIRT_BASE);
+	orion_time_init(IRQ_DOVE_BRIDGE_TIMER1, dove_find_tclk());
 }
 
 struct sys_timer dove_timer = {
@@ -340,8 +338,7 @@ void __init dove_sdio1_init(void)
 
 void __init dove_init(void)
 {
-	pr_info("Dove 88AP510 SoC, TCLK = %d MHz.\n",
-		(dove_tclk + 499999) / 1000000);
+	pr_info("Dove 88AP510 SoC\n");
 
 #ifdef CONFIG_CACHE_TAUROS2
 	tauros2_init(0);
@@ -395,8 +392,7 @@ static struct mv643xx_eth_platform_data dove_dt_ge00_data = {
 
 static void __init dove_dt_init(void)
 {
-	pr_info("Dove 88AP510 SoC, TCLK = %d MHz.\n",
-		(dove_tclk + 499999) / 1000000);
+	pr_info("Dove 88AP510 SoC\n");
 
 #ifdef CONFIG_CACHE_TAUROS2
 	tauros2_init(0);
@@ -425,11 +421,15 @@ static const char * const dove_dt_board_compat[] = {
 	NULL
 };
 
+static struct sys_timer dove_dt_timer = {
+	.init = orion_time_init_dt,
+};
+
 DT_MACHINE_START(DOVE_DT, "Marvell Dove (Flattened Device Tree)")
 	.map_io		= dove_map_io,
 	.init_early	= dove_init_early,
 	.init_irq	= orion_dt_init_irq,
-	.timer		= &dove_timer,
+	.timer		= &dove_dt_timer,
 	.init_machine	= dove_dt_init,
 	.restart	= dove_restart,
 	.dt_compat	= dove_dt_board_compat,
arch/arm/mach-kirkwood/board-dt.c +8 -2
index ecbb26f..c49146c 100644
@@ -17,8 +17,10 @@
 #include <linux/kexec.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
+#include <asm/mach/time.h>
 #include <mach/bridge-regs.h>
 #include <plat/irq.h>
+#include <plat/time.h>
 #include "common.h"
 
 static struct of_device_id kirkwood_dt_match_table[] __initdata = {
@@ -41,7 +43,7 @@ struct of_dev_auxdata kirkwood_auxdata_lookup[] __initdata = {
 
 static void __init kirkwood_dt_init(void)
 {
-	pr_info("Kirkwood: %s, TCLK=%d.\n", kirkwood_id(), kirkwood_tclk);
+	pr_info("Kirkwood: %s\n", kirkwood_id());
 
 	/*
 	 * Disable propagation of mbus errors to the CPU local bus,
@@ -115,12 +117,16 @@ static const char *kirkwood_dt_board_compat[] = {
 	NULL
 };
 
+static struct sys_timer kirkwood_dt_timer = {
+	.init           = orion_time_init_dt,
+};
+
 DT_MACHINE_START(KIRKWOOD_DT, "Marvell Kirkwood (Flattened Device Tree)")
 	/* Maintainer: Jason Cooper <[email protected]> */
 	.map_io		= kirkwood_map_io,
 	.init_early	= kirkwood_init_early,
 	.init_irq	= orion_dt_init_irq,
-	.timer		= &kirkwood_timer,
+	.timer		= &kirkwood_dt_timer,
 	.init_machine	= kirkwood_dt_init,
 	.restart	= kirkwood_restart,
 	.dt_compat	= kirkwood_dt_board_compat,
arch/arm/mach-kirkwood/common.c +19 -23

74 lines not on this page · raw message

arch/arm/mach-kirkwood/common.h +0 -1
index bcffd7c..a92fde9 100644
@@ -120,7 +120,6 @@ void kirkwood_xor0_init(void);
 void kirkwood_xor1_init(void);
 void kirkwood_crypto_init(void);
 
-extern int kirkwood_tclk;
 extern struct sys_timer kirkwood_timer;
 
 #define ARRAY_AND_SIZE(x)	(x), ARRAY_SIZE(x)
arch/arm/plat-orion/include/plat/time.h +1 -0
index c5ccc0a..9a4b142 100644
@@ -14,5 +14,6 @@
 void orion_time_set_base(void __iomem *timer_base);
 
 void orion_time_init(unsigned int irq, unsigned int tclk);
+void __init orion_time_init_dt(void);
 
 #endif
arch/arm/plat-orion/time.c +32 -0
index da22aa4..600e8ee 100644
@@ -16,6 +16,8 @@
 #include <linux/clockchips.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
 #include <asm/sched_clock.h>
 #include <linux/sched.h>
 #include <plat/time.h>
@@ -199,3 +201,33 @@ orion_time_init(unsigned int irq, unsigned int tclk)
 	orion_clkevt.cpumask = cpumask_of(0);
 	clockevents_register_device(&orion_clkevt);
 }
+
+#ifdef CONFIG_OF
+void __init
+orion_time_init_dt(void)
+{
+	struct device_node *np;
+	int ret;
+	int irq;
+	u32 clk;
+
+	np = of_find_compatible_node(NULL, NULL, "marvell,orion-timer");
+	if (!np)
+		panic("Bad marvell,orion-timer DT block");
+
+	timer_base = of_iomap(np, 0);
+	if (!timer_base)
+		panic("Bad marvell,orion-timer DT block");
+
+	/* We use timer 0 as clocksource, and timer 1 for clockevents */
+	irq = irq_of_parse_and_map(np, 1);
+	if (!irq)
+		panic("Bad marvell,orion-timer DT block");
+
+	ret = of_property_read_u32(np, "clock-frequency", &clk);
+	if (ret < 0 || clk == 0)
+		panic("Bad marvell,orion-timer DT block");
+
+	orion_time_init(irq, clk);
+}
+#endif
Signature · 1 line
1.7.5.4