1/* 2 * Interrupt controller driver for Xilinx Virtex FPGAs 3 * 4 * Copyright (C) 2007 Secret Lab Technologies Ltd. 5 * 6 * This file is licensed under the terms of the GNU General Public License 7 * version 2. This program is licensed "as is" without any warranty of any 8 * kind, whether express or implied. 9 * 10 */ 11 12/* 13 * This is a driver for the interrupt controller typically found in 14 * Xilinx Virtex FPGA designs. 15 * 16 * The interrupt sense levels are hard coded into the FPGA design with 17 * typically a 1:1 relationship between irq lines and devices (no shared 18 * irq lines). Therefore, this driver does not attempt to handle edge 19 * and level interrupts differently. 20 */ 21#undef DEBUG 22 23#include <linux/kernel.h> 24#include <linux/irq.h> 25#include <linux/of.h> 26#include <linux/of_address.h> 27#include <linux/of_irq.h> 28#include <asm/io.h> 29#include <asm/processor.h> 30#include <asm/i8259.h> 31#include <asm/irq.h> 32 33/* 34 * INTC Registers 35 */ 36#define XINTC_ISR 0 /* Interrupt Status */ 37#define XINTC_IPR 4 /* Interrupt Pending */ 38#define XINTC_IER 8 /* Interrupt Enable */ 39#define XINTC_IAR 12 /* Interrupt Acknowledge */ 40#define XINTC_SIE 16 /* Set Interrupt Enable bits */ 41#define XINTC_CIE 20 /* Clear Interrupt Enable bits */ 42#define XINTC_IVR 24 /* Interrupt Vector */ 43#define XINTC_MER 28 /* Master Enable */ 44 45static struct irq_domain *master_irqhost; 46 47#define XILINX_INTC_MAXIRQS (32) 48 49/* The following table allows the interrupt type, edge or level, 50 * to be cached after being read from the device tree until the interrupt 51 * is mapped 52 */ 53static int xilinx_intc_typetable[XILINX_INTC_MAXIRQS]; 54 55/* Map the interrupt type from the device tree to the interrupt types 56 * used by the interrupt subsystem 57 */ 58static unsigned char xilinx_intc_map_senses[] = { 59 IRQ_TYPE_EDGE_RISING, 60 IRQ_TYPE_EDGE_FALLING, 61 IRQ_TYPE_LEVEL_HIGH, 62 IRQ_TYPE_LEVEL_LOW, 63}; 64 65/* 66 * The interrupt controller is setup such that it doesn't work well with 67 * the level interrupt handler in the kernel because the handler acks the 68 * interrupt before calling the application interrupt handler. To deal with 69 * that, we use 2 different irq chips so that different functions can be 70 * used for level and edge type interrupts. 71 * 72 * IRQ Chip common (across level and edge) operations 73 */ 74static void xilinx_intc_mask(struct irq_data *d) 75{ 76 int irq = irqd_to_hwirq(d); 77 void * regs = irq_data_get_irq_chip_data(d); 78 pr_debug("mask: %d\n", irq); 79 out_be32(regs + XINTC_CIE, 1 << irq); 80} 81 82static int xilinx_intc_set_type(struct irq_data *d, unsigned int flow_type) 83{ 84 return 0; 85} 86 87/* 88 * IRQ Chip level operations 89 */ 90static void xilinx_intc_level_unmask(struct irq_data *d) 91{ 92 int irq = irqd_to_hwirq(d); 93 void * regs = irq_data_get_irq_chip_data(d); 94 pr_debug("unmask: %d\n", irq); 95 out_be32(regs + XINTC_SIE, 1 << irq); 96 97 /* ack level irqs because they can't be acked during 98 * ack function since the handle_level_irq function 99 * acks the irq before calling the inerrupt handler 100 */ 101 out_be32(regs + XINTC_IAR, 1 << irq); 102} 103 104static struct irq_chip xilinx_intc_level_irqchip = { 105 .name = "Xilinx Level INTC", 106 .irq_mask = xilinx_intc_mask, 107 .irq_mask_ack = xilinx_intc_mask, 108 .irq_unmask = xilinx_intc_level_unmask, 109 .irq_set_type = xilinx_intc_set_type, 110}; 111 112/* 113 * IRQ Chip edge operations 114 */ 115static void xilinx_intc_edge_unmask(struct irq_data *d) 116{ 117 int irq = irqd_to_hwirq(d); 118 void *regs = irq_data_get_irq_chip_data(d); 119 pr_debug("unmask: %d\n", irq); 120 out_be32(regs + XINTC_SIE, 1 << irq); 121} 122 123static void xilinx_intc_edge_ack(struct irq_data *d) 124{ 125 int irq = irqd_to_hwirq(d); 126 void * regs = irq_data_get_irq_chip_data(d); 127 pr_debug("ack: %d\n", irq); 128 out_be32(regs + XINTC_IAR, 1 << irq); 129} 130 131static struct irq_chip xilinx_intc_edge_irqchip = { 132 .name = "Xilinx Edge INTC", 133 .irq_mask = xilinx_intc_mask, 134 .irq_unmask = xilinx_intc_edge_unmask, 135 .irq_ack = xilinx_intc_edge_ack, 136 .irq_set_type = xilinx_intc_set_type, 137}; 138 139/* 140 * IRQ Host operations 141 */ 142 143/** 144 * xilinx_intc_xlate - translate virq# from device tree interrupts property 145 */ 146static int xilinx_intc_xlate(struct irq_domain *h, struct device_node *ct, 147 const u32 *intspec, unsigned int intsize, 148 irq_hw_number_t *out_hwirq, 149 unsigned int *out_flags) 150{ 151 if ((intsize < 2) || (intspec[0] >= XILINX_INTC_MAXIRQS)) 152 return -EINVAL; 153 154 /* keep a copy of the interrupt type til the interrupt is mapped 155 */ 156 xilinx_intc_typetable[intspec[0]] = xilinx_intc_map_senses[intspec[1]]; 157 158 /* Xilinx uses 2 interrupt entries, the 1st being the h/w 159 * interrupt number, the 2nd being the interrupt type, edge or level 160 */ 161 *out_hwirq = intspec[0]; 162 *out_flags = xilinx_intc_map_senses[intspec[1]]; 163 164 return 0; 165} 166static int xilinx_intc_map(struct irq_domain *h, unsigned int virq, 167 irq_hw_number_t irq) 168{ 169 irq_set_chip_data(virq, h->host_data); 170 171 if (xilinx_intc_typetable[irq] == IRQ_TYPE_LEVEL_HIGH || 172 xilinx_intc_typetable[irq] == IRQ_TYPE_LEVEL_LOW) { 173 irq_set_chip_and_handler(virq, &xilinx_intc_level_irqchip, 174 handle_level_irq); 175 } else { 176 irq_set_chip_and_handler(virq, &xilinx_intc_edge_irqchip, 177 handle_edge_irq); 178 } 179 return 0; 180} 181 182static struct irq_domain_ops xilinx_intc_ops = { 183 .map = xilinx_intc_map, 184 .xlate = xilinx_intc_xlate, 185}; 186 187struct irq_domain * __init 188xilinx_intc_init(struct device_node *np) 189{ 190 struct irq_domain * irq; 191 void * regs; 192 193 /* Find and map the intc registers */ 194 regs = of_iomap(np, 0); 195 if (!regs) { 196 pr_err("xilinx_intc: could not map registers\n"); 197 return NULL; 198 } 199 200 /* Setup interrupt controller */ 201 out_be32(regs + XINTC_IER, 0); /* disable all irqs */ 202 out_be32(regs + XINTC_IAR, ~(u32) 0); /* Acknowledge pending irqs */ 203 out_be32(regs + XINTC_MER, 0x3UL); /* Turn on the Master Enable. */ 204 205 /* Allocate and initialize an irq_domain structure. */ 206 irq = irq_domain_add_linear(np, XILINX_INTC_MAXIRQS, &xilinx_intc_ops, 207 regs); 208 if (!irq) 209 panic(__FILE__ ": Cannot allocate IRQ host\n"); 210 211 return irq; 212} 213 214int xilinx_intc_get_irq(void) 215{ 216 void * regs = master_irqhost->host_data; 217 pr_debug("get_irq:\n"); 218 return irq_linear_revmap(master_irqhost, in_be32(regs + XINTC_IVR)); 219} 220 221#if defined(CONFIG_PPC_I8259) 222/* 223 * Support code for cascading to 8259 interrupt controllers 224 */ 225static void xilinx_i8259_cascade(unsigned int irq, struct irq_desc *desc) 226{ 227 struct irq_chip *chip = irq_desc_get_chip(desc); 228 unsigned int cascade_irq = i8259_irq(); 229 230 if (cascade_irq) 231 generic_handle_irq(cascade_irq); 232 233 /* Let xilinx_intc end the interrupt */ 234 chip->irq_unmask(&desc->irq_data); 235} 236 237static void __init xilinx_i8259_setup_cascade(void) 238{ 239 struct device_node *cascade_node; 240 int cascade_irq; 241 242 /* Initialize i8259 controller */ 243 cascade_node = of_find_compatible_node(NULL, NULL, "chrp,iic"); 244 if (!cascade_node) 245 return; 246 247 cascade_irq = irq_of_parse_and_map(cascade_node, 0); 248 if (!cascade_irq) { 249 pr_err("virtex_ml510: Failed to map cascade interrupt\n"); 250 goto out; 251 } 252 253 i8259_init(cascade_node, 0); 254 irq_set_chained_handler(cascade_irq, xilinx_i8259_cascade); 255 256 /* Program irq 7 (usb/audio), 14/15 (ide) to level sensitive */ 257 /* This looks like a dirty hack to me --gcl */ 258 outb(0xc0, 0x4d0); 259 outb(0xc0, 0x4d1); 260 261 out: 262 of_node_put(cascade_node); 263} 264#else 265static inline void xilinx_i8259_setup_cascade(void) { return; } 266#endif /* defined(CONFIG_PPC_I8259) */ 267 268static const struct of_device_id xilinx_intc_match[] __initconst = { 269 { .compatible = "xlnx,opb-intc-1.00.c", }, 270 { .compatible = "xlnx,xps-intc-1.00.a", }, 271 {} 272}; 273 274/* 275 * Initialize master Xilinx interrupt controller 276 */ 277void __init xilinx_intc_init_tree(void) 278{ 279 struct device_node *np; 280 281 /* find top level interrupt controller */ 282 for_each_matching_node(np, xilinx_intc_match) { 283 if (!of_get_property(np, "interrupts", NULL)) 284 break; 285 } 286 BUG_ON(!np); 287 288 master_irqhost = xilinx_intc_init(np); 289 BUG_ON(!master_irqhost); 290 291 irq_set_default_host(master_irqhost); 292 of_node_put(np); 293 294 xilinx_i8259_setup_cascade(); 295} 296