diff options
author | Florian Tobias Schandinat <FlorianSchandinat@gmx.de> | 2012-01-28 19:52:40 +0000 |
---|---|---|
committer | Florian Tobias Schandinat <FlorianSchandinat@gmx.de> | 2012-01-28 19:52:40 +0000 |
commit | b20f86625de738658c74f2ecfe4050416d2252cc (patch) | |
tree | b84216b70bd923409217834a953f983700e39eda /arch/arm/mach-omap2/irq.c | |
parent | 9f1065032ceb7e86c7c9f16bb86518857e88a172 (diff) | |
parent | dcd6c92267155e70a94b3927bce681ce74b80d1f (diff) | |
download | talos-op-linux-b20f86625de738658c74f2ecfe4050416d2252cc.tar.gz talos-op-linux-b20f86625de738658c74f2ecfe4050416d2252cc.zip |
Merge commit 'v3.3-rc1' into fbdev-next
Diffstat (limited to 'arch/arm/mach-omap2/irq.c')
-rw-r--r-- | arch/arm/mach-omap2/irq.c | 53 |
1 files changed, 52 insertions, 1 deletions
diff --git a/arch/arm/mach-omap2/irq.c b/arch/arm/mach-omap2/irq.c index 65f1be6a182c..1fef061f7927 100644 --- a/arch/arm/mach-omap2/irq.c +++ b/arch/arm/mach-omap2/irq.c @@ -15,6 +15,7 @@ #include <linux/interrupt.h> #include <linux/io.h> #include <mach/hardware.h> +#include <asm/exception.h> #include <asm/mach/irq.h> @@ -35,6 +36,11 @@ /* Number of IRQ state bits in each MIR register */ #define IRQ_BITS_PER_REG 32 +#define OMAP2_IRQ_BASE OMAP2_L4_IO_ADDRESS(OMAP24XX_IC_BASE) +#define OMAP3_IRQ_BASE OMAP2_L4_IO_ADDRESS(OMAP34XX_IC_BASE) +#define INTCPS_SIR_IRQ_OFFSET 0x0040 /* omap2/3 active interrupt offset */ +#define ACTIVEIRQ_MASK 0x7f /* omap2/3 active interrupt bits */ + /* * OMAP2 has a number of different interrupt controllers, each interrupt * controller is identified as its own "bank". Register definitions are @@ -143,6 +149,7 @@ omap_alloc_gc(void __iomem *base, unsigned int irq_start, unsigned int num) static void __init omap_init_irq(u32 base, int nr_irqs) { + void __iomem *omap_irq_base; unsigned long nr_of_irqs = 0; unsigned int nr_banks = 0; int i, j; @@ -186,11 +193,49 @@ void __init omap3_init_irq(void) omap_init_irq(OMAP34XX_IC_BASE, 96); } -void __init ti816x_init_irq(void) +void __init ti81xx_init_irq(void) { omap_init_irq(OMAP34XX_IC_BASE, 128); } +static inline void omap_intc_handle_irq(void __iomem *base_addr, struct pt_regs *regs) +{ + u32 irqnr; + + do { + irqnr = readl_relaxed(base_addr + 0x98); + if (irqnr) + goto out; + + irqnr = readl_relaxed(base_addr + 0xb8); + if (irqnr) + goto out; + + irqnr = readl_relaxed(base_addr + 0xd8); +#ifdef CONFIG_SOC_OMAPTI816X + if (irqnr) + goto out; + irqnr = readl_relaxed(base_addr + 0xf8); +#endif + +out: + if (!irqnr) + break; + + irqnr = readl_relaxed(base_addr + INTCPS_SIR_IRQ_OFFSET); + irqnr &= ACTIVEIRQ_MASK; + + if (irqnr) + handle_IRQ(irqnr, regs); + } while (irqnr); +} + +asmlinkage void __exception_irq_entry omap2_intc_handle_irq(struct pt_regs *regs) +{ + void __iomem *base_addr = OMAP2_IRQ_BASE; + omap_intc_handle_irq(base_addr, regs); +} + #ifdef CONFIG_ARCH_OMAP3 static struct omap3_intc_regs intc_context[ARRAY_SIZE(irq_banks)]; @@ -263,4 +308,10 @@ void omap3_intc_resume_idle(void) /* Re-enable autoidle */ intc_bank_write_reg(1, &irq_banks[0], INTC_SYSCONFIG); } + +asmlinkage void __exception_irq_entry omap3_intc_handle_irq(struct pt_regs *regs) +{ + void __iomem *base_addr = OMAP3_IRQ_BASE; + omap_intc_handle_irq(base_addr, regs); +} #endif /* CONFIG_ARCH_OMAP3 */ |