diff options
author | Daniel Hellstrom <daniel@gaisler.com> | 2011-01-03 20:41:29 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-01-04 14:16:35 -0500 |
commit | 53aea7caf2e27108912b9b9dbc5bfe18dbbaec9d (patch) | |
tree | cebe1a8972da0128eedde3c7bdee703a5b5202ec /arch/sparc/kernel/leon_kernel.c | |
parent | 5f66dd35b49ea81a03e71bfd74c28364f4e32d21 (diff) |
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>
Diffstat (limited to 'arch/sparc/kernel/leon_kernel.c')
-rw-r--r-- | arch/sparc/kernel/leon_kernel.c | 44 |
1 files changed, 38 insertions, 6 deletions
diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c index f01c42661ee5..80ba8f517318 100644 --- a/arch/sparc/kernel/leon_kernel.c +++ b/arch/sparc/kernel/leon_kernel.c | |||
@@ -23,15 +23,15 @@ | |||
23 | #include "prom.h" | 23 | #include "prom.h" |
24 | #include "irq.h" | 24 | #include "irq.h" |
25 | 25 | ||
26 | struct leon3_irqctrl_regs_map *leon3_irqctrl_regs; /* interrupt controller base address, initialized by amba_init() */ | 26 | struct leon3_irqctrl_regs_map *leon3_irqctrl_regs; /* interrupt controller base address */ |
27 | struct leon3_gptimer_regs_map *leon3_gptimer_regs; /* timer controller base address, initialized by amba_init() */ | 27 | struct leon3_gptimer_regs_map *leon3_gptimer_regs; /* timer controller base address */ |
28 | struct amba_apb_device leon_percpu_timer_dev[16]; | 28 | struct amba_apb_device leon_percpu_timer_dev[16]; |
29 | 29 | ||
30 | int leondebug_irq_disable; | 30 | int leondebug_irq_disable; |
31 | int leon_debug_irqout; | 31 | int leon_debug_irqout; |
32 | static int dummy_master_l10_counter; | 32 | static int dummy_master_l10_counter; |
33 | 33 | ||
34 | unsigned long leon3_gptimer_irq; /* interrupt controller irq number, initialized by amba_init() */ | 34 | unsigned long leon3_gptimer_irq; /* interrupt controller irq number */ |
35 | unsigned int sparc_leon_eirq; | 35 | unsigned int sparc_leon_eirq; |
36 | #define LEON_IMASK ((&leon3_irqctrl_regs->mask[0])) | 36 | #define LEON_IMASK ((&leon3_irqctrl_regs->mask[0])) |
37 | 37 | ||
@@ -105,13 +105,41 @@ static void leon_disable_irq(unsigned int irq_nr) | |||
105 | void __init leon_init_timers(irq_handler_t counter_fn) | 105 | void __init leon_init_timers(irq_handler_t counter_fn) |
106 | { | 106 | { |
107 | int irq; | 107 | int irq; |
108 | struct device_node *rootnp, *np; | ||
109 | struct property *pp; | ||
110 | int len; | ||
108 | 111 | ||
109 | leondebug_irq_disable = 0; | 112 | leondebug_irq_disable = 0; |
110 | leon_debug_irqout = 0; | 113 | leon_debug_irqout = 0; |
111 | master_l10_counter = (unsigned int *)&dummy_master_l10_counter; | 114 | master_l10_counter = (unsigned int *)&dummy_master_l10_counter; |
112 | dummy_master_l10_counter = 0; | 115 | dummy_master_l10_counter = 0; |
113 | 116 | ||
114 | if (leon3_gptimer_regs && leon3_irqctrl_regs) { | 117 | /*Find IRQMP IRQ Controller Registers base address otherwise bail out.*/ |
118 | rootnp = of_find_node_by_path("/ambapp0"); | ||
119 | if (!rootnp) | ||
120 | goto bad; | ||
121 | np = of_find_node_by_name(rootnp, "GAISLER_IRQMP"); | ||
122 | if (!np) | ||
123 | goto bad; | ||
124 | pp = of_find_property(np, "reg", &len); | ||
125 | if (!pp) | ||
126 | goto bad; | ||
127 | leon3_irqctrl_regs = *(struct leon3_irqctrl_regs_map **)pp->value; | ||
128 | |||
129 | /* Find GPTIMER Timer Registers base address otherwise bail out. */ | ||
130 | np = of_find_node_by_name(rootnp, "GAISLER_GPTIMER"); | ||
131 | if (!np) | ||
132 | goto bad; | ||
133 | pp = of_find_property(np, "reg", &len); | ||
134 | if (!pp) | ||
135 | goto bad; | ||
136 | leon3_gptimer_regs = *(struct leon3_gptimer_regs_map **)pp->value; | ||
137 | pp = of_find_property(np, "interrupts", &len); | ||
138 | if (!pp) | ||
139 | goto bad; | ||
140 | leon3_gptimer_irq = *(unsigned int *)pp->value; | ||
141 | |||
142 | if (leon3_gptimer_regs && leon3_irqctrl_regs && leon3_gptimer_irq) { | ||
115 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].val, 0); | 143 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].val, 0); |
116 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].rld, | 144 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].rld, |
117 | (((1000000 / HZ) - 1))); | 145 | (((1000000 / HZ) - 1))); |
@@ -133,8 +161,7 @@ void __init leon_init_timers(irq_handler_t counter_fn) | |||
133 | # endif | 161 | # endif |
134 | 162 | ||
135 | } else { | 163 | } else { |
136 | printk(KERN_ERR "No Timer/irqctrl found\n"); | 164 | goto bad; |
137 | BUG(); | ||
138 | } | 165 | } |
139 | 166 | ||
140 | irq = request_irq(leon3_gptimer_irq, | 167 | irq = request_irq(leon3_gptimer_irq, |
@@ -183,6 +210,11 @@ void __init leon_init_timers(irq_handler_t counter_fn) | |||
183 | #endif | 210 | #endif |
184 | 211 | ||
185 | } | 212 | } |
213 | return; | ||
214 | bad: | ||
215 | printk(KERN_ERR "No Timer/irqctrl found\n"); | ||
216 | BUG(); | ||
217 | return; | ||
186 | } | 218 | } |
187 | 219 | ||
188 | void leon_clear_clock_irq(void) | 220 | void leon_clear_clock_irq(void) |