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>
This commit is contained in:
Jeffrey Deans 2014-07-17 09:20:58 +01:00 committed by Ralf Baechle
parent 31521a7a64
commit 1c772b5664
1 changed files with 18 additions and 7 deletions

View File

@ -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);
gic_get_int_mask(pending, ipi_ints);
irq = find_first_bit(pending, GIC_NUM_INTRS);
while (irq < GIC_NUM_INTRS) {
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);
irq = gic_get_int();
if (irq < 0)
return; /* interrupt has already been cleared */
do_IRQ(MIPS_GIC_IRQ_BASE + irq);
}
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)