Skip to content

Commit a078999

Browse files
Michal SimekMarc Zyngier
authored andcommitted
irqchip/xilinx: Enable generic irq multi handler
Register default arch handler via driver instead of directly pointing to xilinx intc controller. This patch makes architecture code more generic. Driver calls generic domain specific irq handler which does the most of things self. Also get rid of concurrent_irq counting which hasn't been exported anywhere. Based on this loop was also optimized by using do/while loop instead of goto loop. Signed-off-by: Michal Simek <[email protected]> Signed-off-by: Marc Zyngier <[email protected]> Reviewed-by: Stefan Asserhall <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent c74038b commit a078999

File tree

4 files changed

+23
-37
lines changed

4 files changed

+23
-37
lines changed

arch/microblaze/Kconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ config MICROBLAZE
4747
select CPU_NO_EFFICIENT_FFS
4848
select MMU_GATHER_NO_RANGE if MMU
4949
select SPARSE_IRQ
50+
select GENERIC_IRQ_MULTI_HANDLER
51+
select HANDLE_DOMAIN_IRQ
5052

5153
# Endianness selection
5254
choice

arch/microblaze/include/asm/irq.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,4 @@
1414
struct pt_regs;
1515
extern void do_IRQ(struct pt_regs *regs);
1616

17-
/* should be defined in each interrupt controller driver */
18-
extern unsigned int xintc_get_irq(void);
19-
2017
#endif /* _ASM_MICROBLAZE_IRQ_H */

arch/microblaze/kernel/irq.c

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -20,29 +20,10 @@
2020
#include <linux/irqchip.h>
2121
#include <linux/of_irq.h>
2222

23-
static u32 concurrent_irq;
24-
2523
void __irq_entry do_IRQ(struct pt_regs *regs)
2624
{
27-
unsigned int irq;
28-
struct pt_regs *old_regs = set_irq_regs(regs);
2925
trace_hardirqs_off();
30-
31-
irq_enter();
32-
irq = xintc_get_irq();
33-
next_irq:
34-
BUG_ON(!irq);
35-
generic_handle_irq(irq);
36-
37-
irq = xintc_get_irq();
38-
if (irq != -1U) {
39-
pr_debug("next irq: %d\n", irq);
40-
++concurrent_irq;
41-
goto next_irq;
42-
}
43-
44-
irq_exit();
45-
set_irq_regs(old_regs);
26+
handle_arch_irq(regs);
4627
trace_hardirqs_on();
4728
}
4829

drivers/irqchip/irq-xilinx-intc.c

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -124,20 +124,6 @@ static unsigned int xintc_get_irq_local(struct xintc_irq_chip *irqc)
124124
return irq;
125125
}
126126

127-
unsigned int xintc_get_irq(void)
128-
{
129-
unsigned int irq = -1;
130-
u32 hwirq;
131-
132-
hwirq = xintc_read(primary_intc, IVR);
133-
if (hwirq != -1U)
134-
irq = irq_find_mapping(primary_intc->root_domain, hwirq);
135-
136-
pr_debug("irq-xilinx: hwirq=%d, irq=%d\n", hwirq, irq);
137-
138-
return irq;
139-
}
140-
141127
static int xintc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
142128
{
143129
struct xintc_irq_chip *irqc = d->host_data;
@@ -177,6 +163,25 @@ static void xil_intc_irq_handler(struct irq_desc *desc)
177163
chained_irq_exit(chip, desc);
178164
}
179165

166+
static void xil_intc_handle_irq(struct pt_regs *regs)
167+
{
168+
u32 hwirq;
169+
struct xintc_irq_chip *irqc = primary_intc;
170+
171+
do {
172+
hwirq = xintc_read(irqc, IVR);
173+
if (likely(hwirq != -1U)) {
174+
int ret;
175+
176+
ret = handle_domain_irq(irqc->root_domain, hwirq, regs);
177+
WARN_ONCE(ret, "Unhandled HWIRQ %d\n", hwirq);
178+
continue;
179+
}
180+
181+
break;
182+
} while (1);
183+
}
184+
180185
static int __init xilinx_intc_of_init(struct device_node *intc,
181186
struct device_node *parent)
182187
{
@@ -246,6 +251,7 @@ static int __init xilinx_intc_of_init(struct device_node *intc,
246251
} else {
247252
primary_intc = irqc;
248253
irq_set_default_host(primary_intc->root_domain);
254+
set_handle_irq(xil_intc_handle_irq);
249255
}
250256

251257
return 0;

0 commit comments

Comments
 (0)