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

Configure Feed

Select the types of activity you want to include in your feed.

Revert "irqchip/ls-extirq: Use for_each_of_imap_item iterator"

This reverts commit 3ac6dfe3d7a2396602b67667249b146504dfbd2a.

The ls-extirq uses interrupt-map but it's a non-standard use documented
in fsl,ls-extirq.yaml:

# The driver(drivers/irqchip/irq-ls-extirq.c) have not use standard DT
# function to parser interrupt-map. So it doesn't consider '#address-size'
# in parent interrupt controller, such as GIC.
#
# When dt-binding verify interrupt-map, item data matrix is spitted at
# incorrect position. Remove interrupt-map restriction because it always
# wrong.

This means that by using for_each_of_imap_item and the underlying
of_irq_parse_imap_parent() on its interrupt-map property will effectively
break its functionality

Revert the patch making use of for_each_of_imap_item() in ls-extirq.

Fixes: 3ac6dfe3d7a2 ("irqchip/ls-extirq: Use for_each_of_imap_item iterator")
Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
Signed-off-by: Thomas Gleixner <tglx@kernel.org>
Acked-by: Herve Codina <herve.codina@bootlin.com>
Link: https://patch.msgid.link/20260224113610.1129022-2-ioana.ciornei@nxp.com

authored by

Ioana Ciornei and committed by
Thomas Gleixner
e08f2adc f0617176

+30 -17
+30 -17
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 }