提交 1c772b56 编写于 作者: J Jeffrey Deans 提交者: Ralf Baechle

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: NJeffrey Deans <jeffrey.deans@imgtec.com>
Signed-off-by: NMarkos Chandras <markos.chandras@imgtec.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/7377/Signed-off-by: NRalf Baechle <ralf@linux-mips.org>
上级 31521a7a
...@@ -42,6 +42,10 @@ static unsigned int ipi_map[NR_CPUS]; ...@@ -42,6 +42,10 @@ static unsigned int ipi_map[NR_CPUS];
static DEFINE_RAW_SPINLOCK(mips_irq_lock); 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) static inline int mips_pcibios_iack(void)
{ {
int irq; int irq;
...@@ -125,16 +129,22 @@ static void malta_hw0_irqdispatch(void) ...@@ -125,16 +129,22 @@ static void malta_hw0_irqdispatch(void)
static void malta_ipi_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()) gic_get_int_mask(pending, ipi_ints);
do_IRQ(MIPS_GIC_IRQ_BASE);
irq = find_first_bit(pending, GIC_NUM_INTRS);
irq = gic_get_int(); while (irq < GIC_NUM_INTRS) {
if (irq < 0) do_IRQ(MIPS_GIC_IRQ_BASE + irq);
return; /* interrupt has already been cleared */
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) static void corehi_irqdispatch(void)
...@@ -429,6 +439,7 @@ static void __init fill_ipi_map1(int baseintr, int cpu, int cpupin) ...@@ -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].trigtype = GIC_TRIG_EDGE;
gic_intr_map[intr].flags = 0; gic_intr_map[intr].flags = 0;
ipi_map[cpu] |= (1 << (cpupin + 2)); ipi_map[cpu] |= (1 << (cpupin + 2));
bitmap_set(ipi_ints, intr, 1);
} }
static void __init fill_ipi_map(void) static void __init fill_ipi_map(void)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册