SPARC/LEON: find IRQCTRL and Timer via OF-Tree, instead of hardcoded.

Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c
index f01c426..80ba8f5 100644
--- a/arch/sparc/kernel/leon_kernel.c
+++ b/arch/sparc/kernel/leon_kernel.c
@@ -23,15 +23,15 @@
 #include "prom.h"
 #include "irq.h"
 
-struct leon3_irqctrl_regs_map *leon3_irqctrl_regs; /* interrupt controller base address, initialized by amba_init() */
-struct leon3_gptimer_regs_map *leon3_gptimer_regs; /* timer controller base address, initialized by amba_init() */
+struct leon3_irqctrl_regs_map *leon3_irqctrl_regs; /* interrupt controller base address */
+struct leon3_gptimer_regs_map *leon3_gptimer_regs; /* timer controller base address */
 struct amba_apb_device leon_percpu_timer_dev[16];
 
 int leondebug_irq_disable;
 int leon_debug_irqout;
 static int dummy_master_l10_counter;
 
-unsigned long leon3_gptimer_irq; /* interrupt controller irq number, initialized by amba_init() */
+unsigned long leon3_gptimer_irq; /* interrupt controller irq number */
 unsigned int sparc_leon_eirq;
 #define LEON_IMASK ((&leon3_irqctrl_regs->mask[0]))
 
@@ -105,13 +105,41 @@
 void __init leon_init_timers(irq_handler_t counter_fn)
 {
 	int irq;
+	struct device_node *rootnp, *np;
+	struct property *pp;
+	int len;
 
 	leondebug_irq_disable = 0;
 	leon_debug_irqout = 0;
 	master_l10_counter = (unsigned int *)&dummy_master_l10_counter;
 	dummy_master_l10_counter = 0;
 
-	if (leon3_gptimer_regs && leon3_irqctrl_regs) {
+	/*Find IRQMP IRQ Controller Registers base address otherwise bail out.*/
+	rootnp = of_find_node_by_path("/ambapp0");
+	if (!rootnp)
+		goto bad;
+	np = of_find_node_by_name(rootnp, "GAISLER_IRQMP");
+	if (!np)
+		goto bad;
+	pp = of_find_property(np, "reg", &len);
+	if (!pp)
+		goto bad;
+	leon3_irqctrl_regs = *(struct leon3_irqctrl_regs_map **)pp->value;
+
+	/* Find GPTIMER Timer Registers base address otherwise bail out. */
+	np = of_find_node_by_name(rootnp, "GAISLER_GPTIMER");
+	if (!np)
+		goto bad;
+	pp = of_find_property(np, "reg", &len);
+	if (!pp)
+		goto bad;
+	leon3_gptimer_regs = *(struct leon3_gptimer_regs_map **)pp->value;
+	pp = of_find_property(np, "interrupts", &len);
+	if (!pp)
+		goto bad;
+	leon3_gptimer_irq = *(unsigned int *)pp->value;
+
+	if (leon3_gptimer_regs && leon3_irqctrl_regs && leon3_gptimer_irq) {
 		LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].val, 0);
 		LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].rld,
 				      (((1000000 / HZ) - 1)));
@@ -133,8 +161,7 @@
 # endif
 
 	} else {
-		printk(KERN_ERR "No Timer/irqctrl found\n");
-		BUG();
+		goto bad;
 	}
 
 	irq = request_irq(leon3_gptimer_irq,
@@ -183,6 +210,11 @@
 #endif
 
 	}
+	return;
+bad:
+	printk(KERN_ERR "No Timer/irqctrl found\n");
+	BUG();
+	return;
 }
 
 void leon_clear_clock_irq(void)