Loading arch/microblaze/Kconfig +0 −2 Original line number Diff line number Diff line Loading @@ -47,8 +47,6 @@ config MICROBLAZE select CPU_NO_EFFICIENT_FFS select MMU_GATHER_NO_RANGE if MMU select SPARSE_IRQ select GENERIC_IRQ_MULTI_HANDLER select HANDLE_DOMAIN_IRQ # Endianness selection choice Loading arch/microblaze/include/asm/irq.h +3 −0 Original line number Diff line number Diff line Loading @@ -14,4 +14,7 @@ struct pt_regs; extern void do_IRQ(struct pt_regs *regs); /* should be defined in each interrupt controller driver */ extern unsigned int xintc_get_irq(void); #endif /* _ASM_MICROBLAZE_IRQ_H */ arch/microblaze/kernel/irq.c +20 −1 Original line number Diff line number Diff line Loading @@ -20,10 +20,29 @@ #include <linux/irqchip.h> #include <linux/of_irq.h> static u32 concurrent_irq; void __irq_entry do_IRQ(struct pt_regs *regs) { unsigned int irq; struct pt_regs *old_regs = set_irq_regs(regs); trace_hardirqs_off(); handle_arch_irq(regs); irq_enter(); irq = xintc_get_irq(); next_irq: BUG_ON(!irq); generic_handle_irq(irq); irq = xintc_get_irq(); if (irq != -1U) { pr_debug("next irq: %d\n", irq); ++concurrent_irq; goto next_irq; } irq_exit(); set_irq_regs(old_regs); trace_hardirqs_on(); } Loading drivers/irqchip/irq-xilinx-intc.c +15 −20 Original line number Diff line number Diff line Loading @@ -124,6 +124,20 @@ static unsigned int xintc_get_irq_local(struct xintc_irq_chip *irqc) return irq; } unsigned int xintc_get_irq(void) { unsigned int irq = -1; u32 hwirq; hwirq = xintc_read(primary_intc, IVR); if (hwirq != -1U) irq = irq_find_mapping(primary_intc->root_domain, hwirq); pr_debug("irq-xilinx: hwirq=%d, irq=%d\n", hwirq, irq); return irq; } static int xintc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) { struct xintc_irq_chip *irqc = d->host_data; Loading Loading @@ -163,25 +177,6 @@ static void xil_intc_irq_handler(struct irq_desc *desc) chained_irq_exit(chip, desc); } static void xil_intc_handle_irq(struct pt_regs *regs) { u32 hwirq; struct xintc_irq_chip *irqc = primary_intc; do { hwirq = xintc_read(irqc, IVR); if (likely(hwirq != -1U)) { int ret; ret = handle_domain_irq(irqc->root_domain, hwirq, regs); WARN_ONCE(ret, "Unhandled HWIRQ %d\n", hwirq); continue; } break; } while (1); } static int __init xilinx_intc_of_init(struct device_node *intc, struct device_node *parent) { Loading Loading @@ -250,7 +245,7 @@ static int __init xilinx_intc_of_init(struct device_node *intc, } } else { primary_intc = irqc; set_handle_irq(xil_intc_handle_irq); irq_set_default_host(primary_intc->root_domain); } return 0; Loading Loading
arch/microblaze/Kconfig +0 −2 Original line number Diff line number Diff line Loading @@ -47,8 +47,6 @@ config MICROBLAZE select CPU_NO_EFFICIENT_FFS select MMU_GATHER_NO_RANGE if MMU select SPARSE_IRQ select GENERIC_IRQ_MULTI_HANDLER select HANDLE_DOMAIN_IRQ # Endianness selection choice Loading
arch/microblaze/include/asm/irq.h +3 −0 Original line number Diff line number Diff line Loading @@ -14,4 +14,7 @@ struct pt_regs; extern void do_IRQ(struct pt_regs *regs); /* should be defined in each interrupt controller driver */ extern unsigned int xintc_get_irq(void); #endif /* _ASM_MICROBLAZE_IRQ_H */
arch/microblaze/kernel/irq.c +20 −1 Original line number Diff line number Diff line Loading @@ -20,10 +20,29 @@ #include <linux/irqchip.h> #include <linux/of_irq.h> static u32 concurrent_irq; void __irq_entry do_IRQ(struct pt_regs *regs) { unsigned int irq; struct pt_regs *old_regs = set_irq_regs(regs); trace_hardirqs_off(); handle_arch_irq(regs); irq_enter(); irq = xintc_get_irq(); next_irq: BUG_ON(!irq); generic_handle_irq(irq); irq = xintc_get_irq(); if (irq != -1U) { pr_debug("next irq: %d\n", irq); ++concurrent_irq; goto next_irq; } irq_exit(); set_irq_regs(old_regs); trace_hardirqs_on(); } Loading
drivers/irqchip/irq-xilinx-intc.c +15 −20 Original line number Diff line number Diff line Loading @@ -124,6 +124,20 @@ static unsigned int xintc_get_irq_local(struct xintc_irq_chip *irqc) return irq; } unsigned int xintc_get_irq(void) { unsigned int irq = -1; u32 hwirq; hwirq = xintc_read(primary_intc, IVR); if (hwirq != -1U) irq = irq_find_mapping(primary_intc->root_domain, hwirq); pr_debug("irq-xilinx: hwirq=%d, irq=%d\n", hwirq, irq); return irq; } static int xintc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) { struct xintc_irq_chip *irqc = d->host_data; Loading Loading @@ -163,25 +177,6 @@ static void xil_intc_irq_handler(struct irq_desc *desc) chained_irq_exit(chip, desc); } static void xil_intc_handle_irq(struct pt_regs *regs) { u32 hwirq; struct xintc_irq_chip *irqc = primary_intc; do { hwirq = xintc_read(irqc, IVR); if (likely(hwirq != -1U)) { int ret; ret = handle_domain_irq(irqc->root_domain, hwirq, regs); WARN_ONCE(ret, "Unhandled HWIRQ %d\n", hwirq); continue; } break; } while (1); } static int __init xilinx_intc_of_init(struct device_node *intc, struct device_node *parent) { Loading Loading @@ -250,7 +245,7 @@ static int __init xilinx_intc_of_init(struct device_node *intc, } } else { primary_intc = irqc; set_handle_irq(xil_intc_handle_irq); irq_set_default_host(primary_intc->root_domain); } return 0; Loading