aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/irq.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-03-27 19:47:35 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-03-27 19:47:35 -0400
commit66f03c614c0902ccf7d6160459362a9352f33271 (patch)
treeb9a8864efe5aa7fc5c96cc5ccbeca41f5cd6f6a7 /arch/arm/mach-omap2/irq.c
parent34800598b2eebe061445216473b1e4c2ff5cba99 (diff)
parentcdc3df6f44f72c5924a16a47e1663c3fb0e57820 (diff)
Merge tag 'dt' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull "ARM: device tree work" from Arnd Bergmann: "Most of these patches convert code from using static platform data to describing the hardware in the device tree. This is only the first half of the changes for v3.4 because a lot of patches for this topic came in the last week before the merge window. Signed-off-by: Arnd Bergmann <arnd@arndb.de>" Fix up trivial conflicts in arch/arm/mach-vexpress/{Kconfig,core.h} * tag 'dt' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (86 commits) Document: devicetree: add OF documents for arch-mmp ARM: dts: append DTS file of pxa168 ARM: mmp: append OF support on pxa168 ARM: mmp: enable rtc clk in pxa168 i2c: pxa: add OF support serial: pxa: add OF support arm/dts: mt_ventoux: very basic support for TeeJet Mt.Ventoux board ARM: OMAP2+: Remove extra ifdefs for board-generic ARM: OMAP2+: Fix build error when only ARCH_OMAP2/3 or 4 is selected ASoC: DT: Add digital microphone binding to PAZ00 board. ARM: dt: Add ARM PMU to tegra*.dtsi ARM: at91: at91sam9x5cm/dt: add leds support ARM: at91: usb_a9g20/dt: add gpio-keys support ARM: at91: at91sam9m10g45ek/dt: add gpio-keys support ARM: at91: at91sam9m10g45ek/dt: add leds support ARM: at91: usb_a9g20/dt: add leds support ARM: at91/pio: add new PIO3 features ARM: at91: add sam9_smc.o to at91sam9x5 build ARM: at91/tc/clocksource: Add 32 bit variant to Timer Counter ARM: at91/tc: add device tree support to atmel_tclib ...
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 6da2d0edee11..65f0d2571c9a 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 18
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#include <mach/hardware.h> 25#include <mach/hardware.h>
22 26
@@ -60,6 +64,8 @@ static struct omap_irq_bank {
60 }, 64 },
61}; 65};
62 66
67static struct irq_domain *domain;
68
63/* Structure to save interrupt controller context */ 69/* Structure to save interrupt controller context */
64struct omap3_intc_regs { 70struct omap3_intc_regs {
65 u32 sysconfig; 71 u32 sysconfig;
@@ -150,17 +156,27 @@ omap_alloc_gc(void __iomem *base, unsigned int irq_start, unsigned int num)
150 IRQ_NOREQUEST | IRQ_NOPROBE, 0); 156 IRQ_NOREQUEST | IRQ_NOPROBE, 0);
151} 157}
152 158
153static void __init omap_init_irq(u32 base, int nr_irqs) 159static void __init omap_init_irq(u32 base, int nr_irqs,
160 struct device_node *node)
154{ 161{
155 void __iomem *omap_irq_base; 162 void __iomem *omap_irq_base;
156 unsigned long nr_of_irqs = 0; 163 unsigned long nr_of_irqs = 0;
157 unsigned int nr_banks = 0; 164 unsigned int nr_banks = 0;
158 int i, j; 165 int i, j, irq_base;
159 166
160 omap_irq_base = ioremap(base, SZ_4K); 167 omap_irq_base = ioremap(base, SZ_4K);
161 if (WARN_ON(!omap_irq_base)) 168 if (WARN_ON(!omap_irq_base))
162 return; 169 return;
163 170
171 irq_base = irq_alloc_descs(-1, 0, nr_irqs, 0);
172 if (irq_base < 0) {
173 pr_warn("Couldn't allocate IRQ numbers\n");
174 irq_base = 0;
175 }
176
177 domain = irq_domain_add_legacy(node, nr_irqs, irq_base, 0,
178 &irq_domain_simple_ops, NULL);
179
164 for (i = 0; i < ARRAY_SIZE(irq_banks); i++) { 180 for (i = 0; i < ARRAY_SIZE(irq_banks); i++) {
165 struct omap_irq_bank *bank = irq_banks + i; 181 struct omap_irq_bank *bank = irq_banks + i;
166 182
@@ -169,36 +185,36 @@ static void __init omap_init_irq(u32 base, int nr_irqs)
169 /* Static mapping, never released */ 185 /* Static mapping, never released */
170 bank->base_reg = ioremap(base, SZ_4K); 186 bank->base_reg = ioremap(base, SZ_4K);
171 if (!bank->base_reg) { 187 if (!bank->base_reg) {
172 printk(KERN_ERR "Could not ioremap irq bank%i\n", i); 188 pr_err("Could not ioremap irq bank%i\n", i);
173 continue; 189 continue;
174 } 190 }
175 191
176 omap_irq_bank_init_one(bank); 192 omap_irq_bank_init_one(bank);
177 193
178 for (j = 0; j < bank->nr_irqs; j += 32) 194 for (j = 0; j < bank->nr_irqs; j += 32)
179 omap_alloc_gc(bank->base_reg + j, j, 32); 195 omap_alloc_gc(bank->base_reg + j, j + irq_base, 32);
180 196
181 nr_of_irqs += bank->nr_irqs; 197 nr_of_irqs += bank->nr_irqs;
182 nr_banks++; 198 nr_banks++;
183 } 199 }
184 200
185 printk(KERN_INFO "Total of %ld interrupts on %d active controller%s\n", 201 pr_info("Total of %ld interrupts on %d active controller%s\n",
186 nr_of_irqs, nr_banks, nr_banks > 1 ? "s" : ""); 202 nr_of_irqs, nr_banks, nr_banks > 1 ? "s" : "");
187} 203}
188 204
189void __init omap2_init_irq(void) 205void __init omap2_init_irq(void)
190{ 206{
191 omap_init_irq(OMAP24XX_IC_BASE, 96); 207 omap_init_irq(OMAP24XX_IC_BASE, 96, NULL);
192} 208}
193 209
194void __init omap3_init_irq(void) 210void __init omap3_init_irq(void)
195{ 211{
196 omap_init_irq(OMAP34XX_IC_BASE, 96); 212 omap_init_irq(OMAP34XX_IC_BASE, 96, NULL);
197} 213}
198 214
199void __init ti81xx_init_irq(void) 215void __init ti81xx_init_irq(void)
200{ 216{
201 omap_init_irq(OMAP34XX_IC_BASE, 128); 217 omap_init_irq(OMAP34XX_IC_BASE, 128, NULL);
202} 218}
203 219
204static inline void omap_intc_handle_irq(void __iomem *base_addr, struct pt_regs *regs) 220static inline void omap_intc_handle_irq(void __iomem *base_addr, struct pt_regs *regs)
@@ -228,8 +244,10 @@ out:
228 irqnr = readl_relaxed(base_addr + INTCPS_SIR_IRQ_OFFSET); 244 irqnr = readl_relaxed(base_addr + INTCPS_SIR_IRQ_OFFSET);
229 irqnr &= ACTIVEIRQ_MASK; 245 irqnr &= ACTIVEIRQ_MASK;
230 246
231 if (irqnr) 247 if (irqnr) {
248 irqnr = irq_find_mapping(domain, irqnr);
232 handle_IRQ(irqnr, regs); 249 handle_IRQ(irqnr, regs);
250 }
233 } while (irqnr); 251 } while (irqnr);
234} 252}
235 253
@@ -239,6 +257,28 @@ asmlinkage void __exception_irq_entry omap2_intc_handle_irq(struct pt_regs *regs
239 omap_intc_handle_irq(base_addr, regs); 257 omap_intc_handle_irq(base_addr, regs);
240} 258}
241 259
260int __init omap_intc_of_init(struct device_node *node,
261 struct device_node *parent)
262{
263 struct resource res;
264 u32 nr_irqs = 96;
265
266 if (WARN_ON(!node))
267 return -ENODEV;
268
269 if (of_address_to_resource(node, 0, &res)) {
270 WARN(1, "unable to get intc registers\n");
271 return -EINVAL;
272 }
273
274 if (of_property_read_u32(node, "ti,intc-size", &nr_irqs))
275 pr_warn("unable to get intc-size, default to %d\n", nr_irqs);
276
277 omap_init_irq(res.start, nr_irqs, of_node_get(node));
278
279 return 0;
280}
281
242#ifdef CONFIG_ARCH_OMAP3 282#ifdef CONFIG_ARCH_OMAP3
243static struct omap3_intc_regs intc_context[ARRAY_SIZE(irq_banks)]; 283static struct omap3_intc_regs intc_context[ARRAY_SIZE(irq_banks)];
244 284