diff options
author | Marc Zyngier <marc.zyngier@arm.com> | 2011-09-06 04:56:17 -0400 |
---|---|---|
committer | Marc Zyngier <marc.zyngier@arm.com> | 2011-11-15 13:13:05 -0500 |
commit | 562e0027d21bf64838178e2f5157df3d5833972e (patch) | |
tree | d8585abbc8a255539c33663f850b7832bf0b4dbd | |
parent | baeeb8229cace91c10c856d91e5ca861d3c44968 (diff) |
ARM: GIC: Add global gic_handle_irq() function
Provide the GIC code with a low level handler that can be used
by platforms using CONFIG_MULTI_IRQ_HANDLER.
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
-rw-r--r-- | arch/arm/common/gic.c | 27 | ||||
-rw-r--r-- | arch/arm/include/asm/hardware/gic.h | 1 |
2 files changed, 28 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); |
diff --git a/arch/arm/include/asm/hardware/gic.h b/arch/arm/include/asm/hardware/gic.h index 2721d90625e5..ecf7c02fa16c 100644 --- a/arch/arm/include/asm/hardware/gic.h +++ b/arch/arm/include/asm/hardware/gic.h | |||
@@ -43,6 +43,7 @@ void gic_init_bases(unsigned int, int, void __iomem *, void __iomem *, | |||
43 | u32 offset); | 43 | u32 offset); |
44 | int gic_of_init(struct device_node *node, struct device_node *parent); | 44 | int gic_of_init(struct device_node *node, struct device_node *parent); |
45 | void gic_secondary_init(unsigned int); | 45 | void gic_secondary_init(unsigned int); |
46 | void gic_handle_irq(struct pt_regs *regs); | ||
46 | void gic_cascade_irq(unsigned int gic_nr, unsigned int irq); | 47 | void gic_cascade_irq(unsigned int gic_nr, unsigned int irq); |
47 | void gic_raise_softirq(const struct cpumask *mask, unsigned int irq); | 48 | void gic_raise_softirq(const struct cpumask *mask, unsigned int irq); |
48 | 49 | ||