Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'irq-urgent-2026-03-01' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull irqchip driver fixes from Ingo Molnar:

- Fix frozen interrupt bug in the sifive-plic driver

- Limit per-device MSI interrupts on uncommon gic-v3-its hardware
variants

- Address Sparse warning by constifying a variable in the MMP driver

- Revert broken commit and also fix an error check in the ls-extirq
driver

* tag 'irq-urgent-2026-03-01' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
irqchip/ls-extirq: Fix devm_of_iomap() error check
Revert "irqchip/ls-extirq: Use for_each_of_imap_item iterator"
irqchip/mmp: Make icu_irq_chip variable static const
irqchip/gic-v3-its: Limit number of per-device MSIs to the range the ITS supports
irqchip/sifive-plic: Fix frozen interrupt due to affinity setting

+46 -21
+4
drivers/irqchip/irq-gic-v3-its.c
··· 3474 3474 int lpi_base; 3475 3475 int nr_lpis; 3476 3476 int nr_ites; 3477 + int id_bits; 3477 3478 int sz; 3478 3479 3479 3480 if (!its_alloc_device_table(its, dev_id)) ··· 3486 3485 /* 3487 3486 * Even if the device wants a single LPI, the ITT must be 3488 3487 * sized as a power of two (and you need at least one bit...). 3488 + * Also honor the ITS's own EID limit. 3489 3489 */ 3490 + id_bits = FIELD_GET(GITS_TYPER_IDBITS, its->typer) + 1; 3491 + nvecs = min_t(unsigned int, nvecs, BIT(id_bits)); 3490 3492 nr_ites = max(2, nvecs); 3491 3493 sz = nr_ites * (FIELD_GET(GITS_TYPER_ITT_ENTRY_SIZE, its->typer) + 1); 3492 3494 sz = max(sz, ITS_ITT_ALIGN);
+34 -19
drivers/irqchip/irq-ls-extirq.c
··· 125 125 static int 126 126 ls_extirq_parse_map(struct ls_extirq_data *priv, struct device_node *node) 127 127 { 128 - struct of_imap_parser imap_parser; 129 - struct of_imap_item imap_item; 128 + const __be32 *map; 129 + u32 mapsize; 130 130 int ret; 131 131 132 - ret = of_imap_parser_init(&imap_parser, node, &imap_item); 133 - if (ret) 134 - return ret; 132 + map = of_get_property(node, "interrupt-map", &mapsize); 133 + if (!map) 134 + return -ENOENT; 135 + if (mapsize % sizeof(*map)) 136 + return -EINVAL; 137 + mapsize /= sizeof(*map); 135 138 136 - for_each_of_imap_item(&imap_parser, &imap_item) { 139 + while (mapsize) { 137 140 struct device_node *ipar; 138 - u32 hwirq; 139 - int i; 141 + u32 hwirq, intsize, j; 140 142 141 - hwirq = imap_item.child_imap[0]; 142 - if (hwirq >= MAXIRQ) { 143 - of_node_put(imap_item.parent_args.np); 143 + if (mapsize < 3) 144 144 return -EINVAL; 145 - } 145 + hwirq = be32_to_cpup(map); 146 + if (hwirq >= MAXIRQ) 147 + return -EINVAL; 146 148 priv->nirq = max(priv->nirq, hwirq + 1); 147 149 148 - ipar = of_node_get(imap_item.parent_args.np); 149 - priv->map[hwirq].fwnode = of_fwnode_handle(ipar); 150 + ipar = of_find_node_by_phandle(be32_to_cpup(map + 2)); 151 + map += 3; 152 + mapsize -= 3; 153 + if (!ipar) 154 + return -EINVAL; 155 + priv->map[hwirq].fwnode = &ipar->fwnode; 156 + ret = of_property_read_u32(ipar, "#interrupt-cells", &intsize); 157 + if (ret) 158 + return ret; 150 159 151 - priv->map[hwirq].param_count = imap_item.parent_args.args_count; 152 - for (i = 0; i < priv->map[hwirq].param_count; i++) 153 - priv->map[hwirq].param[i] = imap_item.parent_args.args[i]; 160 + if (intsize > mapsize) 161 + return -EINVAL; 162 + 163 + priv->map[hwirq].param_count = intsize; 164 + for (j = 0; j < intsize; ++j) 165 + priv->map[hwirq].param[j] = be32_to_cpup(map++); 166 + mapsize -= intsize; 154 167 } 155 168 return 0; 156 169 } ··· 190 177 return dev_err_probe(dev, -ENOMEM, "Failed to allocate memory\n"); 191 178 192 179 priv->intpcr = devm_of_iomap(dev, node, 0, NULL); 193 - if (!priv->intpcr) 194 - return dev_err_probe(dev, -ENOMEM, "Cannot ioremap OF node %pOF\n", node); 180 + if (IS_ERR(priv->intpcr)) { 181 + return dev_err_probe(dev, PTR_ERR(priv->intpcr), 182 + "Cannot ioremap OF node %pOF\n", node); 183 + } 195 184 196 185 ret = ls_extirq_parse_map(priv, node); 197 186 if (ret)
+1 -1
drivers/irqchip/irq-mmp.c
··· 136 136 } 137 137 } 138 138 139 - struct irq_chip icu_irq_chip = { 139 + static const struct irq_chip icu_irq_chip = { 140 140 .name = "icu_irq", 141 141 .irq_mask = icu_mask_irq, 142 142 .irq_mask_ack = icu_mask_ack_irq,
+6 -1
drivers/irqchip/irq-sifive-plic.c
··· 172 172 static void plic_irq_eoi(struct irq_data *d) 173 173 { 174 174 struct plic_handler *handler = this_cpu_ptr(&plic_handlers); 175 + u32 __iomem *reg; 176 + bool enabled; 175 177 176 - if (unlikely(irqd_irq_disabled(d))) { 178 + reg = handler->enable_base + (d->hwirq / 32) * sizeof(u32); 179 + enabled = readl(reg) & BIT(d->hwirq % 32); 180 + 181 + if (unlikely(!enabled)) { 177 182 plic_toggle(handler, d->hwirq, 1); 178 183 writel(d->hwirq, handler->hart_base + CONTEXT_CLAIM); 179 184 plic_toggle(handler, d->hwirq, 0);
+1
include/linux/irqchip/arm-gic-v3.h
··· 394 394 #define GITS_TYPER_VLPIS (1UL << 1) 395 395 #define GITS_TYPER_ITT_ENTRY_SIZE_SHIFT 4 396 396 #define GITS_TYPER_ITT_ENTRY_SIZE GENMASK_ULL(7, 4) 397 + #define GITS_TYPER_IDBITS GENMASK_ULL(12, 8) 397 398 #define GITS_TYPER_IDBITS_SHIFT 8 398 399 #define GITS_TYPER_DEVBITS_SHIFT 13 399 400 #define GITS_TYPER_DEVBITS GENMASK_ULL(17, 13)