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