Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

irqchip/xilinx: Add support for parent intc

The MIPS based xilfpga platform has the following IRQ structure

Peripherals --> xilinx_intcontroller -> mips_cpu_int controller

Add support for the driver to chain the irq handler

Signed-off-by: Zubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>

authored by

Zubair Lutfullah Kakakhel and committed by
Marc Zyngier
9689c99e 2120a435

+32 -2
+32 -2
drivers/irqchip/irq-xilinx-intc.c
··· 12 12 #include <linux/irqdomain.h> 13 13 #include <linux/irq.h> 14 14 #include <linux/irqchip.h> 15 + #include <linux/irqchip/chained_irq.h> 15 16 #include <linux/of_address.h> 16 17 #include <linux/io.h> 17 18 #include <linux/jump_label.h> 18 19 #include <linux/bug.h> 20 + #include <linux/of_irq.h> 19 21 20 22 /* No one else should require these constants, so define them locally here. */ 21 23 #define ISR 0x00 /* Interrupt Status Register */ ··· 135 133 .map = xintc_map, 136 134 }; 137 135 136 + static void xil_intc_irq_handler(struct irq_desc *desc) 137 + { 138 + struct irq_chip *chip = irq_desc_get_chip(desc); 139 + u32 pending; 140 + 141 + chained_irq_enter(chip, desc); 142 + do { 143 + pending = xintc_get_irq(); 144 + if (pending == -1U) 145 + break; 146 + generic_handle_irq(pending); 147 + } while (true); 148 + chained_irq_exit(chip, desc); 149 + } 150 + 138 151 static int __init xilinx_intc_of_init(struct device_node *intc, 139 152 struct device_node *parent) 140 153 { 141 154 u32 nr_irq; 142 - int ret; 155 + int ret, irq; 143 156 struct xintc_irq_chip *irqc; 144 157 145 158 if (xintc_irqc) { ··· 213 196 goto err_alloc; 214 197 } 215 198 216 - irq_set_default_host(irqc->root_domain); 199 + if (parent) { 200 + irq = irq_of_parse_and_map(intc, 0); 201 + if (irq) { 202 + irq_set_chained_handler_and_data(irq, 203 + xil_intc_irq_handler, 204 + irqc); 205 + } else { 206 + pr_err("irq-xilinx: interrupts property not in DT\n"); 207 + ret = -EINVAL; 208 + goto err_alloc; 209 + } 210 + } else { 211 + irq_set_default_host(irqc->root_domain); 212 + } 217 213 218 214 return 0; 219 215