* [PATCH 0/2] irqchip/econet-en751221: Support MIPS 34Kc VEIC mode @ 2026-04-25 12:35 Caleb James DeLisle 2026-04-25 12:35 ` [PATCH 1/2] dt-bindings: interrupt-controller: econet: Add CPU interrupt mapping Caleb James DeLisle 2026-04-25 12:35 ` [PATCH 2/2] irqchip/econet-en751221: Support MIPS 34Kc VEIC mode Caleb James DeLisle 0 siblings, 2 replies; 7+ messages in thread From: Caleb James DeLisle @ 2026-04-25 12:35 UTC (permalink / raw) To: linux-mips Cc: tglx, robh, krzk+dt, conor+dt, linux-kernel, devicetree, Caleb James DeLisle MIPS 34Kc and 1004Kc have a Vectored External Interrupt mode, where CPU interrupts are re-routed to the external interrupt controller, which prioritizes them, renumbers them, and integrates them with its own, creating a flat interrupt table. This bypasses the CPU interrupt controller entirely, which is not ideal for modern Linux which formalizes the interrupt hierarchy. The 1004Kc standardized the interrupt controller (MIPS_GIC) so it can be viewed as "part of the CPU" and it's tolerable for it to be more closely coupled to arch/mips/* than a typical interrupt controller driver. The 34Kc supports VEIC mode, but the interrupt controller is not standardized, so it's different per-SoC. This creates a challenge of writing a reasonably modular driver, given hardware that actually does take over the interrupt hierarchy. Ordinarily we wouldn't bother with VEIC on the 34Kc but it is required for MIPS_MT_SMP, so without it you get a single thread processor. The only other 34Kc device which has an in-tree DTS file is realtek,rtl9302-soc, in OpenWrt there is this, realtek,rtl839x-soc, and lantiq,xway. Of these, only the realtek,rtl839x-soc has multi-thread support via an out-of-tree patch to its interrupt controller. Everybody else is not solving this problem and instead sacrificing multi-thread support. This patchset aims to tackle this challenge in a way that is most likely generalizable to other 34Kc interrupt controllers which are facing the same problem. Caleb James DeLisle (2): dt-bindings: interrupt-controller: econet: Add CPU interrupt mapping irqchip/econet-en751221: Support MIPS 34Kc VEIC mode .../econet,en751221-intc.yaml | 20 ++ drivers/irqchip/irq-econet-en751221.c | 176 +++++++++++++++++- 2 files changed, 193 insertions(+), 3 deletions(-) base-commit: e8be82c2d77ec1bb0148406e54b105028a83537e -- 2.39.5 ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 1/2] dt-bindings: interrupt-controller: econet: Add CPU interrupt mapping 2026-04-25 12:35 [PATCH 0/2] irqchip/econet-en751221: Support MIPS 34Kc VEIC mode Caleb James DeLisle @ 2026-04-25 12:35 ` Caleb James DeLisle 2026-04-25 13:28 ` Rob Herring (Arm) 2026-04-25 12:35 ` [PATCH 2/2] irqchip/econet-en751221: Support MIPS 34Kc VEIC mode Caleb James DeLisle 1 sibling, 1 reply; 7+ messages in thread From: Caleb James DeLisle @ 2026-04-25 12:35 UTC (permalink / raw) To: linux-mips Cc: tglx, robh, krzk+dt, conor+dt, linux-kernel, devicetree, Caleb James DeLisle In MIPS VEIC mode (Vectored External Interrupt Controller), the hardware stops directly dispatching CPU interrupts such as IPIs or CPU performance counters, and instead it communicates them to the external interrupt controller (the hardware described here) which prioritizes, renumbers, and integrates them with its own hardware interrupt pins. Interrupts from the external controller are then dispatched through a different method via a dispatch table. In effect, the external controller subsumes the CPU controller and becomes the root. 34K Manual (MD00534) Section 6.3.1.3 rev 1.13 page 136 Since there are interrupts which ought to be controlled by the CPU controller driver - particularly the IPI interrupts - we create a reverse mapping where those interrupts may be sent back to the CPU intc when they are received. This maintains the fiction that there is still a hierarchy, and keeps the DT the same no matter whether the processor is in VEIC mode or not. The econet,cpu-interrupt-map is optional and if omitted, it's assumed that no interrupts need to be mapped. Signed-off-by: Caleb James DeLisle <cjd@cjdns.fr> --- .../econet,en751221-intc.yaml | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/Documentation/devicetree/bindings/interrupt-controller/econet,en751221-intc.yaml b/Documentation/devicetree/bindings/interrupt-controller/econet,en751221-intc.yaml index 5536319c49c3..32d20f7bbd0b 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/econet,en751221-intc.yaml +++ b/Documentation/devicetree/bindings/interrupt-controller/econet,en751221-intc.yaml @@ -52,6 +52,25 @@ properties: - description: primary per-CPU IRQ - description: shadow IRQ number + econet,cpu-interrupt-map: + $ref: /schemas/types.yaml#/definitions/uint32-matrix + description: + When running in VEIC mode, the hardware re-routes interrupts from the + CPU interrupt controller core to the "external" interrupt controller + (this device). It then prioritizes them and sends them back to the CPU + along with its own interrupts. The CPU hardware handles interrupts using + a special dispatch table (the normal interrupt handler is not invoked). + In this interrupt controller, the CPU interrupts are renumbered as they + are merged with this controller's own hardware interrupts. + + This is the inverse of an interrupt-map, mapping which interrupts from + this controller must be routed back to the CPU interrupt domain for + correct handling there. + items: + items: + - The interrupt number which will be received in this controller + - The interrupt number which must then be dispatched on the CPU intc + required: - compatible - reg @@ -74,5 +93,6 @@ examples: interrupts = <2>; econet,shadow-interrupts = <7 2>, <8 3>, <13 12>, <30 29>; + econet,cpu-interrupt-map = <7 0>, <8 1>; }; ... -- 2.39.5 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 1/2] dt-bindings: interrupt-controller: econet: Add CPU interrupt mapping 2026-04-25 12:35 ` [PATCH 1/2] dt-bindings: interrupt-controller: econet: Add CPU interrupt mapping Caleb James DeLisle @ 2026-04-25 13:28 ` Rob Herring (Arm) 2026-04-25 17:03 ` Caleb James DeLisle 0 siblings, 1 reply; 7+ messages in thread From: Rob Herring (Arm) @ 2026-04-25 13:28 UTC (permalink / raw) To: Caleb James DeLisle Cc: tglx, conor+dt, linux-mips, krzk+dt, linux-kernel, devicetree On Sat, 25 Apr 2026 12:35:30 +0000, Caleb James DeLisle wrote: > In MIPS VEIC mode (Vectored External Interrupt Controller), the > hardware stops directly dispatching CPU interrupts such as IPIs or CPU > performance counters, and instead it communicates them to the external > interrupt controller (the hardware described here) which prioritizes, > renumbers, and integrates them with its own hardware interrupt pins. > Interrupts from the external controller are then dispatched through a > different method via a dispatch table. In effect, the external > controller subsumes the CPU controller and becomes the root. > > 34K Manual (MD00534) Section 6.3.1.3 rev 1.13 page 136 > > Since there are interrupts which ought to be controlled by the CPU > controller driver - particularly the IPI interrupts - we create a > reverse mapping where those interrupts may be sent back to the CPU > intc when they are received. This maintains the fiction that there is > still a hierarchy, and keeps the DT the same no matter whether the > processor is in VEIC mode or not. The econet,cpu-interrupt-map is > optional and if omitted, it's assumed that no interrupts need to be > mapped. > > Signed-off-by: Caleb James DeLisle <cjd@cjdns.fr> > --- > .../econet,en751221-intc.yaml | 20 +++++++++++++++++++ > 1 file changed, 20 insertions(+) > My bot found errors running 'make dt_binding_check' on your patch: yamllint warnings/errors: dtschema/dtc warnings/errors: /builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/interrupt-controller/econet,en751221-intc.yaml: ignoring, error in schema: properties: econet,cpu-interrupt-map: items /builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/interrupt-controller/econet,en751221-intc.yaml: properties:econet,cpu-interrupt-map:items: 'anyOf' conditional failed, one must be fixed: {'items': ['The interrupt number which will be received in this controller', 'The interrupt number which must then be dispatched on the CPU intc']} is not of type 'array' /builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/interrupt-controller/econet,en751221-intc.yaml: properties:econet,cpu-interrupt-map:items:items: 'anyOf' conditional failed, one must be fixed: ['The interrupt number which will be received in this controller', 'The interrupt number which must then be dispatched on the CPU intc'] is not of type 'object', 'boolean' 'The interrupt number which will be received in this controller' is not of type 'object', 'boolean' 'The interrupt number which must then be dispatched on the CPU intc' is not of type 'object', 'boolean' Traceback (most recent call last): File "/usr/local/bin/dt-doc-validate", line 8, in <module> sys.exit(main()) ~~~~^^ File "/usr/local/lib/python3.13/dist-packages/dtschema/doc_validate.py", line 66, in main ret |= check_doc(f) ~~~~~~~~~^^^ File "/usr/local/lib/python3.13/dist-packages/dtschema/doc_validate.py", line 37, in check_doc dtsch.check_schema_refs() ~~~~~~~~~~~~~~~~~~~~~~~^^ File "/usr/local/lib/python3.13/dist-packages/dtschema/schema.py", line 241, in check_schema_refs self._check_schema_refs(resolver, self) ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.13/dist-packages/dtschema/schema.py", line 212, in _check_schema_refs self._check_schema_refs(resolver, v, parent=k, is_common=is_common, ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ has_constraint=has_constraint) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.13/dist-packages/dtschema/schema.py", line 216, in _check_schema_refs self._check_schema_refs(resolver, schema[i], parent=parent, is_common=is_common, ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ has_constraint=has_constraint) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.13/dist-packages/dtschema/schema.py", line 203, in _check_schema_refs ref_sch = resolver.lookup(schema['$ref']).contents ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.13/dist-packages/referencing/_core.py", line 682, in lookup retrieved = self._registry.get_or_retrieve(uri) File "/usr/local/lib/python3.13/dist-packages/referencing/_core.py", line 422, in get_or_retrieve registry = self.crawl() File "/usr/local/lib/python3.13/dist-packages/referencing/_core.py", line 500, in crawl id = resource.id() File "/usr/local/lib/python3.13/dist-packages/referencing/_core.py", line 231, in id id = self._specification.id_of(self.contents) File "/usr/local/lib/python3.13/dist-packages/referencing/jsonschema.py", line 50, in _dollar_id return contents.get("$id") ^^^^^^^^^^^^ AttributeError: 'str' object has no attribute 'get' Documentation/devicetree/bindings/interrupt-controller/econet,en751221-intc.example.dtb: /example-0/interrupt-controller@1fb40000: failed to match any schema with compatible: ['econet,en751221-intc'] doc reference errors (make refcheckdocs): See https://patchwork.kernel.org/project/devicetree/patch/20260425123531.270548-2-cjd@cjdns.fr The base for the series is generally the latest rc1. A different dependency should be noted in *this* patch. If you already ran 'make dt_binding_check' and didn't see the above error(s), then make sure 'yamllint' is installed and dt-schema is up to date: pip3 install dtschema --upgrade Please check and re-submit after running the above command yourself. Note that DT_SCHEMA_FILES can be set to your schema file to speed up checking your schema. However, it must be unset to test all examples with your schema. ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/2] dt-bindings: interrupt-controller: econet: Add CPU interrupt mapping 2026-04-25 13:28 ` Rob Herring (Arm) @ 2026-04-25 17:03 ` Caleb James DeLisle 0 siblings, 0 replies; 7+ messages in thread From: Caleb James DeLisle @ 2026-04-25 17:03 UTC (permalink / raw) To: Rob Herring (Arm) Cc: tglx, conor+dt, linux-mips, krzk+dt, linux-kernel, devicetree > My bot found errors running 'make dt_binding_check' on your patch: > Gonna blame this on not doing `pip3 install dtschema --upgrade` often enough. Fixed but will re-send in a couple of days so in case of other notes, all can be addressed together. Thanks, Caleb ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 2/2] irqchip/econet-en751221: Support MIPS 34Kc VEIC mode 2026-04-25 12:35 [PATCH 0/2] irqchip/econet-en751221: Support MIPS 34Kc VEIC mode Caleb James DeLisle 2026-04-25 12:35 ` [PATCH 1/2] dt-bindings: interrupt-controller: econet: Add CPU interrupt mapping Caleb James DeLisle @ 2026-04-25 12:35 ` Caleb James DeLisle 2026-04-29 7:19 ` Thomas Gleixner 1 sibling, 1 reply; 7+ messages in thread From: Caleb James DeLisle @ 2026-04-25 12:35 UTC (permalink / raw) To: linux-mips Cc: tglx, robh, krzk+dt, conor+dt, linux-kernel, devicetree, Caleb James DeLisle The Vectored External Interrupt Controller mode present in the MIPS 34Kc and 1004Kc causes the CPU to stop dispatching interrupts by the normal code path and instead it sends those interrupts to the external interrupt controller to be prioritized, renumbered, and sent back. When they come back, they are handled through a different path using a dispatch table, so plat_irq_dispatch never sees action. This of course subverts the traditional intc hierarchy, and on the 1004Kc the interrupt controller is standardized (IRQ_GIC) so it can be reasonably considered part of the CPU itself - and tighter coupling between IRQ_GIC and arch/mips/* is tolerable. However on the 34Kc the intc is defined by each SoC vendor, so we have the task of making a reasonably modular driver - but for a device which in fact ends up taking over the entire interrupt system. We let the DT describe which IRQs which come from the CPU and should be routed back and handled by the CPU intc. These particularly include the two IPI interrupts which would otherwise necessitate duplication of all the IPI supporting infrastructure from the CPU intc. Signed-off-by: Caleb James DeLisle <cjd@cjdns.fr> --- drivers/irqchip/irq-econet-en751221.c | 176 +++++++++++++++++++++++++- 1 file changed, 173 insertions(+), 3 deletions(-) diff --git a/drivers/irqchip/irq-econet-en751221.c b/drivers/irqchip/irq-econet-en751221.c index d83d5eb12795..98c109fe053b 100644 --- a/drivers/irqchip/irq-econet-en751221.c +++ b/drivers/irqchip/irq-econet-en751221.c @@ -30,6 +30,8 @@ #include <linux/irqchip.h> #include <linux/irqchip/chained_irq.h> +#include <asm/setup.h> + #define IRQ_COUNT 40 #define NOT_PERCPU 0xff @@ -42,14 +44,18 @@ /** * @membase: Base address of the interrupt controller registers + * @domain: The irq_domain for direct dispatch + * @ipi_domain: The irq_domain for inter-process dispatch * @interrupt_shadows: Array of all interrupts, for each value, * - NOT_PERCPU: This interrupt is not per-cpu, so it has no shadow * - IS_SHADOW: This interrupt is a shadow of another per-cpu interrupt * - else: This is a per-cpu interrupt whose shadow is the value */ static struct { - void __iomem *membase; - u8 interrupt_shadows[IRQ_COUNT]; + void __iomem *membase; + struct irq_domain *domain; + struct irq_domain *ipi_domain; + u8 interrupt_shadows[IRQ_COUNT]; } econet_intc __ro_after_init; static DEFINE_RAW_SPINLOCK(irq_lock); @@ -150,6 +156,55 @@ static void econet_intc_from_parent(struct irq_desc *desc) chained_irq_exit(chip, desc); } +/* When in VEIC mode, the CPU jumps to a handler in the vector table. + * The only way to know which interrupt is being triggered is from the vector table offset that + * has been jumped to. Reading REG_PENDING(0|1) will tell you which interrupts are currently + * pending in the intc, but that will not tell you which one the intc wants you to process + * right now. And if you are not processing the exact interrupt that the intc wants you to be + * processing, you might be on the wrong VPE. You can't tell which VPE any given REG_PENDING + * interrupt is intended for (shadow IRQ numbers are for masking only, they never flag as + * pending). + * + * Consequently, this little ritual of generating n handler functions and registering one per + * interrupt is unavoidable. + */ +#define X(irq) \ + static void econet_irq_dispatch ## irq (void) \ + { \ + do_domain_IRQ(econet_intc.domain, irq); \ + } + + X(0) X(1) X(2) X(3) X(4) X(5) X(6) X(7) X(8) X(9) +X(10) X(11) X(12) X(13) X(14) X(15) X(16) X(17) X(18) X(19) +X(20) X(21) X(22) X(23) X(24) X(25) X(26) X(27) X(28) X(29) +X(30) X(31) X(32) X(33) X(34) X(35) X(36) X(37) X(38) X(39) + +#undef X +#define X(irq) econet_irq_dispatch ## irq, + +static void (* const econet_irq_dispatchers[])(void) = { + X(0) X(1) X(2) X(3) X(4) X(5) X(6) X(7) X(8) X(9) + X(10) X(11) X(12) X(13) X(14) X(15) X(16) X(17) X(18) X(19) + X(20) X(21) X(22) X(23) X(24) X(25) X(26) X(27) X(28) X(29) + X(30) X(31) X(32) X(33) X(34) X(35) X(36) X(37) X(38) X(39) +}; + +/* Likewise, we do the same for the 2 IPI IRQs so that we can route them back */ +static void econet_cpu_dispatch0(void) +{ + do_domain_IRQ(econet_intc.ipi_domain, 0); +} + +static void econet_cpu_dispatch1(void) +{ + do_domain_IRQ(econet_intc.ipi_domain, 1); +} + +static void (* const econet_cpu_dispatchers[])(void) = { + econet_cpu_dispatch0, + econet_cpu_dispatch1, +}; + static const struct irq_chip econet_irq_chip; static int econet_intc_map(struct irq_domain *d, u32 irq, irq_hw_number_t hwirq) @@ -174,6 +229,10 @@ static int econet_intc_map(struct irq_domain *d, u32 irq, irq_hw_number_t hwirq) } irq_set_chip_data(irq, NULL); + + if (cpu_has_veic) + set_vi_handler(hwirq + 1, econet_irq_dispatchers[hwirq]); + return 0; } @@ -249,6 +308,101 @@ static int __init get_shadow_interrupts(struct device_node *node) return 0; } +/** + * econet_cpu_init() - configure routing of CPU interrupts to the correct domain. + * @node: The devicetree node of this interrupt controller. + * + * Interrupts that originate from the CPU are unconditionally unmasked here and are re-routed back + * to the IPI irq_domain in the CPU intc. Masking still takes place but the CPU intc is in charge + * of it, using the mask bits of the c0_status register. + * + * Note that because IP2 ... IP7 are repurposed as Interrupt Priority Level, only the two IPI + * interrupts are actually supported. + */ +static int __init econet_cpu_init(struct device_node *node) +{ + const char *field = "econet,cpu-interrupt-map"; + struct device_node *parent_intc; + int map_size; + u32 mask; + + map_size = of_property_count_u32_elems(node, field); + + if (map_size <= 0) { + return 0; + } else if (map_size % 2) { + pr_err("%pOF: %s count is odd, ignoring\n", node, field); + return 0; + } + + u32 *maps __free(kfree) = kmalloc_array(map_size, sizeof(u32), GFP_KERNEL); + if (!maps) + return -ENOMEM; + + if (of_property_read_u32_array(node, field, maps, map_size)) { + pr_err("%pOF: Failed to read %s\n", node, field); + return -EINVAL; + } + + /* Validation */ + for (int i = 0; i < map_size; i += 2) { + u32 receive = maps[i]; + u32 dispatch = maps[i + 1]; + u8 shadow; + + if (receive >= IRQ_COUNT) { + pr_err("%pOF: Entry %d:%d in %s (%u) %s\n", + node, i, 0, field, receive, "is out of bounds"); + return -EINVAL; + } + + shadow = econet_intc.interrupt_shadows[receive]; + if (shadow != NOT_PERCPU && shadow >= IRQ_COUNT) { + pr_err("%pOF: Entry %d:%d in %s (%u) %s\n", + node, i, 0, field, receive, "has invalid shadow"); + return -EINVAL; + } + + if (dispatch >= ARRAY_SIZE(econet_cpu_dispatchers)) { + pr_err("%pOF: Entry %d:%d in %s (%u) %s\n", + node, i, 1, field, dispatch, + "is out of bounds, only IPI interrupts are supported"); + return -EINVAL; + } + } + + parent_intc = of_irq_find_parent(node); + if (!parent_intc) { + pr_err("%pOF: Failed to find parent %s\n", node, "IRQ device"); + return -ENODEV; + } + + econet_intc.ipi_domain = irq_find_matching_host(parent_intc, DOMAIN_BUS_IPI); + if (!econet_intc.ipi_domain) { + pr_err("%pOF: Failed to find parent %s\n", node, "IPI domain"); + return -ENODEV; + } + + mask = 0; + for (int i = 0; i < map_size; i += 2) { + u32 receive = maps[i]; + u32 dispatch = maps[i + 1]; + u8 shadow; + + set_vi_handler(receive + 1, econet_cpu_dispatchers[dispatch]); + + mask |= BIT(receive); + + shadow = econet_intc.interrupt_shadows[receive]; + if (shadow != NOT_PERCPU) + mask |= BIT(shadow); + } + + econet_wreg(REG_MASK0, mask, mask); + + return 0; +} + static int __init econet_intc_of_init(struct device_node *node, struct device_node *parent) { struct irq_domain *domain; @@ -294,7 +448,23 @@ static int __init econet_intc_of_init(struct device_node *node, struct device_no goto err_unmap; } - irq_set_chained_handler_and_data(irq, econet_intc_from_parent, domain); + /* + * 34K Manual (MD00534) Section 6.3.1.3 rev 1.13 page 136: + * In VEIC mode, IP2 ... IP7 are repurposed as Interrupt Priority Level. The controller + * will filter incoming interrupts whose priority is lower than the IPL number. Therefore + * we must not set any of these bits. We avoid setting IP2 by not actually chaining this + * intc to the CPU intc. + */ + if (cpu_has_veic) { + ret = econet_cpu_init(node); + + if (ret) + return ret; + } else { + irq_set_chained_handler_and_data(irq, econet_intc_from_parent, domain); + } + + econet_intc.domain = domain; return 0; -- 2.39.5 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] irqchip/econet-en751221: Support MIPS 34Kc VEIC mode 2026-04-25 12:35 ` [PATCH 2/2] irqchip/econet-en751221: Support MIPS 34Kc VEIC mode Caleb James DeLisle @ 2026-04-29 7:19 ` Thomas Gleixner 2026-05-02 21:54 ` Maciej W. Rozycki 0 siblings, 1 reply; 7+ messages in thread From: Thomas Gleixner @ 2026-04-29 7:19 UTC (permalink / raw) To: Caleb James DeLisle, linux-mips Cc: robh, krzk+dt, conor+dt, linux-kernel, devicetree, Caleb James DeLisle On Sat, Apr 25 2026 at 12:35, Caleb James DeLisle wrote: > This of course subverts the traditional intc hierarchy, and on the > 1004Kc the interrupt controller is standardized (IRQ_GIC) so it can be > reasonably considered part of the CPU itself - and tighter coupling > between IRQ_GIC and arch/mips/* is tolerable. However on the 34Kc > the intc is defined by each SoC vendor, so we have the task of making a s/so we have.../so it's required to have a modular driver/ or something like that. Please use passive and factual voice for change logs. > reasonably modular driver - but for a device which in fact ends up > taking over the entire interrupt system. > > We let the DT describe which IRQs which come from the CPU and should > be s/we let/Let/ > routed back and handled by the CPU intc. These particularly include the > two IPI interrupts which would otherwise necessitate duplication of all > the IPI supporting infrastructure from the CPU intc. > /** > * @membase: Base address of the interrupt controller registers > + * @domain: The irq_domain for direct dispatch > + * @ipi_domain: The irq_domain for inter-process dispatch Can you please make that tabular for easier parsing? > * @interrupt_shadows: Array of all interrupts, for each value, > > +/* When in VEIC mode, the CPU jumps to a handler in the vector table. This is invalid multiline comment style. https://www.kernel.org/doc/html/latest/process/maintainer-tip.html > + * The only way to know which interrupt is being triggered is from the vector table offset that > + * has been jumped to. Reading REG_PENDING(0|1) will tell you which interrupts are currently > + if (receive >= IRQ_COUNT) { > + pr_err("%pOF: Entry %d:%d in %s (%u) %s\n", > + node, i, 0, field, receive, "is out of bounds"); Yuck. What's the point of the last string constant argument? Just stick it into the format string. All over the place. Other than those nits, this look like a reasonable solution for a completely unreasonable hardware design. Thanks, tglx ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] irqchip/econet-en751221: Support MIPS 34Kc VEIC mode 2026-04-29 7:19 ` Thomas Gleixner @ 2026-05-02 21:54 ` Maciej W. Rozycki 0 siblings, 0 replies; 7+ messages in thread From: Maciej W. Rozycki @ 2026-05-02 21:54 UTC (permalink / raw) To: Thomas Gleixner Cc: Caleb James DeLisle, linux-mips, robh, krzk+dt, conor+dt, linux-kernel, devicetree On Wed, 29 Apr 2026, Thomas Gleixner wrote: > Other than those nits, this look like a reasonable solution for a > completely unreasonable hardware design. Why do you think this design is unreasonable? How is that different, at the high level, from say the x86 APIC priority resolver and vector generator, combined with the interrupt descriptor table (except for additional optional GPR stack switching, which saves the handler from the hassle and extra cycles needed for GPR preservation, though I reckon with x86 you could use task gates in the IDT to yield a similar effect although at much higher cost performance-wise as x86 does not implement alternative GPR stacks)? Analogously to x86 in the MIPS VEIC mode the IRQ number is determined by the vector rather than the somewhat arbitrarily numbered (particularly in cascaded topologies) IRQ line and available to the handler in the CP0.Cause.RIPL register field. NB this arbitrary non-VEIC IRQ numbering is particularly obvious with MIPS platforms featuring an x86-style PCI southbridge with an embedded 8259A interrupt controller pair, where for compatibility with our driver code we give root MIPS CPU IRQ lines numbers 16-23 while 8259A IRQ lines cascaded from one of the IRQ lines 18-23 are given numbers 0-15. Example such an odd topology: CPU0 0: 0 XT-PIC 0 timer 1: 0 XT-PIC 1 i8042 2: 0 XT-PIC 2 cascade 3: 4 XT-PIC 3 ttyS1 4: 37 XT-PIC 4 ttyS0 6: 3 XT-PIC 6 floppy 7: 52456 XT-PIC 7 parport0 8: 0 XT-PIC 8 rtc0 10: 99668740 XT-PIC 10 fddi0 11: 0 XT-PIC 11 uhci_hcd:usb1 12: 1 XT-PIC 12 i8042 14: 0 XT-PIC 14 ata_piix 15: 15 XT-PIC 15 ata_piix 20: 0 MIPS 4 ttyS2 21: 0 MIPS 5 CoreHi 23: 803937130 MIPS 7 timer ERR: 1 (where XT-PIC interrupts are cascaded from IRQ line 18/MIPS line 2, not actually given stub registration). At least the VEIC mode brings some sanity here. FWIW, Maciej ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-05-02 21:54 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-04-25 12:35 [PATCH 0/2] irqchip/econet-en751221: Support MIPS 34Kc VEIC mode Caleb James DeLisle 2026-04-25 12:35 ` [PATCH 1/2] dt-bindings: interrupt-controller: econet: Add CPU interrupt mapping Caleb James DeLisle 2026-04-25 13:28 ` Rob Herring (Arm) 2026-04-25 17:03 ` Caleb James DeLisle 2026-04-25 12:35 ` [PATCH 2/2] irqchip/econet-en751221: Support MIPS 34Kc VEIC mode Caleb James DeLisle 2026-04-29 7:19 ` Thomas Gleixner 2026-05-02 21:54 ` Maciej W. Rozycki
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox