diff options
Diffstat (limited to 'arch/arm/common/vic.c')
| -rw-r--r-- | arch/arm/common/vic.c | 9 |
1 files changed, 4 insertions, 5 deletions
diff --git a/arch/arm/common/vic.c b/arch/arm/common/vic.c index 7a66311f3066..7e288f96cedf 100644 --- a/arch/arm/common/vic.c +++ b/arch/arm/common/vic.c | |||
| @@ -427,19 +427,18 @@ int __init vic_of_init(struct device_node *node, struct device_node *parent) | |||
| 427 | 427 | ||
| 428 | /* | 428 | /* |
| 429 | * Handle each interrupt in a single VIC. Returns non-zero if we've | 429 | * Handle each interrupt in a single VIC. Returns non-zero if we've |
| 430 | * handled at least one interrupt. This does a single read of the | 430 | * handled at least one interrupt. This reads the status register |
| 431 | * status register and handles all interrupts in order from LSB first. | 431 | * before handling each interrupt, which is necessary given that |
| 432 | * handle_IRQ may briefly re-enable interrupts for soft IRQ handling. | ||
| 432 | */ | 433 | */ |
| 433 | static int handle_one_vic(struct vic_device *vic, struct pt_regs *regs) | 434 | static int handle_one_vic(struct vic_device *vic, struct pt_regs *regs) |
| 434 | { | 435 | { |
| 435 | u32 stat, irq; | 436 | u32 stat, irq; |
| 436 | int handled = 0; | 437 | int handled = 0; |
| 437 | 438 | ||
| 438 | stat = readl_relaxed(vic->base + VIC_IRQ_STATUS); | 439 | while ((stat = readl_relaxed(vic->base + VIC_IRQ_STATUS))) { |
| 439 | while (stat) { | ||
| 440 | irq = ffs(stat) - 1; | 440 | irq = ffs(stat) - 1; |
| 441 | handle_IRQ(irq_find_mapping(vic->domain, irq), regs); | 441 | handle_IRQ(irq_find_mapping(vic->domain, irq), regs); |
| 442 | stat &= ~(1 << irq); | ||
| 443 | handled = 1; | 442 | handled = 1; |
| 444 | } | 443 | } |
| 445 | 444 | ||
