diff options
Diffstat (limited to 'arch/arm/common/gic.c')
-rw-r--r-- | arch/arm/common/gic.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c index 43cb6f1a7cf2..3c78b7c60691 100644 --- a/arch/arm/common/gic.c +++ b/arch/arm/common/gic.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <linux/slab.h> | 40 | #include <linux/slab.h> |
41 | 41 | ||
42 | #include <asm/irq.h> | 42 | #include <asm/irq.h> |
43 | #include <asm/exception.h> | ||
43 | #include <asm/mach/irq.h> | 44 | #include <asm/mach/irq.h> |
44 | #include <asm/hardware/gic.h> | 45 | #include <asm/hardware/gic.h> |
45 | 46 | ||
@@ -272,6 +273,32 @@ static int gic_set_wake(struct irq_data *d, unsigned int on) | |||
272 | #define gic_set_wake NULL | 273 | #define gic_set_wake NULL |
273 | #endif | 274 | #endif |
274 | 275 | ||
276 | asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs) | ||
277 | { | ||
278 | u32 irqstat, irqnr; | ||
279 | struct gic_chip_data *gic = &gic_data[0]; | ||
280 | void __iomem *cpu_base = gic_data_cpu_base(gic); | ||
281 | |||
282 | do { | ||
283 | irqstat = readl_relaxed(cpu_base + GIC_CPU_INTACK); | ||
284 | irqnr = irqstat & ~0x1c00; | ||
285 | |||
286 | if (likely(irqnr > 15 && irqnr < 1021)) { | ||
287 | irqnr = irq_domain_to_irq(&gic->domain, irqnr); | ||
288 | handle_IRQ(irqnr, regs); | ||
289 | continue; | ||
290 | } | ||
291 | if (irqnr < 16) { | ||
292 | writel_relaxed(irqstat, cpu_base + GIC_CPU_EOI); | ||
293 | #ifdef CONFIG_SMP | ||
294 | handle_IPI(irqnr, regs); | ||
295 | #endif | ||
296 | continue; | ||
297 | } | ||
298 | break; | ||
299 | } while (1); | ||
300 | } | ||
301 | |||
275 | static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc) | 302 | static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc) |
276 | { | 303 | { |
277 | struct gic_chip_data *chip_data = irq_get_handler_data(irq); | 304 | struct gic_chip_data *chip_data = irq_get_handler_data(irq); |