mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-25 02:09:42 +00:00
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:
parent
31521a7a64
commit
1c772b5664
1 changed files with 18 additions and 7 deletions
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue