xref: /linux/drivers/irqchip/irq-econet-en751221.c (revision 2ee2a685ee838fd103a306dab43f6969b61e9156)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * EN751221 Interrupt Controller Driver.
4  *
5  * The EcoNet EN751221 Interrupt Controller is a simple interrupt controller
6  * designed for the MIPS 34Kc MT SMP processor with 2 VPEs. Each interrupt can
7  * be routed to either VPE but not both, so to support per-CPU interrupts, a
8  * secondary IRQ number is allocated to control masking/unmasking on VPE#1. In
9  * this driver, these are called "shadow interrupts". The assignment of shadow
10  * interrupts is defined by the SoC integrator when wiring the interrupt lines,
11  * so they are configurable in the device tree.
12  *
13  * If an interrupt (say 30) needs per-CPU capability, the SoC integrator
14  * allocates another IRQ number (say 29) to be its shadow. The device tree
15  * reflects this by adding the pair <30 29> to the "econet,shadow-interrupts"
16  * property.
17  *
18  * When VPE#1 requests IRQ 30, the driver manipulates the mask bit for IRQ 29,
19  * telling the hardware to mask VPE#1's view of IRQ 30.
20  *
21  * Copyright (C) 2025 Caleb James DeLisle <cjd@cjdns.fr>
22  */
23 
24 #include <linux/cleanup.h>
25 #include <linux/io.h>
26 #include <linux/of.h>
27 #include <linux/of_address.h>
28 #include <linux/of_irq.h>
29 #include <linux/irqdomain.h>
30 #include <linux/irqchip.h>
31 #include <linux/irqchip/chained_irq.h>
32 
33 #include <asm/setup.h>
34 
35 #define IRQ_COUNT		40
36 
37 #define NOT_PERCPU		0xff
38 #define IS_SHADOW		0xfe
39 
40 #define REG_MASK0		0x04
41 #define REG_MASK1		0x50
42 #define REG_PENDING0		0x08
43 #define REG_PENDING1		0x54
44 
45 /**
46  * @membase:		Base address of the interrupt controller registers
47  * @domain:		The irq_domain for direct dispatch
48  * @ipi_domain:		The irq_domain for inter-process dispatch
49  * @interrupt_shadows:	Array of all interrupts, for each value,
50  *	- NOT_PERCPU:	This interrupt is not per-cpu, so it has no shadow
51  *	- IS_SHADOW:	This interrupt is a shadow of another per-cpu interrupt
52  *	- else:		This is a per-cpu interrupt whose shadow is the value
53  */
54 static struct {
55 	void __iomem		*membase;
56 	struct irq_domain	*domain;
57 	struct irq_domain	*ipi_domain;
58 	u8			interrupt_shadows[IRQ_COUNT];
59 } econet_intc __ro_after_init;
60 
61 static DEFINE_RAW_SPINLOCK(irq_lock);
62 
63 /* IRQs must be disabled */
64 static void econet_wreg(u32 reg, u32 val, u32 mask)
65 {
66 	u32 v;
67 
68 	guard(raw_spinlock)(&irq_lock);
69 
70 	v = ioread32(econet_intc.membase + reg);
71 	v &= ~mask;
72 	v |= val & mask;
73 	iowrite32(v, econet_intc.membase + reg);
74 }
75 
76 /* IRQs must be disabled */
77 static void econet_chmask(u32 hwirq, bool unmask)
78 {
79 	u32 reg, mask;
80 	u8 shadow;
81 
82 	/*
83 	 * If the IRQ is a shadow, it should never be manipulated directly.
84 	 * It should only be masked/unmasked as a result of the "real" per-cpu
85 	 * irq being manipulated by a thread running on VPE#1.
86 	 * If it is per-cpu (has a shadow), and we're on VPE#1, the shadow is what we mask.
87 	 * This is single processor only, so smp_processor_id() never exceeds 1.
88 	 */
89 	shadow = econet_intc.interrupt_shadows[hwirq];
90 	if (WARN_ON_ONCE(shadow == IS_SHADOW))
91 		return;
92 	else if (shadow != NOT_PERCPU && smp_processor_id() == 1)
93 		hwirq = shadow;
94 
95 	if (hwirq >= 32) {
96 		reg = REG_MASK1;
97 		mask = BIT(hwirq - 32);
98 	} else {
99 		reg = REG_MASK0;
100 		mask = BIT(hwirq);
101 	}
102 
103 	econet_wreg(reg, unmask ? mask : 0, mask);
104 }
105 
106 /* IRQs must be disabled */
107 static void econet_intc_mask(struct irq_data *d)
108 {
109 	econet_chmask(d->hwirq, false);
110 }
111 
112 /* IRQs must be disabled */
113 static void econet_intc_unmask(struct irq_data *d)
114 {
115 	econet_chmask(d->hwirq, true);
116 }
117 
118 static void econet_mask_all(void)
119 {
120 	/* IRQs are generally disabled during init, but guarding here makes it non-obligatory. */
121 	guard(irqsave)();
122 	econet_wreg(REG_MASK0, 0, ~0);
123 	econet_wreg(REG_MASK1, 0, ~0);
124 }
125 
126 static void econet_intc_handle_pending(struct irq_domain *d, u32 pending, u32 offset)
127 {
128 	int hwirq;
129 
130 	while (pending) {
131 		hwirq = fls(pending) - 1;
132 		generic_handle_domain_irq(d, hwirq + offset);
133 		pending &= ~BIT(hwirq);
134 	}
135 }
136 
137 static void econet_intc_from_parent(struct irq_desc *desc)
138 {
139 	struct irq_chip *chip = irq_desc_get_chip(desc);
140 	struct irq_domain *domain;
141 	u32 pending0, pending1;
142 
143 	chained_irq_enter(chip, desc);
144 
145 	pending0 = ioread32(econet_intc.membase + REG_PENDING0);
146 	pending1 = ioread32(econet_intc.membase + REG_PENDING1);
147 
148 	if (unlikely(!(pending0 | pending1))) {
149 		spurious_interrupt();
150 	} else {
151 		domain = irq_desc_get_handler_data(desc);
152 		econet_intc_handle_pending(domain, pending0, 0);
153 		econet_intc_handle_pending(domain, pending1, 32);
154 	}
155 
156 	chained_irq_exit(chip, desc);
157 }
158 
159 /*
160  * When in VEIC mode, the CPU jumps to a handler in the vector table.
161  * The only way to know which interrupt is being triggered is from the vector table offset that
162  * has been jumped to. Reading REG_PENDING(0|1) will tell you which interrupts are currently
163  * pending in the intc, but that will not tell you which one the intc wants you to process
164  * right now. And if you are not processing the exact interrupt that the intc wants you to be
165  * processing, you might be on the wrong VPE. You can't tell which VPE any given REG_PENDING
166  * interrupt is intended for (shadow IRQ numbers are for masking only, they never flag as
167  * pending).
168  *
169  * Consequently, this little ritual of generating n handler functions and registering one per
170  * interrupt is unavoidable.
171  */
172 #define X(irq) \
173 	static void econet_irq_dispatch ## irq (void) \
174 	{ \
175 		do_domain_IRQ(econet_intc.domain, irq); \
176 	}
177 
178  X(0)  X(1)  X(2)  X(3)  X(4)  X(5)  X(6)  X(7)  X(8)  X(9)
179 X(10) X(11) X(12) X(13) X(14) X(15) X(16) X(17) X(18) X(19)
180 X(20) X(21) X(22) X(23) X(24) X(25) X(26) X(27) X(28) X(29)
181 X(30) X(31) X(32) X(33) X(34) X(35) X(36) X(37) X(38) X(39)
182 
183 #undef X
184 #define X(irq) econet_irq_dispatch ## irq,
185 
186 static void (* const econet_irq_dispatchers[])(void) = {
187 	X(0)  X(1)  X(2)  X(3)  X(4)  X(5)  X(6)  X(7)  X(8)  X(9)
188 	X(10) X(11) X(12) X(13) X(14) X(15) X(16) X(17) X(18) X(19)
189 	X(20) X(21) X(22) X(23) X(24) X(25) X(26) X(27) X(28) X(29)
190 	X(30) X(31) X(32) X(33) X(34) X(35) X(36) X(37) X(38) X(39)
191 };
192 
193 /* Likewise, we do the same for the 2 IPI IRQs so that we can route them back */
194 static void econet_cpu_dispatch0(void)
195 {
196 	do_domain_IRQ(econet_intc.ipi_domain, 0);
197 }
198 
199 static void econet_cpu_dispatch1(void)
200 {
201 	do_domain_IRQ(econet_intc.ipi_domain, 1);
202 }
203 
204 static void (* const econet_cpu_dispatchers[])(void) = {
205 	econet_cpu_dispatch0,
206 	econet_cpu_dispatch1,
207 };
208 
209 static const struct irq_chip econet_irq_chip;
210 
211 static int econet_intc_map(struct irq_domain *d, u32 irq, irq_hw_number_t hwirq)
212 {
213 	int ret;
214 
215 	if (hwirq >= IRQ_COUNT) {
216 		pr_err("%s: hwirq %lu out of range\n", __func__, hwirq);
217 		return -EINVAL;
218 	} else if (econet_intc.interrupt_shadows[hwirq] == IS_SHADOW) {
219 		pr_err("%s: can't map hwirq %lu, it is a shadow interrupt\n", __func__, hwirq);
220 		return -EINVAL;
221 	}
222 
223 	if (econet_intc.interrupt_shadows[hwirq] == NOT_PERCPU) {
224 		irq_set_chip_and_handler(irq, &econet_irq_chip, handle_level_irq);
225 	} else {
226 		irq_set_chip_and_handler(irq, &econet_irq_chip, handle_percpu_devid_irq);
227 		ret = irq_set_percpu_devid(irq);
228 		if (ret)
229 			pr_warn("%s: Failed irq_set_percpu_devid for %u: %d\n", d->name, irq, ret);
230 	}
231 
232 	irq_set_chip_data(irq, NULL);
233 
234 	if (cpu_has_veic)
235 		set_vi_handler(hwirq + 1, econet_irq_dispatchers[hwirq]);
236 
237 	return 0;
238 }
239 
240 static const struct irq_chip econet_irq_chip = {
241 	.name		= "en751221-intc",
242 	.irq_unmask	= econet_intc_unmask,
243 	.irq_mask	= econet_intc_mask,
244 	.irq_mask_ack	= econet_intc_mask,
245 };
246 
247 static const struct irq_domain_ops econet_domain_ops = {
248 	.xlate	= irq_domain_xlate_onecell,
249 	.map	= econet_intc_map
250 };
251 
252 static int __init get_shadow_interrupts(struct device_node *node)
253 {
254 	const char *field = "econet,shadow-interrupts";
255 	int num_shadows;
256 
257 	num_shadows = of_property_count_u32_elems(node, field);
258 
259 	memset(econet_intc.interrupt_shadows, NOT_PERCPU,
260 	       sizeof(econet_intc.interrupt_shadows));
261 
262 	if (num_shadows <= 0) {
263 		return 0;
264 	} else if (num_shadows % 2) {
265 		pr_err("%pOF: %s count is odd, ignoring\n", node, field);
266 		return 0;
267 	}
268 
269 	u32 *shadows __free(kfree) = kmalloc_array(num_shadows, sizeof(u32), GFP_KERNEL);
270 	if (!shadows)
271 		return -ENOMEM;
272 
273 	if (of_property_read_u32_array(node, field, shadows, num_shadows)) {
274 		pr_err("%pOF: Failed to read %s\n", node, field);
275 		return -EINVAL;
276 	}
277 
278 	for (int i = 0; i < num_shadows; i += 2) {
279 		u32 shadow = shadows[i + 1];
280 		u32 target = shadows[i];
281 
282 		if (shadow > IRQ_COUNT) {
283 			pr_err("%pOF: %s[%d] shadow(%d) out of range\n",
284 			       node, field, i + 1, shadow);
285 			continue;
286 		}
287 
288 		if (target >= IRQ_COUNT) {
289 			pr_err("%pOF: %s[%d] target(%d) out of range\n", node, field, i, target);
290 			continue;
291 		}
292 
293 		if (econet_intc.interrupt_shadows[target] != NOT_PERCPU) {
294 			pr_err("%pOF: %s[%d] target(%d) already has a shadow\n",
295 			       node, field, i, target);
296 			continue;
297 		}
298 
299 		if (econet_intc.interrupt_shadows[shadow] != NOT_PERCPU) {
300 			pr_err("%pOF: %s[%d] shadow(%d) already has a target\n",
301 			       node, field, i + 1, shadow);
302 			continue;
303 		}
304 
305 		econet_intc.interrupt_shadows[target] = shadow;
306 		econet_intc.interrupt_shadows[shadow] = IS_SHADOW;
307 	}
308 
309 	return 0;
310 }
311 
312 /**
313  * econet_cpu_init() - configure routing of CPU interrupts to the correct domain.
314  * @node: The devicetree node of this interrupt controller.
315  *
316  * Interrupts that originate from the CPU are unconditionally unmasked here and are re-routed back
317  * to the IPI irq_domain in the CPU intc. Masking still takes place but the CPU intc is in charge
318  * of it, using the mask bits of the c0_status register.
319  *
320  * Note that because IP2 ... IP7 are repurposed as Interrupt Priority Level, only the two IPI
321  * interrupts are actually supported.
322  */
323 static int __init econet_cpu_init(struct device_node *node)
324 {
325 	const char *field = "econet,cpu-interrupt-map";
326 	struct device_node *parent_intc;
327 	int map_size;
328 	u32 mask;
329 
330 	map_size = of_property_count_u32_elems(node, field);
331 
332 	if (map_size <= 0) {
333 		return 0;
334 	} else if (map_size % 2) {
335 		pr_err("%pOF: %s count is odd, ignoring\n", node, field);
336 		return 0;
337 	}
338 
339 	u32 *maps __free(kfree) = kmalloc_array(map_size, sizeof(u32), GFP_KERNEL);
340 	if (!maps)
341 		return -ENOMEM;
342 
343 	if (of_property_read_u32_array(node, field, maps, map_size)) {
344 		pr_err("%pOF: Failed to read %s\n", node, field);
345 		return -EINVAL;
346 	}
347 
348 	/* Validation */
349 	for (int i = 0; i < map_size; i += 2) {
350 		u32 receive = maps[i];
351 		u32 dispatch = maps[i + 1];
352 		u8 shadow;
353 
354 		if (receive >= IRQ_COUNT) {
355 			pr_err("%pOF: Entry %d:%d in %s (%u) is out of bounds\n",
356 			       node, i, 0, field, receive);
357 			return -EINVAL;
358 		}
359 
360 		shadow = econet_intc.interrupt_shadows[receive];
361 		if (shadow != NOT_PERCPU && shadow >= IRQ_COUNT) {
362 			pr_err("%pOF: Entry %d:%d in %s (%u) has invalid shadow (%d)\n",
363 			       node, i, 0, field, receive, shadow);
364 			return -EINVAL;
365 		}
366 
367 		if (dispatch >= ARRAY_SIZE(econet_cpu_dispatchers)) {
368 			pr_err("%pOF: Entry %d:%d in %s (%u) is out of bounds only IPI interrupts are supported\n",
369 			       node, i, 1, field, dispatch);
370 			return -EINVAL;
371 		}
372 	}
373 
374 	parent_intc = of_irq_find_parent(node);
375 	if (!parent_intc) {
376 		pr_err("%pOF: Failed to find parent %s\n", node, "IRQ device");
377 		return -ENODEV;
378 	}
379 
380 	econet_intc.ipi_domain = irq_find_matching_host(parent_intc, DOMAIN_BUS_IPI);
381 	if (!econet_intc.ipi_domain) {
382 		pr_err("%pOF: Failed to find parent %s\n", node, "IPI domain");
383 		return -ENODEV;
384 	}
385 
386 	mask = 0;
387 	for (int i = 0; i < map_size; i += 2) {
388 		u32 receive = maps[i];
389 		u32 dispatch = maps[i + 1];
390 		u8 shadow;
391 
392 		set_vi_handler(receive + 1, econet_cpu_dispatchers[dispatch]);
393 
394 		mask |= BIT(receive);
395 
396 		shadow = econet_intc.interrupt_shadows[receive];
397 		if (shadow != NOT_PERCPU)
398 			mask |= BIT(shadow);
399 	}
400 
401 	econet_wreg(REG_MASK0, mask, mask);
402 
403 	return 0;
404 }
405 
406 static int __init econet_intc_of_init(struct device_node *node, struct device_node *parent)
407 {
408 	struct irq_domain *domain;
409 	struct resource res;
410 	int ret, irq;
411 
412 	ret = get_shadow_interrupts(node);
413 	if (ret)
414 		return ret;
415 
416 	irq = irq_of_parse_and_map(node, 0);
417 	if (!irq) {
418 		pr_err("%pOF: DT: Failed to get IRQ from 'interrupts'\n", node);
419 		return -EINVAL;
420 	}
421 
422 	if (of_address_to_resource(node, 0, &res)) {
423 		pr_err("%pOF: DT: Failed to get 'reg'\n", node);
424 		ret = -EINVAL;
425 		goto err_dispose_mapping;
426 	}
427 
428 	if (!request_mem_region(res.start, resource_size(&res), res.name)) {
429 		pr_err("%pOF: Failed to request memory\n", node);
430 		ret = -EBUSY;
431 		goto err_dispose_mapping;
432 	}
433 
434 	econet_intc.membase = ioremap(res.start, resource_size(&res));
435 	if (!econet_intc.membase) {
436 		pr_err("%pOF: Failed to remap membase\n", node);
437 		ret = -ENOMEM;
438 		goto err_release;
439 	}
440 
441 	econet_mask_all();
442 
443 	domain = irq_domain_create_linear(of_fwnode_handle(node), IRQ_COUNT,
444 					  &econet_domain_ops, NULL);
445 	if (!domain) {
446 		pr_err("%pOF: Failed to add irqdomain\n", node);
447 		ret = -ENOMEM;
448 		goto err_unmap;
449 	}
450 
451 	/*
452 	 * 34K Manual (MD00534) Section 6.3.1.3 rev 1.13 page 136:
453 	 * In VEIC mode, IP2 ... IP7 are repurposed as Interrupt Priority Level. The controller
454 	 * will filter incoming interrupts whose priority is lower than the IPL number. Therefore
455 	 * we must not set any of these bits. We avoid setting IP2 by not actually chaining this
456 	 * intc to the CPU intc.
457 	 */
458 	if (cpu_has_veic) {
459 		ret = econet_cpu_init(node);
460 
461 		if (ret)
462 			return ret;
463 	} else {
464 		irq_set_chained_handler_and_data(irq, econet_intc_from_parent, domain);
465 	}
466 
467 	econet_intc.domain = domain;
468 
469 	return 0;
470 
471 err_unmap:
472 	iounmap(econet_intc.membase);
473 err_release:
474 	release_mem_region(res.start, resource_size(&res));
475 err_dispose_mapping:
476 	irq_dispose_mapping(irq);
477 	return ret;
478 }
479 
480 IRQCHIP_DECLARE(econet_en751221_intc, "econet,en751221-intc", econet_intc_of_init);
481