aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/irq.c
diff options
context:
space:
mode:
authorBenoit Cousson <b-cousson@ti.com>2011-11-30 13:21:07 -0500
committerBenoit Cousson <b-cousson@ti.com>2012-02-27 04:33:18 -0500
commit52fa212088b141dd05957dc4b7f06a893c8166ad (patch)
tree9a9c1e90a6acce6dd8ea965e41a7fca79e459b84 /arch/arm/mach-omap2/irq.c
parent1f52299ec000e2161635b263d81ab92ea7f1f0a7 (diff)
ARM: OMAP2/3: intc: Add DT support for TI interrupt controller
Add a function to initialize the OMAP2/3 interrupt controller (INTC) using a device tree node. This version take advantage of the new irq_domain_add_legacy API. Replace some printk() with the proper pr_ macro. Signed-off-by: Benoit Cousson <b-cousson@ti.com> Cc: Tony Lindgren <tony@atomide.com> Acked-by: Rob Herring <rob.herring@calxeda.com> Acked-by: Grant Likely <grant.likely@secretlab.ca>
Diffstat (limited to 'arch/arm/mach-omap2/irq.c')
-rw-r--r--arch/arm/mach-omap2/irq.c60
1 files changed, 50 insertions, 10 deletions
diff --git a/arch/arm/mach-omap2/irq.c b/arch/arm/mach-omap2/irq.c
index 1fef061f792..26eaf37ce4d 100644
--- a/arch/arm/mach-omap2/irq.c
+++ b/arch/arm/mach-omap2/irq.c
@@ -11,12 +11,16 @@
11 * for more details. 11 * for more details.
12 */ 12 */
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/module.h>
14#include <linux/init.h> 15#include <linux/init.h>
15#include <linux/interrupt.h> 16#include <linux/interrupt.h>
16#include <linux/io.h> 17#include <linux/io.h>
17#include <mach/hardware.h> 18#include <mach/hardware.h>
18#include <asm/exception.h> 19#include <asm/exception.h>
19#include <asm/mach/irq.h> 20#include <asm/mach/irq.h>
21#include <linux/irqdomain.h>
22#include <linux/of.h>
23#include <linux/of_address.h>
20 24
21 25
22/* selected INTC register offsets */ 26/* selected INTC register offsets */
@@ -57,6 +61,8 @@ static struct omap_irq_bank {
57 }, 61 },
58}; 62};
59 63
64static struct irq_domain *domain;
65
60/* Structure to save interrupt controller context */ 66/* Structure to save interrupt controller context */
61struct omap3_intc_regs { 67struct omap3_intc_regs {
62 u32 sysconfig; 68 u32 sysconfig;
@@ -147,17 +153,27 @@ omap_alloc_gc(void __iomem *base, unsigned int irq_start, unsigned int num)
147 IRQ_NOREQUEST | IRQ_NOPROBE, 0); 153 IRQ_NOREQUEST | IRQ_NOPROBE, 0);
148} 154}
149 155
150static void __init omap_init_irq(u32 base, int nr_irqs) 156static void __init omap_init_irq(u32 base, int nr_irqs,
157 struct device_node *node)
151{ 158{
152 void __iomem *omap_irq_base; 159 void __iomem *omap_irq_base;
153 unsigned long nr_of_irqs = 0; 160 unsigned long nr_of_irqs = 0;
154 unsigned int nr_banks = 0; 161 unsigned int nr_banks = 0;
155 int i, j; 162 int i, j, irq_base;
156 163
157 omap_irq_base = ioremap(base, SZ_4K); 164 omap_irq_base = ioremap(base, SZ_4K);
158 if (WARN_ON(!omap_irq_base)) 165 if (WARN_ON(!omap_irq_base))
159 return; 166 return;
160 167
168 irq_base = irq_alloc_descs(-1, 0, nr_irqs, 0);
169 if (irq_base < 0) {
170 pr_warn("Couldn't allocate IRQ numbers\n");
171 irq_base = 0;
172 }
173
174 domain = irq_domain_add_legacy(node, nr_irqs, irq_base, 0,
175 &irq_domain_simple_ops, NULL);
176
161 for (i = 0; i < ARRAY_SIZE(irq_banks); i++) { 177 for (i = 0; i < ARRAY_SIZE(irq_banks); i++) {
162 struct omap_irq_bank *bank = irq_banks + i; 178 struct omap_irq_bank *bank = irq_banks + i;
163 179
@@ -166,36 +182,36 @@ static void __init omap_init_irq(u32 base, int nr_irqs)
166 /* Static mapping, never released */ 182 /* Static mapping, never released */
167 bank->base_reg = ioremap(base, SZ_4K); 183 bank->base_reg = ioremap(base, SZ_4K);
168 if (!bank->base_reg) { 184 if (!bank->base_reg) {
169 printk(KERN_ERR "Could not ioremap irq bank%i\n", i); 185 pr_err("Could not ioremap irq bank%i\n", i);
170 continue; 186 continue;
171 } 187 }
172 188
173 omap_irq_bank_init_one(bank); 189 omap_irq_bank_init_one(bank);
174 190
175 for (j = 0; j < bank->nr_irqs; j += 32) 191 for (j = 0; j < bank->nr_irqs; j += 32)
176 omap_alloc_gc(bank->base_reg + j, j, 32); 192 omap_alloc_gc(bank->base_reg + j, j + irq_base, 32);
177 193
178 nr_of_irqs += bank->nr_irqs; 194 nr_of_irqs += bank->nr_irqs;
179 nr_banks++; 195 nr_banks++;
180 } 196 }
181 197
182 printk(KERN_INFO "Total of %ld interrupts on %d active controller%s\n", 198 pr_info("Total of %ld interrupts on %d active controller%s\n",
183 nr_of_irqs, nr_banks, nr_banks > 1 ? "s" : ""); 199 nr_of_irqs, nr_banks, nr_banks > 1 ? "s" : "");
184} 200}
185 201
186void __init omap2_init_irq(void) 202void __init omap2_init_irq(void)
187{ 203{
188 omap_init_irq(OMAP24XX_IC_BASE, 96); 204 omap_init_irq(OMAP24XX_IC_BASE, 96, NULL);
189} 205}
190 206
191void __init omap3_init_irq(void) 207void __init omap3_init_irq(void)
192{ 208{
193 omap_init_irq(OMAP34XX_IC_BASE, 96); 209 omap_init_irq(OMAP34XX_IC_BASE, 96, NULL);
194} 210}
195 211
196void __init ti81xx_init_irq(void) 212void __init ti81xx_init_irq(void)
197{ 213{
198 omap_init_irq(OMAP34XX_IC_BASE, 128); 214 omap_init_irq(OMAP34XX_IC_BASE, 128, NULL);
199} 215}
200 216
201static inline void omap_intc_handle_irq(void __iomem *base_addr, struct pt_regs *regs) 217static inline void omap_intc_handle_irq(void __iomem *base_addr, struct pt_regs *regs)
@@ -225,8 +241,10 @@ out:
225 irqnr = readl_relaxed(base_addr + INTCPS_SIR_IRQ_OFFSET); 241 irqnr = readl_relaxed(base_addr + INTCPS_SIR_IRQ_OFFSET);
226 irqnr &= ACTIVEIRQ_MASK; 242 irqnr &= ACTIVEIRQ_MASK;
227 243
228 if (irqnr) 244 if (irqnr) {
245 irqnr = irq_find_mapping(domain, irqnr);
229 handle_IRQ(irqnr, regs); 246 handle_IRQ(irqnr, regs);
247 }
230 } while (irqnr); 248 } while (irqnr);
231} 249}
232 250
@@ -236,6 +254,28 @@ asmlinkage void __exception_irq_entry omap2_intc_handle_irq(struct pt_regs *regs
236 omap_intc_handle_irq(base_addr, regs); 254 omap_intc_handle_irq(base_addr, regs);
237} 255}
238 256
257int __init omap_intc_of_init(struct device_node *node,
258 struct device_node *parent)
259{
260 struct resource res;
261 u32 nr_irqs = 96;
262
263 if (WARN_ON(!node))
264 return -ENODEV;
265
266 if (of_address_to_resource(node, 0, &res)) {
267 WARN(1, "unable to get intc registers\n");
268 return -EINVAL;
269 }
270
271 if (of_property_read_u32(node, "ti,intc-size", &nr_irqs))
272 pr_warn("unable to get intc-size, default to %d\n", nr_irqs);
273
274 omap_init_irq(res.start, nr_irqs, of_node_get(node));
275
276 return 0;
277}
278
239#ifdef CONFIG_ARCH_OMAP3 279#ifdef CONFIG_ARCH_OMAP3
240static struct omap3_intc_regs intc_context[ARRAY_SIZE(irq_banks)]; 280static struct omap3_intc_regs intc_context[ARRAY_SIZE(irq_banks)];
241 281