diff options
author | Will Deacon <will.deacon@arm.com> | 2012-04-04 10:13:49 +0100 |
---|---|---|
committer | Marc Zyngier <marc.zyngier@arm.com> | 2012-04-20 14:55:15 +0100 |
commit | a38d59c28b8fe0ecc00beb4b57b11490105fc1fb (patch) | |
tree | eba0db78e9188f13ad15ff8c5b8218ad363a5712 /arch/arm | |
parent | cb0ec30dee53229a03f0a41a6010df93450da16b (diff) |
ARM: vic: re-read status register before dispatching each IRQ handler
handle_IRQ may briefly cause interrupts to be re-enabled during soft IRQ
processing on the exit path, leading to nested handling of VIC interrupts.
Since the current code does not re-read the VIC_IRQ_STATUS register, this
can lead to multiple invocations of the same interrupt handler and
spurious interrupts to be reported.
This patch changes the VIC interrupt dispatching code to re-read the
status register each time, avoiding duplicate invocations of the same
handler.
Acked-and-tested-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Jamie Iles <jamie@jamieiles.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/common/vic.c | 4 |
1 files changed, 1 insertions, 3 deletions
diff --git a/arch/arm/common/vic.c b/arch/arm/common/vic.c index dcb004a804c7..cb6b49adaae1 100644 --- a/arch/arm/common/vic.c +++ b/arch/arm/common/vic.c @@ -441,11 +441,9 @@ static int handle_one_vic(struct vic_device *vic, struct pt_regs *regs) u32 stat, irq; int handled = 0; - stat = readl_relaxed(vic->base + VIC_IRQ_STATUS); - while (stat) { + while ((stat = readl_relaxed(vic->base + VIC_IRQ_STATUS))) { irq = ffs(stat) - 1; handle_IRQ(irq_domain_to_irq(&vic->domain, irq), regs); - stat &= ~(1 << irq); handled = 1; } |