Skip to content

Commit b8b0145

Browse files
XBurstMarc Zyngier
authored andcommitted
irqchip: Ingenic: Add process for more than one irq at the same time.
Add process for the situation that more than one irq is coming to a single chip at the same time. The original code will only respond to the lowest setted bit in JZ_REG_INTC_PENDING, and then exit the interrupt dispatch function. After exiting the interrupt dispatch function, since the second interrupt has not yet responded, the interrupt dispatch function is again entered to process the second interrupt. This creates additional unnecessary overhead, and the more interrupts that occur at the same time, the more overhead is added. The improved method in this patch is to check whether there are still unresponsive interrupts after processing the lowest setted bit interrupt. If there are any, the processing will be processed according to the bit in JZ_REG_INTC_PENDING, and the interrupt dispatch function will be exited until all processing is completed. Signed-off-by: Zhou Yanjie <[email protected]> Signed-off-by: Marc Zyngier <[email protected]> Reviewed-by: Paul Cercueil <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 8bc7464 commit b8b0145

File tree

1 file changed

+11
-6
lines changed

1 file changed

+11
-6
lines changed

drivers/irqchip/irq-ingenic.c

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// SPDX-License-Identifier: GPL-2.0-or-later
22
/*
33
* Copyright (C) 2009-2010, Lars-Peter Clausen <[email protected]>
4-
* JZ4740 platform IRQ support
4+
* Ingenic XBurst platform IRQ support
55
*/
66

77
#include <linux/errno.h>
@@ -37,18 +37,23 @@ static irqreturn_t intc_cascade(int irq, void *data)
3737
struct ingenic_intc_data *intc = irq_get_handler_data(irq);
3838
struct irq_domain *domain = intc->domain;
3939
struct irq_chip_generic *gc;
40-
uint32_t irq_reg;
40+
uint32_t pending;
4141
unsigned i;
4242

4343
for (i = 0; i < intc->num_chips; i++) {
4444
gc = irq_get_domain_generic_chip(domain, i * 32);
4545

46-
irq_reg = irq_reg_readl(gc, JZ_REG_INTC_PENDING);
47-
if (!irq_reg)
46+
pending = irq_reg_readl(gc, JZ_REG_INTC_PENDING);
47+
if (!pending)
4848
continue;
4949

50-
irq = irq_find_mapping(domain, __fls(irq_reg) + (i * 32));
51-
generic_handle_irq(irq);
50+
while (pending) {
51+
int bit = __fls(pending);
52+
53+
irq = irq_find_mapping(domain, bit + (i * 32));
54+
generic_handle_irq(irq);
55+
pending &= ~BIT(bit);
56+
}
5257
}
5358

5459
return IRQ_HANDLED;

0 commit comments

Comments
 (0)