Skip to contentSkip to conversation

gpio: renesas: Add support for GPIO and related interrupts in RZ/N1 SoC

PATCH Superseded Herve Codina (Schneider Electric) 6 participants 42 messages Sep 18, 2025 – Oct 14, 2025

Subsystems (5)

v3 of 8 Superseded Latest is v8 →

lore
Share & tools
lore
#0 lore raw

v3 cover gpio: renesas: Add support for GPIO and related interrupts in RZ/N1 SoC

Hi,

This series adds support for GPIO and GPIO IRQ mux available in the RZ/N1 SoCs.

The first patches in this series are related to a new helper introduced to parse an interrupt-map property.
- patch 1: Introduce the helper (for_each_of_imap_item)
- patch 2: Add a unittest for the new helper
- patch 3 and 4: convert existing drivers to use this new helper

Patch 4 will conflicts with commit 40c26230a1bf ("irqchip: Use int type to store negative error codes") available in linux-next.

Patch 5 adds support for GPIO (device-tree description)

The last patches (6, 7 and 8) of the series are related to GPIO interrupts and GPIO IRQ multiplexer.

In the RZ/N1 SoCs, GPIO interrupts are wired to a GPIO IRQ multiplexer.

This multiplexer does nothing but select 8 GPIO IRQ lines out of the 96 available to wire them to the GIC input lines.

One upstreaming attempt have been done previously by Phil Edworthy [1] but the series has never been applied.

Based on my understanding, I have fully reworked the driver proposed by Phil and removed the IRQ domain. Indeed, the device doesn't handle interrupts. It just routes signals.

Also, as an interrupt-map property is used, the driver cannot be involved as an interrupt controller itself. It is a nexus node.

With that in mind,
- Patch 6 is related to the irq-mux binding.

- Patch 7 introduces the irq-mux driver.
This driver uses the 'for_each_of_imap_item' helper introduced previously. Indeed, the lines routing is defined by the interrupt-map property and the driver needs to set registers to apply this routing.

- Patch 8 is the RZ/N1 device-tree description update to have the support for the GPIO interrupts.

[1] https://lore.kernel.org/all/[email protected]/

Best regards,
Hervé

Changes v2 -> v3
v2: https://lore.kernel.org/lkml/[email protected]/

Reordered patches as suggested by Thomas Gleixner.

Patch 1: (3 in v2)
- Replace a wrong 'extern' by 'static inline' in of_irq.h (detected by test robots)

Patch 2: (4 in v2)
Patch 3: (5 in v2)
Patch 4: (6 in v2)
- No changes

Patch 5: (1 in v2)
- Add 'Reviewed-by: Wolfram Sang'
- Add 'Tested-by: Wolfram Sang'

Patch 6: (2 in v2)
- Add '#address-cells = <0>;' in the interrupt-controller node present in the example.

Patch 7:
Patch 8:
- No changes

Changes v1 -> v2
v1: https://lore.kernel.org/lkml/[email protected]/

Rebase on top of v6.17-rc5

Patch 1 in v1
- Removed in v2 (no need for RZ/N1 compatible strings).

Patch 1 (2 in v1)
- Fix node names (issue reported by Rob's bot)
- Fix compatible RZ/N1 compatible strings
- Removed undocumented and unused 'bank-name' properties

Patch 2 (3 in v1)
- Remove 'interrupts' property
- Update 'interrupt-map' description

Patch 3 (4 in v1)
- Rework of_irq_foreach_imap() to provide the for_each_of_imap_item iterator (similar to for_each_of_range)

Patch 4 (new in v2)
- Add a unittest for for_each_of_imap_item

Patch 5 (new in v2)
- Convert irqchip/ls-extirq to use for_each_of_imap_item

Patch 6 (new in v2)
- Convert irqchip/renesas-rza1 to use for_each_of_imap_item

Patch 7 (5 in v1)
- Use for_each_of_imap_item
- Remove 'interrupts' property usage

Patch 8 (6 in v1)
- Remove 'interrupts' property

Herve Codina (Schneider Electric) (8):
of/irq: Introduce for_each_of_imap_item
of: unittest: Add a test case for for_each_of_imap_item iterator irqchip/ls-extirq: Use for_each_of_imap_item iterator irqchip/renesas-rza1: Use for_each_of_imap_item iterator
ARM: dts: r9a06g032: Add GPIO controllers
dt-bindings: soc: renesas: Add the Renesas RZ/N1 GPIO Interrupt
Multiplexer
soc: renesas: Add support for Renesas RZ/N1 GPIO Interrupt Multiplexer
ARM: dts: r9a06g032: Add support for GPIO interrupts

 .../soc/renesas/renesas,rzn1-gpioirqmux.yaml  |  87 +++++++++
 arch/arm/boot/dts/renesas/r9a06g032.dtsi      | 170 ++++++++++++++++++
 drivers/irqchip/irq-ls-extirq.c               |  47 ++---
 drivers/irqchip/irq-renesas-rza1.c            |  43 ++---
 drivers/of/irq.c                              |  70 ++++++++
 .../of/unittest-data/tests-interrupts.dtsi    |   9 +
 drivers/of/unittest.c                         | 116 ++++++++++++
 drivers/soc/renesas/Kconfig                   |   4 +
 drivers/soc/renesas/Makefile                  |   1 +
 drivers/soc/renesas/rzn1_irqmux.c             | 110 ++++++++++++
 include/linux/of_irq.h                        |  41 ++++-
 11 files changed, 640 insertions(+), 58 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/soc/renesas/renesas,rzn1-gpioirqmux.yaml
 create mode 100644 drivers/soc/renesas/rzn1_irqmux.c
Signature · 1 line
2.51.0
#1 lore raw

PATCH v3 1/8 of/irq: Introduce for_each_of_imap_item

for_each_of_imap_item is an iterator designed to help a driver to parse an interrupt-map property.

Indeed some drivers need to know details about the interrupt mapping described in the device-tree in order to set internal registers accordingly.

---
 drivers/of/irq.c       | 70 ++++++++++++++++++++++++++++++++++++++++++
 include/linux/of_irq.h | 41 ++++++++++++++++++++++++-
 2 files changed, 110 insertions(+), 1 deletion(-)
drivers/of/irq.c +70 -0
index 74aaea61de13..0723ae4153a0 100644
@@ -157,6 +157,76 @@ const __be32 *of_irq_parse_imap_parent(const __be32 *imap, int len, struct of_ph
 	return imap;
 }
 
+int of_imap_parser_init(struct of_imap_parser *parser, struct device_node *node,
+			struct of_imap_item *item)
+{
+	int imaplen;
+	u32 tmp;
+	int ret;
+
+	/*
+	 * parent_offset is the offset where the parent part is starting.
+	 * In other words, the offset where the parent interrupt controller
+	 * phandle is present.
+	 *
+	 * Compute this offset (child #interrupt-cells + child #address-cells)
+	 */
+	parser->parent_offset = of_bus_n_addr_cells(node);
+
+	ret = of_property_read_u32(node, "#interrupt-cells", &tmp);
+	if (ret)
+		return ret;
+
+	parser->parent_offset += tmp;
+
+	if (WARN(parser->parent_offset > ARRAY_SIZE(item->child_imap),
+		 "child part size = %u, cannot fit in array of %zu items",
+		 parser->parent_offset, ARRAY_SIZE(item->child_imap)))
+		return -EINVAL;
+
+	parser->imap = of_get_property(node, "interrupt-map", &imaplen);
+	if (!parser->imap)
+		return -ENOENT;
+
+	imaplen /= sizeof(*parser->imap);
+	parser->imap_end = parser->imap + imaplen;
+
+	memset(item, 0, sizeof(*item));
+	item->child_imap_count = parser->parent_offset;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(of_imap_parser_init);
+
+struct of_imap_item *of_imap_parser_one(struct of_imap_parser *parser,
+					struct of_imap_item *item)
+{
+	const __be32 *imap_parent, *imap_next;
+	int i;
+
+	/* Release previously get parent node */
+	of_node_put(item->parent_args.np);
+
+	if (parser->imap + parser->parent_offset + 1 >= parser->imap_end)
+		return NULL;
+
+	imap_parent = parser->imap + parser->parent_offset;
+
+	imap_next = of_irq_parse_imap_parent(imap_parent,
+					     parser->imap_end - imap_parent,
+					     &item->parent_args);
+	if (!imap_next)
+		return NULL;
+
+	for (i = 0; i < parser->parent_offset; i++)
+		item->child_imap[i] = be32_to_cpu(*(parser->imap + i));
+
+	parser->imap = imap_next;
+
+	return item;
+}
+EXPORT_SYMBOL_GPL(of_imap_parser_one);
+
 /**
  * of_irq_parse_raw - Low level interrupt tree parsing
  * @addr:	address specifier (start of "reg" property of the device) in be32 format
include/linux/of_irq.h +40 -1

59 lines not on this page · raw message

Signature · 1 line
2.51.0
#2 lore raw

PATCH v3 2/8 of: unittest: Add a test case for for_each_of_imap_item iterator

In reply to Herve Codina (Schneider Electric)

Recently for_each_of_imap_item iterator has been introduce to help drivers in parsing the interrupt-map property.

Add a test case for this iterator.

---
 .../of/unittest-data/tests-interrupts.dtsi    |   9 ++
 drivers/of/unittest.c                         | 116 ++++++++++++++++++
 2 files changed, 125 insertions(+)
drivers/of/unittest-data/tests-interrupts.dtsi +9 -0
index 4ccb54f91c30..974f888c9b15 100644
@@ -50,6 +50,15 @@ test_intmap1: intmap1 {
 				interrupt-map = <0x5000 1 2 &test_intc0 15>;
 			};
 
+			intmap2 {
+				#interrupt-cells = <2>;
+				#address-cells = <0>;
+				interrupt-map = <1 11 &test_intc0 100>,
+						<2 22 &test_intc1 200 201 202>,
+						<3 33 &test_intc2 300 301>,
+						<4 44 &test_intc2 400 401>;
+			};
+
 			test_intc_intmap0: intc-intmap0 {
 				#interrupt-cells = <1>;
 				#address-cells = <1>;
drivers/of/unittest.c +116 -0

128 lines not on this page · raw message

Signature · 1 line
2.51.0
#3 lore raw

PATCH v3 3/8 irqchip/ls-extirq: Use for_each_of_imap_item iterator

In reply to Herve Codina (Schneider Electric)

The ls-extirq driver parses the interrupt-map property. It does it using open code.

Recently for_each_of_imap_item iterator has been introduce to help drivers in this parsing.

Convert the ls-extirq driver to use the for_each_of_imap_item iterator instead of open code.

---
 drivers/irqchip/irq-ls-extirq.c | 47 ++++++++++++---------------------
 1 file changed, 17 insertions(+), 30 deletions(-)
drivers/irqchip/irq-ls-extirq.c +17 -30
index 50a7b38381b9..ed8755777349 100644
@@ -125,45 +125,32 @@ static const struct irq_domain_ops extirq_domain_ops = {
 static int
 ls_extirq_parse_map(struct ls_extirq_data *priv, struct device_node *node)
 {
-	const __be32 *map;
-	u32 mapsize;
+	struct of_imap_parser imap_parser;
+	struct of_imap_item imap_item;
 	int ret;
 
-	map = of_get_property(node, "interrupt-map", &mapsize);
-	if (!map)
-		return -ENOENT;
-	if (mapsize % sizeof(*map))
-		return -EINVAL;
-	mapsize /= sizeof(*map);
+	ret = of_imap_parser_init(&imap_parser, node, &imap_item);
+	if (ret)
+		return ret;
 
-	while (mapsize) {
+	for_each_of_imap_item(&imap_parser, &imap_item) {
 		struct device_node *ipar;
-		u32 hwirq, intsize, j;
+		u32 hwirq;
+		int i;
 
-		if (mapsize < 3)
-			return -EINVAL;
-		hwirq = be32_to_cpup(map);
-		if (hwirq >= MAXIRQ)
+		hwirq = imap_item.child_imap[0];
+		if (hwirq >= MAXIRQ) {
+			of_node_put(imap_item.parent_args.np);
 			return -EINVAL;
+		}
 		priv->nirq = max(priv->nirq, hwirq + 1);
 
-		ipar = of_find_node_by_phandle(be32_to_cpup(map + 2));
-		map += 3;
-		mapsize -= 3;
-		if (!ipar)
-			return -EINVAL;
-		priv->map[hwirq].fwnode = &ipar->fwnode;
-		ret = of_property_read_u32(ipar, "#interrupt-cells", &intsize);
-		if (ret)
-			return ret;
-
-		if (intsize > mapsize)
-			return -EINVAL;
+		ipar = of_node_get(imap_item.parent_args.np);
+		priv->map[hwirq].fwnode = of_fwnode_handle(ipar);
 
-		priv->map[hwirq].param_count = intsize;
-		for (j = 0; j < intsize; ++j)
-			priv->map[hwirq].param[j] = be32_to_cpup(map++);
-		mapsize -= intsize;
+		priv->map[hwirq].param_count = imap_item.parent_args.args_count;
+		for (i = 0; i < priv->map[hwirq].param_count; i++)
+			priv->map[hwirq].param[i] = imap_item.parent_args.args[i];
 	}
 	return 0;
 }
Signature · 1 line
2.51.0
#4 lore raw

PATCH v3 4/8 irqchip/renesas-rza1: Use for_each_of_imap_item iterator

In reply to Herve Codina (Schneider Electric)

The renesas-rza1 driver parses the interrupt-map property. It does it using open code.

Recently for_each_of_imap_item iterator has been introduce to help drivers in this parsing.

Convert the renesas-rza1 driver to use the for_each_of_imap_item iterator instead of open code.

---
 drivers/irqchip/irq-renesas-rza1.c | 43 +++++++++++-------------------
 1 file changed, 16 insertions(+), 27 deletions(-)
drivers/irqchip/irq-renesas-rza1.c +16 -27
index a697eb55ac90..789196b71656 100644
@@ -142,46 +142,35 @@ static const struct irq_domain_ops rza1_irqc_domain_ops = {
 static int rza1_irqc_parse_map(struct rza1_irqc_priv *priv,
 			       struct device_node *gic_node)
 {
-	unsigned int imaplen, i, j, ret;
+	struct of_imap_parser imap_parser;
 	struct device *dev = priv->dev;
+	struct of_imap_item imap_item;
 	struct device_node *ipar;
-	const __be32 *imap;
-	u32 intsize;
+	int j, ret;
+	u32 i = 0;
 
-	imap = of_get_property(dev->of_node, "interrupt-map", &imaplen);
-	if (!imap)
-		return -EINVAL;
-
-	for (i = 0; i < IRQC_NUM_IRQ; i++) {
-		if (imaplen < 3)
-			return -EINVAL;
+	ret = of_imap_parser_init(&imap_parser, dev->of_node, &imap_item);
+	if (ret)
+		return ret;
 
+	for_each_of_imap_item(&imap_parser, &imap_item) {
 		/* Check interrupt number, ignore sense */
-		if (be32_to_cpup(imap) != i)
+		if (imap_item.child_imap[0] != i) {
+			of_node_put(imap_item.parent_args.np);
 			return -EINVAL;
+		}
 
-		ipar = of_find_node_by_phandle(be32_to_cpup(imap + 2));
+		ipar  = imap_item.parent_args.np;
 		if (ipar != gic_node) {
 			of_node_put(ipar);
 			return -EINVAL;
 		}
 
-		imap += 3;
-		imaplen -= 3;
-
-		ret = of_property_read_u32(ipar, "#interrupt-cells", &intsize);
-		of_node_put(ipar);
-		if (ret)
-			return ret;
-
-		if (imaplen < intsize)
-			return -EINVAL;
-
-		priv->map[i].args_count = intsize;
-		for (j = 0; j < intsize; j++)
-			priv->map[i].args[j] = be32_to_cpup(imap++);
+		priv->map[i].args_count = imap_item.parent_args.args_count;
+		for (j = 0; j < priv->map[i].args_count; j++)
+			priv->map[i].args[j] = imap_item.parent_args.args[j];
 
-		imaplen -= intsize;
+		i++;
 	}
 
 	return 0;
Signature · 1 line
2.51.0
#5 lore raw

PATCH v3 5/8 ARM: dts: r9a06g032: Add GPIO controllers

In reply to Herve Codina (Schneider Electric)

Add GPIO controllers (Synosys DesignWare IPs) available in the r9a06g032 (RZ/N1D) SoC.

---
 arch/arm/boot/dts/renesas/r9a06g032.dtsi | 121 +++++++++++++++++++++++
 1 file changed, 121 insertions(+)
arch/arm/boot/dts/renesas/r9a06g032.dtsi +121 -0
index 13a60656b044..da977cdd8487 100644
@@ -499,6 +499,127 @@ gic: interrupt-controller@44101000 {
 				<GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
 		};
 
+		/*
+		 * The GPIO mapping to the corresponding pins is not obvious.
+		 * See the hardware documentation for details.
+		 */
+		gpio0: gpio@5000b000 {
+			compatible = "snps,dw-apb-gpio";
+			reg = <0x5000b000 0x80>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			clocks = <&sysctrl R9A06G032_HCLK_GPIO0>;
+			clock-names = "bus";
+			status = "disabled";
+
+			/* GPIO0a[0]      connected to pin  GPIO0      */
+			/* GPIO0a[1..2]   connected to pins GPIO3..4   */
+			/* GPIO0a[3..4]   connected to pins GPIO9..10  */
+			/* GPIO0a[5]      connected to pin  GPIO12     */
+			/* GPIO0a[6..7]   connected to pins GPIO15..16 */
+			/* GPIO0a[8..9]   connected to pins GPIO21..22 */
+			/* GPIO0a[10]     connected to pin  GPIO24     */
+			/* GPIO0a[11..12] connected to pins GPIO27..28 */
+			/* GPIO0a[13..14] connected to pins GPIO33..34 */
+			/* GPIO0a[15]     connected to pin  GPIO36     */
+			/* GPIO0a[16..17] connected to pins GPIO39..40 */
+			/* GPIO0a[18..19] connected to pins GPIO45..46 */
+			/* GPIO0a[20]     connected to pin  GPIO48     */
+			/* GPIO0a[21..22] connected to pins GPIO51..52 */
+			/* GPIO0a[23..24] connected to pins GPIO57..58 */
+			/* GPIO0a[25..31] connected to pins GPIO62..68 */
+			gpio0a: gpio-port@0 {
+				compatible = "snps,dw-apb-gpio-port";
+				gpio-controller;
+				#gpio-cells = <2>;
+				snps,nr-gpios = <32>;
+				reg = <0>;
+			};
+
+			/* GPIO0b[0..1]   connected to pins GPIO1..2   */
+			/* GPIO0b[2..5]   connected to pins GPIO5..8   */
+			/* GPIO0b[6]      connected to pin  GPIO11     */
+			/* GPIO0b[7..8]   connected to pins GPIO13..14 */
+			/* GPIO0b[9..12]  connected to pins GPIO17..20 */
+			/* GPIO0b[13]     connected to pin  GPIO23     */
+			/* GPIO0b[14..15] connected to pins GPIO25..26 */
+			/* GPIO0b[16..19] connected to pins GPIO29..32 */
+			/* GPIO0b[20]     connected to pin  GPIO35     */
+			/* GPIO0b[21..22] connected to pins GPIO37..38 */
+			/* GPIO0b[23..26] connected to pins GPIO41..44 */
+			/* GPIO0b[27]     connected to pin  GPIO47     */
+			/* GPIO0b[28..29] connected to pins GPIO49..50 */
+			/* GPIO0b[30..31] connected to pins GPIO53..54 */
+			gpio0b: gpio-port@1 {
+				compatible = "snps,dw-apb-gpio-port";
+				gpio-controller;
+				#gpio-cells = <2>;
+				snps,nr-gpios = <32>;
+				reg = <1>;
+			};
+		};
+
+		gpio1: gpio@5000c000 {
+			compatible = "snps,dw-apb-gpio";
+			reg = <0x5000c000 0x80>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			clocks = <&sysctrl R9A06G032_HCLK_GPIO1>;
+			clock-names = "bus";
+			status = "disabled";
+
+			/* GPIO1a[0..4]  connected to pins GPIO69..73 */
+			/* GPIO1a[5..31] connected to pins GPIO95..121 */
+			gpio1a: gpio-port@0 {
+				compatible = "snps,dw-apb-gpio-port";
+				gpio-controller;
+				#gpio-cells = <2>;
+				snps,nr-gpios = <32>;
+				reg = <0>;
+			};
+
+			/* GPIO1b[0..1]   connected to pins GPIO55..56 */
+			/* GPIO1b[2..4]   connected to pins GPIO59..61 */
+			/* GPIO1b[5..25]  connected to pins GPIO74..94 */
+			/* GPIO1b[26..31] connected to pins GPIO150..155 */
+			gpio1b: gpio-port@1 {
+				compatible = "snps,dw-apb-gpio-port";
+				gpio-controller;
+				#gpio-cells = <2>;
+				snps,nr-gpios = <32>;
+				reg = <1>;
+			};
+		};
+
+		gpio2: gpio@5000d000 {
+			compatible = "snps,dw-apb-gpio";
+			reg = <0x5000d000 0x80>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			clocks = <&sysctrl R9A06G032_HCLK_GPIO2>;
+			clock-names = "bus";
+			status = "disabled";
+
+			/* GPIO2a[0..27]  connected to pins GPIO122..149 */
+			/* GPIO2a[28..31] connected to pins GPIO156..159 */
+			gpio2a: gpio-port@0 {
+				compatible = "snps,dw-apb-gpio-port";
+				gpio-controller;
+				#gpio-cells = <2>;
+				snps,nr-gpios = <32>;
+				reg = <0>;
+			};
+
+			/* GPIO2b[0..9] connected to pins GPIO160..169 */
+			gpio2b: gpio-port@1 {
+				compatible = "snps,dw-apb-gpio-port";
+				gpio-controller;
+				#gpio-cells = <2>;
+				snps,nr-gpios = <10>;
+				reg = <1>;
+			};
+		};
+
 		can0: can@52104000 {
 			compatible = "renesas,r9a06g032-sja1000", "renesas,rzn1-sja1000";
 			reg = <0x52104000 0x800>;
Signature · 1 line
2.51.0
Reviewed-by on v3 5/8
#7 lore raw

Re: [PATCH v3 5/8] ARM: dts: r9a06g032: Add GPIO controllers

In reply to Herve Codina (Schneider Electric)
Quoted 8 lines · Herve Codina (Schneider Electric)

Add GPIO controllers (Synosys DesignWare IPs) available in the r9a06g032 (RZ/N1D) SoC.

---

#8 lore raw

Re: [PATCH v3 5/8] ARM: dts: r9a06g032: Add GPIO controllers

Hi Bartosz,

Quoted 6 lines · On Mon, 22 Sep 2025 16:22:14 +0200 Bartosz Golaszewski <[email protected]> wrote:
Quoted 4 lines · Herve Codina (Schneider Electric)

Add GPIO controllers (Synosys DesignWare IPs) available in the r9a06g032 (RZ/N1D) SoC.

Quoted 6 lines
Quoted 4 lines

---

I have just sent the v4 iteration.

This patch has not been modified in v4.

Can you add your 'Reviewed-by' in the v4 series?

Best regards,
Hervé

Signature · 3 lines
Hervé Codina, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
#9 lore raw

Re: [PATCH v3 5/8] ARM: dts: r9a06g032: Add GPIO controllers

Quoted 16 lines · Herve Codina

Hi Bartosz,

Quoted 11 lines · On Mon, 22 Sep 2025 16:22:14 +0200 Bartosz Golaszewski <[email protected]> wrote:
Quoted 8 lines · Herve Codina (Schneider Electric)

Add GPIO controllers (Synosys DesignWare IPs) available in the r9a06g032 (RZ/N1D) SoC.

---

Quoted 8 lines
Quoted 1 line

I have just sent the v4 iteration.

This patch has not been modified in v4.

Can you add your 'Reviewed-by' in the v4 series?

Sure, done.

Bart

#10 lore raw

Re: [PATCH v3 5/8] ARM: dts: r9a06g032: Add GPIO controllers

Hi Barosz,

Quoted 20 lines · On Mon, 22 Sep 2025 18:33:49 +0300 Bartosz Golaszewski <[email protected]> wrote:
Quoted 18 lines · Herve Codina

Hi Bartosz,

Quoted 12 lines · On Mon, 22 Sep 2025 16:22:14 +0200 Bartosz Golaszewski <[email protected]> wrote:
Quoted 8 lines · Herve Codina (Schneider Electric)

Add GPIO controllers (Synosys DesignWare IPs) available in the r9a06g032 (RZ/N1D) SoC.

---

Quoted 8 lines
Quoted 6 lines

I have just sent the v4 iteration.

This patch has not been modified in v4.

Can you add your 'Reviewed-by' in the v4 series?

Sure, done.

I have seen your 'Reviewed-by' in v4 but on patch 8 ("ARM: dts: r9a06g032:
Add support for GPIO interrupts").

Maybe this is correct but here (v3) your 'Reviewed-by' in on patch 5 ("ARM: dts:
r9a06g032: Add GPIO controllers").

This exact same patch 5 exists also in v4.

Best regards,
Hervé

#11 lore raw

PATCH v3 6/8 dt-bindings: soc: renesas: Add the Renesas RZ/N1 GPIO Interrupt Multiplexer

In reply to Herve Codina (Schneider Electric)

On the Renesas RZ/N1 SoC, GPIOs can generate interruptions. Those interruption lines are multiplexed by the GPIO Interrupt Multiplexer in order to map 32 * 3 GPIO interrupt lines to 8 GIC interrupt lines.

The GPIO interrupt multiplexer IP does nothing but select 8 GPIO IRQ lines out of the 96 available to wire them to the GIC input lines.

---
 .../soc/renesas/renesas,rzn1-gpioirqmux.yaml  | 87 +++++++++++++++++++
 1 file changed, 87 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/soc/renesas/renesas,rzn1-gpioirqmux.yaml
Documentation/devicetree/bindings/soc/renesas/renesas,rzn1-gpioirqmux.yaml new file +87 -0
new file mode 100644
index 000000000000..21c6b6e1fa9a
@@ -0,0 +1,87 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/soc/renesas/renesas,rzn1-gpioirqmux.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Renesas RZ/N1 SoCs GPIO Interrupt Multiplexer
+
+description: |
+   The Renesas RZ/N1 GPIO Interrupt Multiplexer multiplexes GPIO interrupt
+   lines to the interrupt controller available in the SoC.
+
+   It selects up to 8 of the 96 GPIO interrupt lines available and connect them
+   to 8 output interrupt lines.
+
+maintainers:
+  - Herve Codina <[email protected]>
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - renesas,r9a06g032-gpioirqmux
+      - const: renesas,rzn1-gpioirqmux
+
+  reg:
+    maxItems: 1
+
+  "#address-cells":
+    const: 0
+
+  "#interrupt-cells":
+    const: 1
+
+  interrupt-map-mask:
+    items:
+      - const: 0x7f
+
+  interrupt-map:
+    description:
+      Specifies the mapping from external GPIO interrupt lines to the output
+      interrupts. The array items have to be ordered with the first item
+      related to the output line 0 (IRQ 103), the next one to the output line 1
+      (IRQ 104) and so on up to the output line 8 (IRQ 110).
+
+required:
+  - compatible
+  - reg
+  - "#address-cells"
+  - "#interrupt-cells"
+  - interrupt-map-mask
+  - interrupt-map
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    gic: interrupt-controller {
+        interrupt-controller;
+        #address-cells = <0>;
+        #interrupt-cells = <3>;
+    };
+
+    interrupt-controller@51000480 {
+        compatible = "renesas,r9a06g032-gpioirqmux", "renesas,rzn1-gpioirqmux";
+        reg = <0x51000480 0x20>;
+        #address-cells = <0>;
+        #interrupt-cells = <1>;
+        interrupt-map-mask = <0x7f>;
+        /*
+         * The child interrupt number is computed using the following formula:
+         *    gpio_bank * 32 + gpio_number
+         *
+         * with:
+         *    - gpio_bank: The GPIO bank number
+         *          - 0 for GPIO0A,
+         *          - 1 for GPIO1A,
+         *          - 2 for GPIO2A
+         *    - gpio_number: Number of the gpio in the bank (0..31)
+         */
+        interrupt-map =
+            <32 &gic GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>, /* GPIO1A.0 */
+            <89 &gic GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>, /* GPIO2A.25 */
+            <9 &gic GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>; /* GPIO0A.9 */
+    };
Signature · 1 line
2.51.0
Acked-by on v3 6/8
#12 lore raw

Re: [PATCH v3 6/8] dt-bindings: soc: renesas: Add the Renesas RZ/N1 GPIO Interrupt Multiplexer

Quoted 4 lines · Herve Codina (Schneider Electric)

On the Renesas RZ/N1 SoC, GPIOs can generate interruptions. Those interruption lines are multiplexed by the GPIO Interrupt Multiplexer in order to map 32 * 3 GPIO interrupt lines to 8 GIC interrupt lines.

Quoted 8 lines

The GPIO interrupt multiplexer IP does nothing but select 8 GPIO IRQ lines out of the 96 available to wire them to the GIC input lines.

---
 .../soc/renesas/renesas,rzn1-gpioirqmux.yaml  | 87 +++++++++++++++++++
 1 file changed, 87 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/soc/renesas/renesas,rzn1-gpioirqmux.yaml

This is an interrupt controller, please move it to that subdirectory. Otherwise,

#13 lore raw

Re: [PATCH v3 6/8] dt-bindings: soc: renesas: Add the Renesas RZ/N1 GPIO Interrupt Multiplexer

Hi Conor,

Quoted 8 lines · On Thu, 18 Sep 2025 16:06:04 +0100 Conor Dooley <[email protected]> wrote:
Quoted 7 lines · Herve Codina (Schneider Electric)

On the Renesas RZ/N1 SoC, GPIOs can generate interruptions. Those interruption lines are multiplexed by the GPIO Interrupt Multiplexer in order to map 32 * 3 GPIO interrupt lines to 8 GIC interrupt lines.

The GPIO interrupt multiplexer IP does nothing but select 8 GPIO IRQ lines out of the 96 available to wire them to the GIC input lines.

Quoted 7 lines
Quoted 5 lines
---
 .../soc/renesas/renesas,rzn1-gpioirqmux.yaml  | 87 +++++++++++++++++++
 1 file changed, 87 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/soc/renesas/renesas,rzn1-gpioirqmux.yaml  

This is an interrupt controller, please move it to that subdirectory.

Not so sure. It is a nexus node. It routes interrupt signals to the interrupt controller (interrupt-map) but it is not an interrupt controller itself.

I am not sure that it should be moved to the interrupt-controller directory.

Quoted 2 lines

Otherwise,

Best regards,
Hervé

#14 lore raw

Re: [PATCH v3 6/8] dt-bindings: soc: renesas: Add the Renesas RZ/N1 GPIO Interrupt Multiplexer

Quoted 19 lines · Herve Codina

Hi Conor,

Quoted 14 lines · On Thu, 18 Sep 2025 16:06:04 +0100 Conor Dooley <[email protected]> wrote:
Quoted 12 lines · Herve Codina (Schneider Electric)

On the Renesas RZ/N1 SoC, GPIOs can generate interruptions. Those interruption lines are multiplexed by the GPIO Interrupt Multiplexer in order to map 32 * 3 GPIO interrupt lines to 8 GIC interrupt lines.

The GPIO interrupt multiplexer IP does nothing but select 8 GPIO IRQ lines out of the 96 available to wire them to the GIC input lines.

---
 .../soc/renesas/renesas,rzn1-gpioirqmux.yaml  | 87 +++++++++++++++++++
 1 file changed, 87 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/soc/renesas/renesas,rzn1-gpioirqmux.yaml  
Quoted 8 lines
Quoted 1 line

This is an interrupt controller, please move it to that subdirectory.

Not so sure. It is a nexus node. It routes interrupt signals to the interrupt controller (interrupt-map) but it is not an interrupt controller itself.

I am not sure that it should be moved to the interrupt-controller directory.

Your node name choice disagrees with you!

#15 lore raw

Re: [PATCH v3 6/8] dt-bindings: soc: renesas: Add the Renesas RZ/N1 GPIO Interrupt Multiplexer

Quoted 22 lines · On Thu, 18 Sep 2025 16:26:59 +0100 Conor Dooley <[email protected]> wrote:
Quoted 21 lines · Herve Codina

Hi Conor,

Quoted 15 lines · On Thu, 18 Sep 2025 16:06:04 +0100 Conor Dooley <[email protected]> wrote:
Quoted 4 lines · Herve Codina (Schneider Electric)

On the Renesas RZ/N1 SoC, GPIOs can generate interruptions. Those interruption lines are multiplexed by the GPIO Interrupt Multiplexer in order to map 32 * 3 GPIO interrupt lines to 8 GIC interrupt lines.

Quoted 8 lines

The GPIO interrupt multiplexer IP does nothing but select 8 GPIO IRQ lines out of the 96 available to wire them to the GIC input lines.

---
 .../soc/renesas/renesas,rzn1-gpioirqmux.yaml  | 87 +++++++++++++++++++
 1 file changed, 87 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/soc/renesas/renesas,rzn1-gpioirqmux.yaml    

This is an interrupt controller, please move it to that subdirectory.

Quoted 8 lines
Quoted 6 lines

Not so sure. It is a nexus node. It routes interrupt signals to the interrupt controller (interrupt-map) but it is not an interrupt controller itself.

I am not sure that it should be moved to the interrupt-controller directory.

Your node name choice disagrees with you!

Oups, you're right, my bad.

What do you think if I change the node name from "interrupt-controller" to "interrupt-mux" in the next iteration?

Best regards,
Hervé

#16 lore raw

Re: [PATCH v3 6/8] dt-bindings: soc: renesas: Add the Renesas RZ/N1 GPIO Interrupt Multiplexer

Quoted 32 lines · Herve Codina
Quoted 29 lines · On Thu, 18 Sep 2025 16:26:59 +0100 Conor Dooley <[email protected]> wrote:
Quoted 27 lines · Herve Codina

Hi Conor,

Quoted 8 lines · On Thu, 18 Sep 2025 16:06:04 +0100 Conor Dooley <[email protected]> wrote:
Quoted 7 lines · Herve Codina (Schneider Electric)

On the Renesas RZ/N1 SoC, GPIOs can generate interruptions. Those interruption lines are multiplexed by the GPIO Interrupt Multiplexer in order to map 32 * 3 GPIO interrupt lines to 8 GIC interrupt lines.

The GPIO interrupt multiplexer IP does nothing but select 8 GPIO IRQ lines out of the 96 available to wire them to the GIC input lines.

Quoted 7 lines
Quoted 5 lines
---
 .../soc/renesas/renesas,rzn1-gpioirqmux.yaml  | 87 +++++++++++++++++++
 1 file changed, 87 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/soc/renesas/renesas,rzn1-gpioirqmux.yaml    

This is an interrupt controller, please move it to that subdirectory.

Not so sure. It is a nexus node. It routes interrupt signals to the interrupt controller (interrupt-map) but it is not an interrupt controller itself.

I am not sure that it should be moved to the interrupt-controller directory.

Quoted 6 lines
Quoted 1 line

Your node name choice disagrees with you!

Oups, you're right, my bad.

What do you think if I change the node name from "interrupt-controller" to "interrupt-mux" in the next iteration?

I guess, sure.

maintainer
#17 lore raw

Re: [PATCH v3 6/8] dt-bindings: soc: renesas: Add the Renesas RZ/N1 GPIO Interrupt Multiplexer

Quoted 34 lines · Conor Dooley
Quoted 32 lines · Herve Codina
Quoted 29 lines · On Thu, 18 Sep 2025 16:26:59 +0100 Conor Dooley <[email protected]> wrote:
Quoted 27 lines · Herve Codina

Hi Conor,

Quoted 8 lines · On Thu, 18 Sep 2025 16:06:04 +0100 Conor Dooley <[email protected]> wrote:
Quoted 7 lines · Herve Codina (Schneider Electric)

On the Renesas RZ/N1 SoC, GPIOs can generate interruptions. Those interruption lines are multiplexed by the GPIO Interrupt Multiplexer in order to map 32 * 3 GPIO interrupt lines to 8 GIC interrupt lines.

The GPIO interrupt multiplexer IP does nothing but select 8 GPIO IRQ lines out of the 96 available to wire them to the GIC input lines.

Quoted 7 lines
Quoted 5 lines
---
 .../soc/renesas/renesas,rzn1-gpioirqmux.yaml  | 87 +++++++++++++++++++
 1 file changed, 87 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/soc/renesas/renesas,rzn1-gpioirqmux.yaml

This is an interrupt controller, please move it to that subdirectory.

Not so sure. It is a nexus node. It routes interrupt signals to the interrupt controller (interrupt-map) but it is not an interrupt controller itself.

I am not sure that it should be moved to the interrupt-controller directory.

Quoted 8 lines
Quoted 6 lines
Quoted 1 line

Your node name choice disagrees with you!

Oups, you're right, my bad.

What do you think if I change the node name from "interrupt-controller" to "interrupt-mux" in the next iteration?

I guess, sure.

Stick with interrupt-controller. That's what the schema expects and 'interrupt-mux' (or any other variation) is not in the spec.

#18 lore raw

Re: [PATCH v3 6/8] dt-bindings: soc: renesas: Add the Renesas RZ/N1 GPIO Interrupt Multiplexer

In reply to Herve Codina (Schneider Electric)

Documentation/devicetree/bindings/soc/renesas/renesas,rzn1-gpioirqmux.yaml line 44

Quoted 7 lines
Documentation/devicetree/bindings/soc/renesas/renesas,rzn1-gpioirqmux.yaml new file +6 -0
+  interrupt-map:
+    description:
+      Specifies the mapping from external GPIO interrupt lines to the output
+      interrupts. The array items have to be ordered with the first item
+      related to the output line 0 (IRQ 103), the next one to the output line 1
+      (IRQ 104) and so on up to the output line 8 (IRQ 110).

maxItems 8?

Documentation/devicetree/bindings/soc/renesas/renesas,rzn1-gpioirqmux.yaml line 82

Quoted 11 lines
Documentation/devicetree/bindings/soc/renesas/renesas,rzn1-gpioirqmux.yaml new file +11 -0
+        /*
+         * The child interrupt number is computed using the following formula:
+         *    gpio_bank * 32 + gpio_number
+         *
+         * with:
+         *    - gpio_bank: The GPIO bank number
+         *          - 0 for GPIO0A,
+         *          - 1 for GPIO1A,
+         *          - 2 for GPIO2A
+         *    - gpio_number: Number of the gpio in the bank (0..31)
+         */

I wonder if this comment wouldn't be better in the interrupt-map description above?

#19 lore raw

Re: [PATCH v3 6/8] dt-bindings: soc: renesas: Add the Renesas RZ/N1 GPIO Interrupt Multiplexer

Hi Wolfram,

Quoted 8 lines · On Fri, 19 Sep 2025 11:34:51 +0200 Wolfram Sang…

Documentation/devicetree/bindings/soc/renesas/renesas,rzn1-gpioirqmux.yaml line 44

Quoted 6 lines
Documentation/devicetree/bindings/soc/renesas/renesas,rzn1-gpioirqmux.yaml new file +6 -0
+  interrupt-map:
+    description:
+      Specifies the mapping from external GPIO interrupt lines to the output
+      interrupts. The array items have to be ordered with the first item
+      related to the output line 0 (IRQ 103), the next one to the output line 1
+      (IRQ 104) and so on up to the output line 8 (IRQ 110).  

maxItems 8?

Yes indeed and probably both
minItems: 1
maxItems: 8

Quoted 13 lines

Documentation/devicetree/bindings/soc/renesas/renesas,rzn1-gpioirqmux.yaml line 82

Quoted 12 lines
Documentation/devicetree/bindings/soc/renesas/renesas,rzn1-gpioirqmux.yaml new file +11 -0
+        /*
+         * The child interrupt number is computed using the following formula:
+         *    gpio_bank * 32 + gpio_number
+         *
+         * with:
+         *    - gpio_bank: The GPIO bank number
+         *          - 0 for GPIO0A,
+         *          - 1 for GPIO1A,
+         *          - 2 for GPIO2A
+         *    - gpio_number: Number of the gpio in the bank (0..31)
+         */  
Quoted 3 lines

I wonder if this comment wouldn't be better in the interrupt-map description above?

I will move in the description.

Best regards,
Hervé

#20 lore raw

PATCH v3 7/8 soc: renesas: Add support for Renesas RZ/N1 GPIO Interrupt Multiplexer

In reply to Herve Codina (Schneider Electric)

On the Renesas RZ/N1 SoC, GPIOs can generate interruptions. Those interruption lines are multiplexed by the GPIO Interrupt Multiplexer in order to map 32 * 3 GPIO interrupt lines to 8 GIC interrupt lines.

The GPIO interrupt multiplexer IP does nothing but select 8 GPIO IRQ lines out of the 96 available to wire them to the GIC input lines.

---
 drivers/soc/renesas/Kconfig       |   4 ++
 drivers/soc/renesas/Makefile      |   1 +
 drivers/soc/renesas/rzn1_irqmux.c | 110 ++++++++++++++++++++++++++++++
 3 files changed, 115 insertions(+)
 create mode 100644 drivers/soc/renesas/rzn1_irqmux.c
drivers/soc/renesas/Kconfig +4 -0
index 719b7f4f376f..0878b6884515 100644
@@ -58,6 +58,7 @@ config ARCH_RZN1
 	select PM
 	select PM_GENERIC_DOMAINS
 	select ARM_AMBA
+	select RZN1_IRQMUX
 
 if ARM && ARCH_RENESAS
 
@@ -447,6 +448,9 @@ config PWC_RZV2M
 config RST_RCAR
 	bool "Reset Controller support for R-Car" if COMPILE_TEST
 
+config RZN1_IRQMUX
+	bool "Renesas RZ/N1 GPIO IRQ multiplexer support" if COMPILE_TEST
+
 config SYSC_RZ
 	bool "System controller for RZ SoCs" if COMPILE_TEST
 
drivers/soc/renesas/Makefile +1 -0
index 3bdcc6a395d5..daa932c7698d 100644
@@ -14,4 +14,5 @@ obj-$(CONFIG_SYS_R9A09G057)	+= r9a09g057-sys.o
 # Family
 obj-$(CONFIG_PWC_RZV2M)		+= pwc-rzv2m.o
 obj-$(CONFIG_RST_RCAR)		+= rcar-rst.o
+obj-$(CONFIG_RZN1_IRQMUX)		+= rzn1_irqmux.o
 obj-$(CONFIG_SYSC_RZ)		+= rz-sysc.o
drivers/soc/renesas/rzn1_irqmux.c new file +110 -0

110 lines not on this page · raw message

Signature · 1 line
2.51.0
#21 lore raw

Re: [PATCH v3 7/8] soc: renesas: Add support for Renesas RZ/N1 GPIO Interrupt Multiplexer

Hi Herve,

drivers/soc/renesas/rzn1_irqmux.c line 17

Quoted 3 lines
drivers/soc/renesas/rzn1_irqmux.c new file +3 -0
+#define IRQMUX_MAX_IRQS 8
+
+static int irqmux_setup(struct device *dev, struct device_node *np, u32 __iomem *regs)

The whole driver would benefit from a 'rzn1_irqmux' instead of 'irqmux' prefix, I'd say.

drivers/soc/renesas/rzn1_irqmux.c line 51

Quoted 10 lines
drivers/soc/renesas/rzn1_irqmux.c new file +10 -0
+	for_each_of_imap_item(&imap_parser, &imap_item) {
+		/*
+		 * The child #address-cells is 0 (already checked). The first
+		 * value in imap item is the src hwirq.
+		 *
+		 * imap items matches 1:1 the interrupt lines that could
+		 * be configured by registers (same order, same number).
+		 * Configure the related register with the src hwirq retrieved
+		 * from the interrupt-map.
+		 */

I haven't looked into the above for_each_of_imap_item-helper. But wouldn't it be possibleto retrieve the GIC_SPI number as well and use the correct register based on that? That would remove the need of an already sorted interrupt-map.

drivers/soc/renesas/rzn1_irqmux.c line 55

Quoted 4 lines
drivers/soc/renesas/rzn1_irqmux.c new file +4 -0
+		if (index > IRQMUX_MAX_IRQS) {
+			of_node_put(imap_item.parent_args.np);
+			dev_err(dev, "too much items in interrupt-map\n");
+			return -EINVAL;

-E2BIG? With such a unique errno, we could even drop the dev_err.

Quoted 18 lines
drivers/soc/renesas/rzn1_irqmux.c new file +18 -0
+		}
+
+		writel(imap_item.child_imap[0], regs + index);
+		index++;
+	}
+
+	return 0;
+}
+
+static int irqmux_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	u32 __iomem *regs;
+	int nr_irqs;
+	int ret;
+
+	regs = devm_platform_ioremap_resource(pdev, 0);

drivers/soc/renesas/rzn1_irqmux.c line 83

Quoted 10 lines
drivers/soc/renesas/rzn1_irqmux.c new file +10 -0
+	if (IS_ERR(regs))
+		return PTR_ERR(regs);
+
+	nr_irqs = of_irq_count(np);
+	if (nr_irqs < 0)
+		return nr_irqs;
+
+	if (nr_irqs > IRQMUX_MAX_IRQS) {
+		dev_err(dev, "too many output interrupts\n");
+		return -ENOENT;

-E2BIG? Wait, isn't this the same check twice?

Thanks for this work,

Wolfram

#22 lore raw

Re: [PATCH v3 7/8] soc: renesas: Add support for Renesas RZ/N1 GPIO Interrupt Multiplexer

Hi Wolfram,

Quoted 8 lines · On Fri, 19 Sep 2025 11:41:39 +0200 Wolfram Sang…

Hi Herve,

drivers/soc/renesas/rzn1_irqmux.c line 17

Quoted 3 lines
drivers/soc/renesas/rzn1_irqmux.c new file +3 -0
+#define IRQMUX_MAX_IRQS 8
+
+static int irqmux_setup(struct device *dev, struct device_node *np, u32 __iomem *regs)  

The whole driver would benefit from a 'rzn1_irqmux' instead of 'irqmux' prefix, I'd say.

Agree, I will used the 'rzn1_irqmux' prefix.

Quoted 16 lines

drivers/soc/renesas/rzn1_irqmux.c line 51

Quoted 11 lines
drivers/soc/renesas/rzn1_irqmux.c new file +10 -0
+	for_each_of_imap_item(&imap_parser, &imap_item) {
+		/*
+		 * The child #address-cells is 0 (already checked). The first
+		 * value in imap item is the src hwirq.
+		 *
+		 * imap items matches 1:1 the interrupt lines that could
+		 * be configured by registers (same order, same number).
+		 * Configure the related register with the src hwirq retrieved
+		 * from the interrupt-map.
+		 */  

I haven't looked into the above for_each_of_imap_item-helper. But wouldn't it be possibleto retrieve the GIC_SPI number as well and use the correct register based on that? That would remove the need of an already sorted interrupt-map.

Hum, this give the knowledge of the GIC interrupt number in the driver itself.

Not sure that the mapping between the output interrupt line number N (handled by register index N) and the GIC interrupt number X should be hardcoded in the driver.

In my v1 series iteration, I used the 'interrupts' property to provide this missing information:
interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>, /* line 0 (reg index 0) route to GIC 103 */

                <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>, /* line 1 (reg index 1) route to GIC 104 */
                <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>, /* line 2 (reg index 2) route to GIC 105 */
                ...

Base on the interrupts table and the interrupt-map, I deduce the reg index:
- From interrupt-map, got a GIC interrupt number
- From interrupts table and the GIC interrupt number, got the line/reg index.

Rob asked to use only interrupt-map and use directly the interrupt-map index as the hardware index:
https://lore.kernel.org/lkml/[email protected]/

Quoted 7 lines

drivers/soc/renesas/rzn1_irqmux.c line 55

Quoted 5 lines
drivers/soc/renesas/rzn1_irqmux.c new file +4 -0
+		if (index > IRQMUX_MAX_IRQS) {
+			of_node_put(imap_item.parent_args.np);
+			dev_err(dev, "too much items in interrupt-map\n");
+			return -EINVAL;  

-E2BIG? With such a unique errno, we could even drop the dev_err.

Yes sure.

Quoted 23 lines
Quoted 23 lines
drivers/soc/renesas/rzn1_irqmux.c new file +22 -0
+		}
+
+		writel(imap_item.child_imap[0], regs + index);
+		index++;
+	}
+
+	return 0;
+}
+
+static int irqmux_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	u32 __iomem *regs;
+	int nr_irqs;
+	int ret;
+
+	regs = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(regs))
+		return PTR_ERR(regs);
+
+	nr_irqs = of_irq_count(np);
Quoted 8 lines

drivers/soc/renesas/rzn1_irqmux.c line 83

Quoted 6 lines
drivers/soc/renesas/rzn1_irqmux.c new file +6 -0
+	if (nr_irqs < 0)
+		return nr_irqs;
+
+	if (nr_irqs > IRQMUX_MAX_IRQS) {
+		dev_err(dev, "too many output interrupts\n");
+		return -ENOENT;  

-E2BIG? Wait, isn't this the same check twice?

This is not the same check but this one should not be there.

Indeed of_irq_count() counts the number of items available in the 'interrupts' property. This is not used anymore.

I missed to remove it from v1 to v2 updates (and also from v2 to v3).

The of_irq_count() call and related checks will be remove in the next iteration.

Best regards,
Hervé

#23 lore raw

Re: [PATCH v3 7/8] soc: renesas: Add support for Renesas RZ/N1 GPIO Interrupt Multiplexer

Quoted 4 lines

Rob asked to use only interrupt-map and use directly the interrupt-map index as the hardware index:
https://lore.kernel.org/lkml/[email protected]/

I agree with that. Currently an interrupt-map entry looks like:

interrupt-map = <0 &gic GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>,

And the number after GIC_SPI determines the index register, no? Can't we simply say 'index = <SPI_nr_from_dt> - 103' incl. some sanity checks?

#24 lore raw

Re: [PATCH v3 7/8] soc: renesas: Add support for Renesas RZ/N1 GPIO Interrupt Multiplexer

Hi Wolfram,

Quoted 11 lines · On Fri, 19 Sep 2025 16:40:06 +0200 Wolfram Sang…
Quoted 3 lines

Rob asked to use only interrupt-map and use directly the interrupt-map index as the hardware index:
https://lore.kernel.org/lkml/[email protected]/

I agree with that. Currently an interrupt-map entry looks like:

interrupt-map = <0 &gic GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>,

And the number after GIC_SPI determines the index register, no? Can't we simply say 'index = <SPI_nr_from_dt> - 103' incl. some sanity checks?

And so 103 used to compute the index is hardcoded on the driver.

Further more the wiring of irq-mux interrupt output to the GIC input line depends on the irq-mux integration and not the irq-mux itself. Nothing in the irq-mux itself requires a specific connection to the GIC.

But well, without adding this mapping information in the DT, maybe a table in the driver in order to determine reg index from GIC IRQ number.

kind of:
static u8 reg_index[8] = {103, 104, 105, ... , 110};

Base on GIC IRQ number retrieve from the interrupt-map item, we search for the index in reg_index that match this number. The index found is the index used to access the register.

What do you think about this?

Best regards,
Hervé

#25 lore raw

Re: [PATCH v3 7/8] soc: renesas: Add support for Renesas RZ/N1 GPIO Interrupt Multiplexer

Quoted 9 lines

kind of:
static u8 reg_index[8] = {103, 104, 105, ... , 110};

Base on GIC IRQ number retrieve from the interrupt-map item, we search for the index in reg_index that match this number. The index found is the index used to access the register.

What do you think about this?

I sure like it better than a fixed ordering in DT. And the advantage compared to subtracting 103 is that reg_index can be flexible in case we want to support other SoCs than RZ/N1?

#26 lore raw

Re: [PATCH v3 7/8] soc: renesas: Add support for Renesas RZ/N1 GPIO Interrupt Multiplexer

In reply to Herve Codina (Schneider Electric)

Hi Hervé,

Quoted 8 lines · Herve Codina (Schneider Electric)

On the Renesas RZ/N1 SoC, GPIOs can generate interruptions. Those interruption lines are multiplexed by the GPIO Interrupt Multiplexer in order to map 32 * 3 GPIO interrupt lines to 8 GIC interrupt lines.

The GPIO interrupt multiplexer IP does nothing but select 8 GPIO IRQ lines out of the 96 available to wire them to the GIC input lines.

Thanks for your patch!

drivers/soc/renesas/rzn1_irqmux.c line 97

Quoted 8 lines
drivers/soc/renesas/rzn1_irqmux.c new file +5 -0
 
+static const struct of_device_id irqmux_of_match[] = {
+       { .compatible = "renesas,rzn1-gpioirqmux", },
+       { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, irq_mux_of_match);
                           ^^^^^^^^^^^^^^^^
                           irqmux_of_match

Interestingly, this built fine for me before, presumably until commit 5ab23c7923a1d2ae ("modpost: Create modalias for builtin modules") in v6.18-rc1.

Gr{oetje,eeting}s,

Geert

Signature · 5 lines
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds
#27 lore raw

Re: [PATCH v3 7/8] soc: renesas: Add support for Renesas RZ/N1 GPIO Interrupt Multiplexer

Quoted 9 lines

drivers/soc/renesas/rzn1_irqmux.c line 97

Quoted 6 lines
drivers/soc/renesas/rzn1_irqmux.c new file +5 -0
+static const struct of_device_id irqmux_of_match[] = {
+       { .compatible = "renesas,rzn1-gpioirqmux", },
+       { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, irq_mux_of_match);
                           ^^^^^^^^^^^^^^^^
                           irqmux_of_match
Quoted 3 lines

Interestingly, this built fine for me before, presumably until commit 5ab23c7923a1d2ae ("modpost: Create modalias for builtin modules") in v6.18-rc1.

This should be fixed in v4 already as a side effect of my request for a better namespace prefix.

#28 lore raw

Re: [PATCH v3 7/8] soc: renesas: Add support for Renesas RZ/N1 GPIO Interrupt Multiplexer

Hi Wolfram,

Quoted 8 lines · Wolfram Sang
Quoted 8 lines

drivers/soc/renesas/rzn1_irqmux.c line 97

Quoted 5 lines
drivers/soc/renesas/rzn1_irqmux.c new file +5 -0
+static const struct of_device_id irqmux_of_match[] = {
+       { .compatible = "renesas,rzn1-gpioirqmux", },
+       { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, irq_mux_of_match);
                           ^^^^^^^^^^^^^^^^
                           irqmux_of_match
Quoted 6 lines
Quoted 3 lines

Interestingly, this built fine for me before, presumably until commit 5ab23c7923a1d2ae ("modpost: Create modalias for builtin modules") in v6.18-rc1.

This should be fixed in v4 already as a side effect of my request for a better namespace prefix.

Thanks! Sorry, I really thought I had the latest version in my tree...

Gr{oetje,eeting}s,

Geert

Signature · 5 lines
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds
#29 lore raw

PATCH v3 8/8 ARM: dts: r9a06g032: Add support for GPIO interrupts

In reply to Herve Codina (Schneider Electric)

In the RZ/N1 SoC, the GPIO interrupts are multiplexed using the GPIO Interrupt Multiplexer.

Add the multiplexer node and connect GPIO interrupt lines to the multiplexer.

The interrupt-map available in the multiplexer node has to be updated in dts files depending on the GPIO usage. Indeed, the usage of an interrupt for a GPIO is board dependent.

Up to 8 GPIOs can be used as an interrupt line (one per multiplexer output interrupt).

---
 arch/arm/boot/dts/renesas/r9a06g032.dtsi | 49 ++++++++++++++++++++++++
 1 file changed, 49 insertions(+)
arch/arm/boot/dts/renesas/r9a06g032.dtsi +49 -0
index da977cdd8487..3cd7ac38eb7a 100644
@@ -534,6 +534,14 @@ gpio0a: gpio-port@0 {
 				#gpio-cells = <2>;
 				snps,nr-gpios = <32>;
 				reg = <0>;
+
+				interrupt-controller;
+				interrupt-parent = <&gpioirqmux>;
+				interrupts = < 0  1  2  3  4  5  6  7
+					       8  9 10 11 12 13 14 15
+					      16 17 18 19 20 21 22 23
+					      24 25 26 27 28 29 30 31 >;
+				#interrupt-cells = <2>;
 			};
 
 			/* GPIO0b[0..1]   connected to pins GPIO1..2   */
@@ -576,6 +584,14 @@ gpio1a: gpio-port@0 {
 				#gpio-cells = <2>;
 				snps,nr-gpios = <32>;
 				reg = <0>;
+
+				interrupt-controller;
+				interrupt-parent = <&gpioirqmux>;
+				interrupts = < 32 33 34 35 36 37 38 39
+					       40 41 42 43 44 45 46 47
+					       48 49 50 51 52 53 54 55
+					       56 57 58 59 60 61 62 63 >;
+				#interrupt-cells = <2>;
 			};
 
 			/* GPIO1b[0..1]   connected to pins GPIO55..56 */
@@ -608,6 +624,14 @@ gpio2a: gpio-port@0 {
 				#gpio-cells = <2>;
 				snps,nr-gpios = <32>;
 				reg = <0>;
+
+				interrupt-controller;
+				interrupt-parent = <&gpioirqmux>;
+				interrupts = < 64 65 66 67 68 69 70 71
+					       72 73 74 75 76 77 78 79
+					       80 81 82 83 84 85 86 87
+					       88 89 90 91 92 93 94 95 >;
+				#interrupt-cells = <2>;
 			};
 
 			/* GPIO2b[0..9] connected to pins GPIO160..169 */
@@ -620,6 +644,31 @@ gpio2b: gpio-port@1 {
 			};
 		};
 
+		gpioirqmux: interrupt-controller@51000480 {
+			compatible = "renesas,r9a06g032-gpioirqmux", "renesas,rzn1-gpioirqmux";
+			reg = <0x51000480 0x20>;
+			#interrupt-cells = <1>;
+			#address-cells = <0>;
+			interrupt-map-mask = <0x7f>;
+
+			/*
+			 * interrupt-map has to be updated according to GPIO
+			 * usage. The order has to be kept. Only the src irq
+			 * (0 field) has to be updated with the needed GPIO
+			 * interrupt number.
+			 */
+			interrupt-map = <0 &gic GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>,
+					<0 &gic GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>,
+					<0 &gic GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>,
+					<0 &gic GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>,
+					<0 &gic GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>,
+					<0 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>,
+					<0 &gic GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>,
+					<0 &gic GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
+
+			status = "disabled";
+		};
+
 		can0: can@52104000 {
 			compatible = "renesas,r9a06g032-sja1000", "renesas,rzn1-sja1000";
 			reg = <0x52104000 0x800>;
Signature · 1 line
2.51.0
#30 lore raw

Re: [PATCH v3 8/8] ARM: dts: r9a06g032: Add support for GPIO interrupts

Quoted 4 lines
arch/arm/boot/dts/renesas/r9a06g032.dtsi +4 -0
+			/*
+			 * interrupt-map has to be updated according to GPIO
+			 * usage. The order has to be kept. Only the src irq
+			 * (0 field) has to be updated with the needed GPIO

arch/arm/boot/dts/renesas/r9a06g032.dtsi gpio2b: gpio-port@1 { · line 667

Quoted 10 lines
arch/arm/boot/dts/renesas/r9a06g032.dtsi +10 -0
+			 * interrupt number.
+			 */
+			interrupt-map = <0 &gic GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>,
+					<0 &gic GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>,
+					<0 &gic GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>,
+					<0 &gic GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>,
+					<0 &gic GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>,
+					<0 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>,
+					<0 &gic GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>,
+					<0 &gic GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;

I'd think this should be dropped from the include and added in the board file instead. I did this with my board and it works fine.

#31 lore raw

Re: [PATCH v3 8/8] ARM: dts: r9a06g032: Add support for GPIO interrupts

Quoted 9 lines · On Fri, 19 Sep 2025 11:42:46 +0200 Wolfram Sang…
Quoted 9 lines
arch/arm/boot/dts/renesas/r9a06g032.dtsi +9 -0
+			/*
+			 * interrupt-map has to be updated according to GPIO
+			 * usage. The order has to be kept. Only the src irq
+			 * (0 field) has to be updated with the needed GPIO
+			 * interrupt number.
+			 */
+			interrupt-map = <0 &gic GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>,
+					<0 &gic GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>,
+					<0 &gic GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>,
Quoted 9 lines

arch/arm/boot/dts/renesas/r9a06g032.dtsi gpio2b: gpio-port@1 { · line 667

Quoted 5 lines
arch/arm/boot/dts/renesas/r9a06g032.dtsi +5 -0
+					<0 &gic GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>,
+					<0 &gic GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>,
+					<0 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>,
+					<0 &gic GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>,
+					<0 &gic GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;  

I'd think this should be dropped from the include and added in the board file instead. I did this with my board and it works fine.

I can only reduce the table but I need to keep the interrupt-map property.

'interrupt-map' is a required property. If the board doesn't use any interrupt GPIO, its dts has no reason to set the interrupt-map.

In that case, if I fully remove 'interrupt-map' in the dtsi, dtbs_check will not be happy. Indeed, a required property is missing.

Also, having the full table containing the 8 items with the correct GIC interrupt number and the correct order could help a user to route the GPIO line to one of those 8 items.

The '0' field use as interrupt source matches the registers reset value of the irq-mux controller.

With that in mind, do you still think that I should reduce this table?

Best regards,
Hervé

#32 lore raw

Re: [PATCH v3 8/8] ARM: dts: r9a06g032: Add support for GPIO interrupts

Quoted 3 lines

'interrupt-map' is a required property. If the board doesn't use any interrupt GPIO, its dts has no reason to set the interrupt-map.

Why is 'interrupt-map' then a required property? Can we drop it from the requirements?

#33 lore raw

Re: [PATCH v3 8/8] ARM: dts: r9a06g032: Add support for GPIO interrupts

Quoted 6 lines · On Fri, 19 Sep 2025 16:41:05 +0200 Wolfram Sang…
Quoted 2 lines

'interrupt-map' is a required property. If the board doesn't use any interrupt GPIO, its dts has no reason to set the interrupt-map.

Why is 'interrupt-map' then a required property? Can we drop it from the requirements?

I need to check in details but 'interrupt-map' should be kept required. Indeed, irq-mux needs this property to work. It is not an optional one.

I need to look at the 'make CHECK_DTBS=y' behavior when required property is missing in a not enabled node (node with status = "disabled").

Also, got some:
Warning (interrupts_property): /soc/interrupt-controller@51000480: Missing interrupt-controller or interrupt-map property

This could be due to the presence of #interrupt-cells or the node name (not sure). As I need to rename the node (Conor's comment), I will see if the warning disappear. If the warning is due to #interrupt-cells, I don't think that removing #interrupt-cells is the right solution to avoid the warning.

That's said, I need to perform some local tries. I will keep you informed.

Best regards
Hervé

#34 lore raw

Re: [PATCH v3 8/8] ARM: dts: r9a06g032: Add support for GPIO interrupts

Hi Wolfram,

Quoted 19 lines · On Fri, 19 Sep 2025 19:12:11 +0200 Herve Codina <[email protected]>…
Quoted 6 lines · On Fri, 19 Sep 2025 16:41:05 +0200 Wolfram Sang…
Quoted 2 lines

'interrupt-map' is a required property. If the board doesn't use any interrupt GPIO, its dts has no reason to set the interrupt-map.

Why is 'interrupt-map' then a required property? Can we drop it from the requirements?

I need to check in details but 'interrupt-map' should be kept required. Indeed, irq-mux needs this property to work. It is not an optional one.

I need to look at the 'make CHECK_DTBS=y' behavior when required property is missing in a not enabled node (node with status = "disabled").

Also, got some:
Warning (interrupts_property): /soc/interrupt-controller@51000480: Missing interrupt-controller or interrupt-map property

Quoted 7 lines

This could be due to the presence of #interrupt-cells or the node name (not sure). As I need to rename the node (Conor's comment), I will see if the warning disappear. If the warning is due to #interrupt-cells, I don't think that removing #interrupt-cells is the right solution to avoid the warning.

That's said, I need to perform some local tries. I will keep you informed.

If I remove the 'interrupt-map', I still have warnings from DTC:
r9a06g032.dtsi:647.45-664.5: Warning (interrupts_property): /soc/interrupt-controller@51000480: Missing interrupt-controller or interrupt-map property r9a06g032.dtsi:647.45-664.5: Warning (interrupts_property): /soc/interrupt-controller@51000480: Missing interrupt-controller or interrupt-map property r9a06g032.dtsi:647.45-664.5: Warning (interrupts_property): /soc/interrupt-controller@51000480: Missing interrupt-controller or interrupt-map property r9a06g032.dtsi:647.45-664.5: Warning (interrupt_provider): /soc/interrupt-controller@51000480: '#interrupt-cells' found, but node is not an interrupt provider r9a06g032-rzn1d400-eb.dtb: Warning (interrupt_map): Failed prerequisite 'interrupt_provider'

Indeed, the irq-mux node is referenced (interrupt-parent) in the gpio nodes. DTC checks that in that case irq-mux is correctly set. It has to be either an interrupt controller ('interrupt-controller' property) or a interrupt nexus node ('interrupt-map' property).

If I remove, the 'interrupt-map' property, DTC is not happy.

Also in that case, my node has '#interrupt-cells' set without being an interrupt controller of a interrupt nexus node and this leads to a warning too.

The only way to avoid warnings is to fully remove the irq-mux node and related references available in gpio nodes.

IHMO, I think we can leave with a reduce 'interrupt-map' array set in the irq-mux node in r9a06g032.dtsi file such as follow.
--- 8< ---

	interrupt-controller@51000480 {
		compatible = "renesas,r9a06g032-gpioirqmux", "renesas,rzn1-gpioirqmux";
		reg = <0x51000480 0x20>;
		#interrupt-cells = <1>;
		#address-cells = <0>;
		interrupt-map-mask = <0x7f>;

		/*
		 * interrupt-map has to be updated according to GPIO
		 * usage. The src irq (0 field) has to be updated with
		 * the needed GPIO interrupt number.
		 * More items can be added (up to 8). Those items must
		 * define a GIC SPI interrupt in the range 103 to 110.
		 */
		interrupt-map = <0 &gic GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;

		status = "disabled";
	};

--- 8< ---

Could this modification be ok on your side?

Best regards,
Hervé

#35 lore raw

Re: [PATCH v3 8/8] ARM: dts: r9a06g032: Add support for GPIO interrupts

Hi Hervé,

Quoted 8 lines

/*
* interrupt-map has to be updated according to GPIO
* usage. The src irq (0 field) has to be updated with
* the needed GPIO interrupt number.
* More items can be added (up to 8). Those items must
* define a GIC SPI interrupt in the range 103 to 110. */
interrupt-map = <0 &gic GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;

Thanks for digging into this. Gievn your results, I can live with a minimal interrupt-map, but ideally it should do nothing instead of mapping GPIO0? Will think about it...

All the best,

Wolfram

#36 lore raw
In reply to Herve Codina (Schneider Electric)
Quoted 43 lines · Herve Codina (Schneider Electric)

Hi,

This series adds support for GPIO and GPIO IRQ mux available in the RZ/N1 SoCs.

The first patches in this series are related to a new helper introduced to parse an interrupt-map property.
- patch 1: Introduce the helper (for_each_of_imap_item)
- patch 2: Add a unittest for the new helper
- patch 3 and 4: convert existing drivers to use this new helper

Patch 4 will conflicts with commit 40c26230a1bf ("irqchip: Use int type to store negative error codes") available in linux-next.

Patch 5 adds support for GPIO (device-tree description)

The last patches (6, 7 and 8) of the series are related to GPIO interrupts and GPIO IRQ multiplexer.

In the RZ/N1 SoCs, GPIO interrupts are wired to a GPIO IRQ multiplexer.

This multiplexer does nothing but select 8 GPIO IRQ lines out of the 96 available to wire them to the GIC input lines.

One upstreaming attempt have been done previously by Phil Edworthy [1] but the series has never been applied.

Based on my understanding, I have fully reworked the driver proposed by Phil and removed the IRQ domain. Indeed, the device doesn't handle interrupts. It just routes signals.

Also, as an interrupt-map property is used, the driver cannot be involved as an interrupt controller itself. It is a nexus node.

With that in mind,
- Patch 6 is related to the irq-mux binding.

- Patch 7 introduces the irq-mux driver.
This driver uses the 'for_each_of_imap_item' helper introduced previously. Indeed, the lines routing is defined by the interrupt-map property and the driver needs to set registers to apply this routing.

Quoted 7 lines

- Patch 8 is the RZ/N1 device-tree description update to have the support for the GPIO interrupts.

[1] https://lore.kernel.org/all/[email protected]/

Best regards,
Hervé

This whole thing is super interesting to me. I have a gpio irq mux of my own with a driver that is massively more complex than what you have here (it's a full on irqchip driver). I'm definitely gonna have to see if I can ape what you have done here and simplify what I have.

#37 lore raw

Hi Conor,

Quoted 49 lines · On Thu, 18 Sep 2025 16:37:39 +0100 Conor Dooley <[email protected]> wrote:
Quoted 48 lines · Herve Codina (Schneider Electric)

Hi,

This series adds support for GPIO and GPIO IRQ mux available in the RZ/N1 SoCs.

The first patches in this series are related to a new helper introduced to parse an interrupt-map property.
- patch 1: Introduce the helper (for_each_of_imap_item)
- patch 2: Add a unittest for the new helper
- patch 3 and 4: convert existing drivers to use this new helper

Patch 4 will conflicts with commit 40c26230a1bf ("irqchip: Use int type to store negative error codes") available in linux-next.

Patch 5 adds support for GPIO (device-tree description)

The last patches (6, 7 and 8) of the series are related to GPIO interrupts and GPIO IRQ multiplexer.

In the RZ/N1 SoCs, GPIO interrupts are wired to a GPIO IRQ multiplexer.

This multiplexer does nothing but select 8 GPIO IRQ lines out of the 96 available to wire them to the GIC input lines.

One upstreaming attempt have been done previously by Phil Edworthy [1] but the series has never been applied.

Based on my understanding, I have fully reworked the driver proposed by Phil and removed the IRQ domain. Indeed, the device doesn't handle interrupts. It just routes signals.

Also, as an interrupt-map property is used, the driver cannot be involved as an interrupt controller itself. It is a nexus node.

With that in mind,
- Patch 6 is related to the irq-mux binding.

- Patch 7 introduces the irq-mux driver.
This driver uses the 'for_each_of_imap_item' helper introduced previously. Indeed, the lines routing is defined by the interrupt-map property and the driver needs to set registers to apply this routing.

- Patch 8 is the RZ/N1 device-tree description update to have the support for the GPIO interrupts.

[1] https://lore.kernel.org/all/[email protected]/

Quoted 7 lines
Quoted 2 lines

Best regards,
Hervé

This whole thing is super interesting to me. I have a gpio irq mux of my own with a driver that is massively more complex than what you have here (it's a full on irqchip driver). I'm definitely gonna have to see if I can ape what you have done here and simplify what I have.

Glad to see that this is giving some ideas!

Best regards,
Hervé

Tested-by
#39 lore raw
Quoted 6 lines · Wolfram Sang
Quoted 3 lines

This series adds support for GPIO and GPIO IRQ mux available in the RZ/N1 SoCs.

I want to test this series today. From a glimpse, I might have some comments, so please wait a little before resending.

Despite the comments, the series works fine, so:

#40 lore raw
Quoted 11 lines · Wolfram Sang
Quoted 6 lines · Wolfram Sang
Quoted 3 lines

This series adds support for GPIO and GPIO IRQ mux available in the RZ/N1 SoCs.

I want to test this series today. From a glimpse, I might have some comments, so please wait a little before resending.

Despite the comments, the series works fine, so:

To be more precise: I actually tested patches 1, 5, 6, 7, 8.

Maybe I can test patch 4 later today on my RZ/A1-Genmai.

#41 lore raw
Quoted 2 lines

Maybe I can test patch 4 later today on my RZ/A1-Genmai.

That needs to wait until v3 of this series.