1/* 2 * Support for Versatile FPGA-based IRQ controllers 3 */ 4#include <linux/bitops.h> 5#include <linux/irq.h> 6#include <linux/io.h> 7#include <linux/irqchip/versatile-fpga.h> 8#include <linux/irqdomain.h> 9#include <linux/module.h> 10#include <linux/of.h> 11#include <linux/of_address.h> 12#include <linux/of_irq.h> 13 14#include <asm/exception.h> 15#include <asm/mach/irq.h> 16 17#include "irqchip.h" 18 19#define IRQ_STATUS 0x00 20#define IRQ_RAW_STATUS 0x04 21#define IRQ_ENABLE_SET 0x08 22#define IRQ_ENABLE_CLEAR 0x0c 23#define INT_SOFT_SET 0x10 24#define INT_SOFT_CLEAR 0x14 25#define FIQ_STATUS 0x20 26#define FIQ_RAW_STATUS 0x24 27#define FIQ_ENABLE 0x28 28#define FIQ_ENABLE_SET 0x28 29#define FIQ_ENABLE_CLEAR 0x2C 30 31#define PIC_ENABLES 0x20 /* set interrupt pass through bits */ 32 33/** 34 * struct fpga_irq_data - irq data container for the FPGA IRQ controller 35 * @base: memory offset in virtual memory 36 * @chip: chip container for this instance 37 * @domain: IRQ domain for this instance 38 * @valid: mask for valid IRQs on this controller 39 * @used_irqs: number of active IRQs on this controller 40 */ 41struct fpga_irq_data { 42 void __iomem *base; 43 struct irq_chip chip; 44 u32 valid; 45 struct irq_domain *domain; 46 u8 used_irqs; 47}; 48 49/* we cannot allocate memory when the controllers are initially registered */ 50static struct fpga_irq_data fpga_irq_devices[CONFIG_VERSATILE_FPGA_IRQ_NR]; 51static int fpga_irq_id; 52 53static void fpga_irq_mask(struct irq_data *d) 54{ 55 struct fpga_irq_data *f = irq_data_get_irq_chip_data(d); 56 u32 mask = 1 << d->hwirq; 57 58 writel(mask, f->base + IRQ_ENABLE_CLEAR); 59} 60 61static void fpga_irq_unmask(struct irq_data *d) 62{ 63 struct fpga_irq_data *f = irq_data_get_irq_chip_data(d); 64 u32 mask = 1 << d->hwirq; 65 66 writel(mask, f->base + IRQ_ENABLE_SET); 67} 68 69static void fpga_irq_handle(unsigned int irq, struct irq_desc *desc) 70{ 71 struct fpga_irq_data *f = irq_desc_get_handler_data(desc); 72 u32 status = readl(f->base + IRQ_STATUS); 73 74 if (status == 0) { 75 do_bad_IRQ(irq, desc); 76 return; 77 } 78 79 do { 80 irq = ffs(status) - 1; 81 status &= ~(1 << irq); 82 generic_handle_irq(irq_find_mapping(f->domain, irq)); 83 } while (status); 84} 85 86/* 87 * Handle each interrupt in a single FPGA IRQ controller. Returns non-zero 88 * if we've handled at least one interrupt. This does a single read of the 89 * status register and handles all interrupts in order from LSB first. 90 */ 91static int handle_one_fpga(struct fpga_irq_data *f, struct pt_regs *regs) 92{ 93 int handled = 0; 94 int irq; 95 u32 status; 96 97 while ((status = readl(f->base + IRQ_STATUS))) { 98 irq = ffs(status) - 1; 99 handle_domain_irq(f->domain, irq, regs); 100 handled = 1; 101 } 102 103 return handled; 104} 105 106/* 107 * Keep iterating over all registered FPGA IRQ controllers until there are 108 * no pending interrupts. 109 */ 110asmlinkage void __exception_irq_entry fpga_handle_irq(struct pt_regs *regs) 111{ 112 int i, handled; 113 114 do { 115 for (i = 0, handled = 0; i < fpga_irq_id; ++i) 116 handled |= handle_one_fpga(&fpga_irq_devices[i], regs); 117 } while (handled); 118} 119 120static int fpga_irqdomain_map(struct irq_domain *d, unsigned int irq, 121 irq_hw_number_t hwirq) 122{ 123 struct fpga_irq_data *f = d->host_data; 124 125 /* Skip invalid IRQs, only register handlers for the real ones */ 126 if (!(f->valid & BIT(hwirq))) 127 return -EPERM; 128 irq_set_chip_data(irq, f); 129 irq_set_chip_and_handler(irq, &f->chip, 130 handle_level_irq); 131 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); 132 return 0; 133} 134 135static struct irq_domain_ops fpga_irqdomain_ops = { 136 .map = fpga_irqdomain_map, 137 .xlate = irq_domain_xlate_onetwocell, 138}; 139 140void __init fpga_irq_init(void __iomem *base, const char *name, int irq_start, 141 int parent_irq, u32 valid, struct device_node *node) 142{ 143 struct fpga_irq_data *f; 144 int i; 145 146 if (fpga_irq_id >= ARRAY_SIZE(fpga_irq_devices)) { 147 pr_err("%s: too few FPGA IRQ controllers, increase CONFIG_VERSATILE_FPGA_IRQ_NR\n", __func__); 148 return; 149 } 150 f = &fpga_irq_devices[fpga_irq_id]; 151 f->base = base; 152 f->chip.name = name; 153 f->chip.irq_ack = fpga_irq_mask; 154 f->chip.irq_mask = fpga_irq_mask; 155 f->chip.irq_unmask = fpga_irq_unmask; 156 f->valid = valid; 157 158 if (parent_irq != -1) { 159 irq_set_handler_data(parent_irq, f); 160 irq_set_chained_handler(parent_irq, fpga_irq_handle); 161 } 162 163 /* This will also allocate irq descriptors */ 164 f->domain = irq_domain_add_simple(node, fls(valid), irq_start, 165 &fpga_irqdomain_ops, f); 166 167 /* This will allocate all valid descriptors in the linear case */ 168 for (i = 0; i < fls(valid); i++) 169 if (valid & BIT(i)) { 170 if (!irq_start) 171 irq_create_mapping(f->domain, i); 172 f->used_irqs++; 173 } 174 175 pr_info("FPGA IRQ chip %d \"%s\" @ %p, %u irqs", 176 fpga_irq_id, name, base, f->used_irqs); 177 if (parent_irq != -1) 178 pr_cont(", parent IRQ: %d\n", parent_irq); 179 else 180 pr_cont("\n"); 181 182 fpga_irq_id++; 183} 184 185#ifdef CONFIG_OF 186int __init fpga_irq_of_init(struct device_node *node, 187 struct device_node *parent) 188{ 189 void __iomem *base; 190 u32 clear_mask; 191 u32 valid_mask; 192 int parent_irq; 193 194 if (WARN_ON(!node)) 195 return -ENODEV; 196 197 base = of_iomap(node, 0); 198 WARN(!base, "unable to map fpga irq registers\n"); 199 200 if (of_property_read_u32(node, "clear-mask", &clear_mask)) 201 clear_mask = 0; 202 203 if (of_property_read_u32(node, "valid-mask", &valid_mask)) 204 valid_mask = 0; 205 206 /* Some chips are cascaded from a parent IRQ */ 207 parent_irq = irq_of_parse_and_map(node, 0); 208 if (!parent_irq) { 209 set_handle_irq(fpga_handle_irq); 210 parent_irq = -1; 211 } 212 213 fpga_irq_init(base, node->name, 0, parent_irq, valid_mask, node); 214 215 writel(clear_mask, base + IRQ_ENABLE_CLEAR); 216 writel(clear_mask, base + FIQ_ENABLE_CLEAR); 217 218 /* 219 * On Versatile AB/PB, some secondary interrupts have a direct 220 * pass-thru to the primary controller for IRQs 20 and 22-31 which need 221 * to be enabled. See section 3.10 of the Versatile AB user guide. 222 */ 223 if (of_device_is_compatible(node, "arm,versatile-sic")) 224 writel(0xffd00000, base + PIC_ENABLES); 225 226 return 0; 227} 228IRQCHIP_DECLARE(arm_fpga, "arm,versatile-fpga-irq", fpga_irq_of_init); 229IRQCHIP_DECLARE(arm_fpga_sic, "arm,versatile-sic", fpga_irq_of_init); 230#endif 231