Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 56af0416 authored by Hans de Goede's avatar Hans de Goede Committed by Thomas Gleixner
Browse files

irqchip: sun4i: Fix irq 0 not working



SUN4I_IRQ_VECTOR_REG containing 0 can mean one of 3 things:

1) no more irqs pending
2) irq 0 pending
3) spurious irq

So if we immediately get a reading of 0, check the irq-pending reg
to differentiate between 2 and 3. We only do this once to avoid
the extra check in the common case of 1) hapening after having
read the vector-reg once.

Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
Acked-by: default avatarMaxime Ripard <maxime.ripard@free-electrons.com>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-sunxi@googlegroups.com
Link: http://lkml.kernel.org/r/1394733834-26839-3-git-send-email-hdegoede@redhat.com


Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
parent 328a4978
Loading
Loading
Loading
Loading
+16 −2
Original line number Diff line number Diff line
@@ -140,10 +140,24 @@ static void __exception_irq_entry sun4i_handle_irq(struct pt_regs *regs)
{
	u32 irq, hwirq;

	/*
	 * hwirq == 0 can mean one of 3 things:
	 * 1) no more irqs pending
	 * 2) irq 0 pending
	 * 3) spurious irq
	 * So if we immediately get a reading of 0, check the irq-pending reg
	 * to differentiate between 2 and 3. We only do this once to avoid
	 * the extra check in the common case of 1 hapening after having
	 * read the vector-reg once.
	 */
	hwirq = readl(sun4i_irq_base + SUN4I_IRQ_VECTOR_REG) >> 2;
	while (hwirq != 0) {
	if (hwirq == 0 &&
		  !(readl(sun4i_irq_base + SUN4I_IRQ_PENDING_REG(0)) & BIT(0)))
		return;

	do {
		irq = irq_find_mapping(sun4i_irq_domain, hwirq);
		handle_IRQ(irq, regs);
		hwirq = readl(sun4i_irq_base + SUN4I_IRQ_VECTOR_REG) >> 2;
	}
	} while (hwirq != 0);
}