gpio: renesas: Add support for GPIO and related interrupts in RZ/N1 SoC
Subsystems (5)
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
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
@@ -157,6 +157,76 @@ const __be32 *of_irq_parse_imap_parent(const __be32 *imap, int len, struct of_phreturn 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
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
@@ -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
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
@@ -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
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
@@ -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
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
@@ -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
Re: [PATCH v3 5/8] ARM: dts: r9a06g032: Add GPIO controllers
Quoted 6 lines · Herve Codina (Schneider Electric)
Add GPIO controllers (Synosys DesignWare IPs) available in the r9a06g032 (RZ/N1D) SoC.
Signed-off-by Herve Codina (Schneider Electric) <[email protected]>Reviewed-by Wolfram Sang <[email protected]>Tested-by Wolfram Sang <[email protected]>
Maybe we can apply this already? It is useful on its own.
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.
Signed-off-by Herve Codina (Schneider Electric) <[email protected]>Reviewed-by Wolfram Sang <[email protected]>Tested-by Wolfram Sang <[email protected]>---
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
Signed-off-by Herve Codina (Schneider Electric) <[email protected]>Reviewed-by Wolfram Sang <[email protected]>Tested-by Wolfram Sang <[email protected]>---
Reviewed-by Bartosz Golaszewski <[email protected]>
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
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.
Signed-off-by Herve Codina (Schneider Electric) <[email protected]>Reviewed-by Wolfram Sang <[email protected]>Tested-by Wolfram Sang <[email protected]>---
Quoted 8 lines
Quoted 1 line
Reviewed-by Bartosz Golaszewski <[email protected]>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
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.
Signed-off-by Herve Codina (Schneider Electric) <[email protected]>Reviewed-by Wolfram Sang <[email protected]>Tested-by Wolfram Sang <[email protected]>---
Reviewed-by Bartosz Golaszewski <[email protected]>
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é
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
@@ -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
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.
Signed-off-by Herve Codina (Schneider Electric) <[email protected]>--- .../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,
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
Signed-off-by Herve Codina (Schneider Electric) <[email protected]>--- .../soc/renesas/renesas,rzn1-gpioirqmux.yaml | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 Documentation/devicetree/bindings/soc/renesas/renesas,rzn1-gpioirqmux.yamlThis 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,
Acked-by Conor Dooley <[email protected]>
Best regards,
Hervé
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.
Signed-off-by Herve Codina (Schneider Electric) <[email protected]>--- .../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!
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.
Signed-off-by Herve Codina (Schneider Electric) <[email protected]>--- .../soc/renesas/renesas,rzn1-gpioirqmux.yaml | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 Documentation/devicetree/bindings/soc/renesas/renesas,rzn1-gpioirqmux.yamlThis 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é
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
Signed-off-by Herve Codina (Schneider Electric) <[email protected]>--- .../soc/renesas/renesas,rzn1-gpioirqmux.yaml | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 Documentation/devicetree/bindings/soc/renesas/renesas,rzn1-gpioirqmux.yamlThis 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.
Rob Herring
maintainerRe: [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
Signed-off-by Herve Codina (Schneider Electric) <[email protected]>--- .../soc/renesas/renesas,rzn1-gpioirqmux.yaml | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 Documentation/devicetree/bindings/soc/renesas/renesas,rzn1-gpioirqmux.yamlThis 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.
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?
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é
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
@@ -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
@@ -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
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
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_SPInumber 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 thedev_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é
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?
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_SPI103IRQ_TYPE_LEVEL_HIGH>,And the number after
GIC_SPIdetermines 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é
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_indexthat 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?
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.
Signed-off-by Herve Codina (Schneider Electric) <[email protected]>
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_matchInterestingly, 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
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.
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
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
@@ -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
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.
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é
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?
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é
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é
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 &gicGIC_SPI103IRQ_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
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 helperPatch 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.
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 helperPatch 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.
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é
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.
Wolfram Sang
Tested-byQuoted 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:
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:
Tested-by Wolfram Sang <[email protected]>
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.
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.