diff options
author | Jeffrey Deans <jeffrey.deans@imgtec.com> | 2014-07-17 09:20:58 +0100 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2014-08-02 00:06:41 +0200 |
commit | 1c772b5664d9efa8d8d25b69b4ea8ae8996d6153 (patch) | |
tree | 9ff73849a38884773d291383298263d5e0b7d624 /arch/mips | |
parent | 31521a7a64bc5df5202e479ee7ba8133993ab32a (diff) | |
download | blackbird-op-linux-1c772b5664d9efa8d8d25b69b4ea8ae8996d6153.tar.gz blackbird-op-linux-1c772b5664d9efa8d8d25b69b4ea8ae8996d6153.zip |
MIPS: Malta: Fix dispatching of GIC interrupts
The Malta malta_ipi_irqdispatch() routine now checks only IPI interrupts
when handling IPIs. It could previously call do_IRQ() for non-IPIs, and
also call do_IRQ() with an invalid IRQ number if there were no pending
GIC interrupts when gic_get_int() was called.
Signed-off-by: Jeffrey Deans <jeffrey.deans@imgtec.com>
Signed-off-by: Markos Chandras <markos.chandras@imgtec.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/7377/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips')
-rw-r--r-- | arch/mips/mti-malta/malta-int.c | 25 |
1 files changed, 18 insertions, 7 deletions
diff --git a/arch/mips/mti-malta/malta-int.c b/arch/mips/mti-malta/malta-int.c index 4ab919141737..e4f43baa8f67 100644 --- a/arch/mips/mti-malta/malta-int.c +++ b/arch/mips/mti-malta/malta-int.c @@ -42,6 +42,10 @@ static unsigned int ipi_map[NR_CPUS]; static DEFINE_RAW_SPINLOCK(mips_irq_lock); +#ifdef CONFIG_MIPS_GIC_IPI +DECLARE_BITMAP(ipi_ints, GIC_NUM_INTRS); +#endif + static inline int mips_pcibios_iack(void) { int irq; @@ -125,16 +129,22 @@ static void malta_hw0_irqdispatch(void) static void malta_ipi_irqdispatch(void) { - int irq; +#ifdef CONFIG_MIPS_GIC_IPI + unsigned long irq; + DECLARE_BITMAP(pending, GIC_NUM_INTRS); - if (gic_compare_int()) - do_IRQ(MIPS_GIC_IRQ_BASE); + gic_get_int_mask(pending, ipi_ints); + + irq = find_first_bit(pending, GIC_NUM_INTRS); - irq = gic_get_int(); - if (irq < 0) - return; /* interrupt has already been cleared */ + while (irq < GIC_NUM_INTRS) { + do_IRQ(MIPS_GIC_IRQ_BASE + irq); - do_IRQ(MIPS_GIC_IRQ_BASE + irq); + irq = find_next_bit(pending, GIC_NUM_INTRS, irq + 1); + } +#endif + if (gic_compare_int()) + do_IRQ(MIPS_GIC_IRQ_BASE); } static void corehi_irqdispatch(void) @@ -429,6 +439,7 @@ static void __init fill_ipi_map1(int baseintr, int cpu, int cpupin) gic_intr_map[intr].trigtype = GIC_TRIG_EDGE; gic_intr_map[intr].flags = 0; ipi_map[cpu] |= (1 << (cpupin + 2)); + bitmap_set(ipi_ints, intr, 1); } static void __init fill_ipi_map(void) |