aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/irq.c
diff options
context:
space:
mode:
authorMarc Zyngier <marc.zyngier@arm.com>2011-09-06 04:56:17 -0400
committerMarc Zyngier <marc.zyngier@arm.com>2011-11-15 13:14:02 -0500
commit2db1499784da653f7e257d98fefdebc65fde7c40 (patch)
treea7fb2699e1282f96d315df926fb41bf4f49c4dd0 /arch/arm/mach-omap2/irq.c
parent368b8e252335725ea72d7bcbb3b1c8837b8dfeed (diff)
ARM: omap2/3: Add global omap2/3_intc_handle_irq() functions
Provide the OMAP2/3 IRQ code with low level handlers that can be used by platforms using CONFIG_MULTI_IRQ_HANDLER. Though the handlers are written in C, the compiled code looks very similar to its assembly counterpart (at least with my gcc 4.4.1). Tested-by: Tony Lindgren <tony@atomide.com> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Diffstat (limited to 'arch/arm/mach-omap2/irq.c')
-rw-r--r--arch/arm/mach-omap2/irq.c50
1 files changed, 50 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/irq.c b/arch/arm/mach-omap2/irq.c
index 65f1be6a182c..ec52bee0e089 100644
--- a/arch/arm/mach-omap2/irq.c
+++ b/arch/arm/mach-omap2/irq.c
@@ -15,6 +15,7 @@
15#include <linux/interrupt.h> 15#include <linux/interrupt.h>
16#include <linux/io.h> 16#include <linux/io.h>
17#include <mach/hardware.h> 17#include <mach/hardware.h>
18#include <asm/exception.h>
18#include <asm/mach/irq.h> 19#include <asm/mach/irq.h>
19 20
20 21
@@ -35,6 +36,11 @@
35/* Number of IRQ state bits in each MIR register */ 36/* Number of IRQ state bits in each MIR register */
36#define IRQ_BITS_PER_REG 32 37#define IRQ_BITS_PER_REG 32
37 38
39#define OMAP2_IRQ_BASE OMAP2_L4_IO_ADDRESS(OMAP24XX_IC_BASE)
40#define OMAP3_IRQ_BASE OMAP2_L4_IO_ADDRESS(OMAP34XX_IC_BASE)
41#define INTCPS_SIR_IRQ_OFFSET 0x0040 /* omap2/3 active interrupt offset */
42#define ACTIVEIRQ_MASK 0x7f /* omap2/3 active interrupt bits */
43
38/* 44/*
39 * OMAP2 has a number of different interrupt controllers, each interrupt 45 * OMAP2 has a number of different interrupt controllers, each interrupt
40 * controller is identified as its own "bank". Register definitions are 46 * controller is identified as its own "bank". Register definitions are
@@ -191,6 +197,44 @@ void __init ti816x_init_irq(void)
191 omap_init_irq(OMAP34XX_IC_BASE, 128); 197 omap_init_irq(OMAP34XX_IC_BASE, 128);
192} 198}
193 199
200static inline void omap_intc_handle_irq(void __iomem *base_addr, struct pt_regs *regs)
201{
202 u32 irqnr;
203
204 do {
205 irqnr = readl_relaxed(base_addr + 0x98);
206 if (irqnr)
207 goto out;
208
209 irqnr = readl_relaxed(base_addr + 0xb8);
210 if (irqnr)
211 goto out;
212
213 irqnr = readl_relaxed(base_addr + 0xd8);
214#ifdef CONFIG_SOC_OMAPTI816X
215 if (irqnr)
216 goto out;
217 irqnr = readl_relaxed(base_addr + 0xf8);
218#endif
219
220out:
221 if (!irqnr)
222 break;
223
224 irqnr = readl_relaxed(base_addr + INTCPS_SIR_IRQ_OFFSET);
225 irqnr &= ACTIVEIRQ_MASK;
226
227 if (irqnr)
228 handle_IRQ(irqnr, regs);
229 } while (irqnr);
230}
231
232asmlinkage void __exception_irq_entry omap2_intc_handle_irq(struct pt_regs *regs)
233{
234 void __iomem *base_addr = OMAP2_IRQ_BASE;
235 omap_intc_handle_irq(base_addr, regs);
236}
237
194#ifdef CONFIG_ARCH_OMAP3 238#ifdef CONFIG_ARCH_OMAP3
195static struct omap3_intc_regs intc_context[ARRAY_SIZE(irq_banks)]; 239static struct omap3_intc_regs intc_context[ARRAY_SIZE(irq_banks)];
196 240
@@ -263,4 +307,10 @@ void omap3_intc_resume_idle(void)
263 /* Re-enable autoidle */ 307 /* Re-enable autoidle */
264 intc_bank_write_reg(1, &irq_banks[0], INTC_SYSCONFIG); 308 intc_bank_write_reg(1, &irq_banks[0], INTC_SYSCONFIG);
265} 309}
310
311asmlinkage void __exception_irq_entry omap3_intc_handle_irq(struct pt_regs *regs)
312{
313 void __iomem *base_addr = OMAP3_IRQ_BASE;
314 omap_intc_handle_irq(base_addr, regs);
315}
266#endif /* CONFIG_ARCH_OMAP3 */ 316#endif /* CONFIG_ARCH_OMAP3 */