* [PATCH v2 1/8] ARM: dts: r9a06g032: Add GPIO controllers
2025-09-09 12:00 [PATCH v2 0/8] gpio: renesas: Add support for GPIO and related interrupts in RZ/N1 SoC Herve Codina (Schneider Electric)
@ 2025-09-09 12:00 ` Herve Codina (Schneider Electric)
2025-09-10 11:17 ` Wolfram Sang
2025-09-09 12:00 ` [PATCH v2 2/8] dt-bindings: soc: renesas: Add the Renesas RZ/N1 GPIO Interrupt Multiplexer Herve Codina (Schneider Electric)
` (7 subsequent siblings)
8 siblings, 1 reply; 18+ messages in thread
From: Herve Codina (Schneider Electric) @ 2025-09-09 12:00 UTC (permalink / raw)
To: Wolfram Sang, Hoan Tran, Linus Walleij, Bartosz Golaszewski,
Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Geert Uytterhoeven, Magnus Damm, Saravana Kannan, Serge Semin,
Herve Codina
Cc: Phil Edworthy, linux-gpio, devicetree, linux-kernel,
linux-renesas-soc, Pascal Eberhard, Miquel Raynal,
Thomas Petazzoni
Add GPIO controllers (Synosys DesignWare IPs) available in the
r9a06g032 (RZ/N1D) SoC.
Signed-off-by: Herve Codina (Schneider Electric) <herve.codina@bootlin.com>
---
arch/arm/boot/dts/renesas/r9a06g032.dtsi | 121 +++++++++++++++++++++++
1 file changed, 121 insertions(+)
diff --git a/arch/arm/boot/dts/renesas/r9a06g032.dtsi b/arch/arm/boot/dts/renesas/r9a06g032.dtsi
index 13a60656b044..da977cdd8487 100644
--- a/arch/arm/boot/dts/renesas/r9a06g032.dtsi
+++ b/arch/arm/boot/dts/renesas/r9a06g032.dtsi
@@ -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>;
--
2.51.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* Re: [PATCH v2 1/8] ARM: dts: r9a06g032: Add GPIO controllers
2025-09-09 12:00 ` [PATCH v2 1/8] ARM: dts: r9a06g032: Add GPIO controllers Herve Codina (Schneider Electric)
@ 2025-09-10 11:17 ` Wolfram Sang
0 siblings, 0 replies; 18+ messages in thread
From: Wolfram Sang @ 2025-09-10 11:17 UTC (permalink / raw)
To: Herve Codina (Schneider Electric)
Cc: Hoan Tran, Linus Walleij, Bartosz Golaszewski, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Geert Uytterhoeven,
Magnus Damm, Saravana Kannan, Serge Semin, Phil Edworthy,
linux-gpio, devicetree, linux-kernel, linux-renesas-soc,
Pascal Eberhard, Miquel Raynal, Thomas Petazzoni
[-- Attachment #1: Type: text/plain, Size: 719 bytes --]
On Tue, Sep 09, 2025 at 02:00:32PM +0200, Herve Codina (Schneider Electric) wrote:
> Add GPIO controllers (Synosys DesignWare IPs) available in the
> r9a06g032 (RZ/N1D) SoC.
>
> Signed-off-by: Herve Codina (Schneider Electric) <herve.codina@bootlin.com>
Of course, I couldn't test and review all GPIOs but the GPIOs I tested
on my N1D-DB and EB work nicely so far. Previous tests didn't work
because I simply missed to setup a configuration switch properly for
this case. Phew!
Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Tested-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
I won't have the bandwidth to review the irq patches. Maybe I can donate
tests, but no promises...
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v2 2/8] dt-bindings: soc: renesas: Add the Renesas RZ/N1 GPIO Interrupt Multiplexer
2025-09-09 12:00 [PATCH v2 0/8] gpio: renesas: Add support for GPIO and related interrupts in RZ/N1 SoC Herve Codina (Schneider Electric)
2025-09-09 12:00 ` [PATCH v2 1/8] ARM: dts: r9a06g032: Add GPIO controllers Herve Codina (Schneider Electric)
@ 2025-09-09 12:00 ` Herve Codina (Schneider Electric)
2025-09-10 14:33 ` Rob Herring
2025-09-09 12:00 ` [PATCH v2 3/8] of/irq: Introduce for_each_of_imap_item Herve Codina (Schneider Electric)
` (6 subsequent siblings)
8 siblings, 1 reply; 18+ messages in thread
From: Herve Codina (Schneider Electric) @ 2025-09-09 12:00 UTC (permalink / raw)
To: Wolfram Sang, Hoan Tran, Linus Walleij, Bartosz Golaszewski,
Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Geert Uytterhoeven, Magnus Damm, Saravana Kannan, Serge Semin,
Herve Codina
Cc: Phil Edworthy, linux-gpio, devicetree, linux-kernel,
linux-renesas-soc, Pascal Eberhard, Miquel Raynal,
Thomas Petazzoni
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) <herve.codina@bootlin.com>
---
.../soc/renesas/renesas,rzn1-gpioirqmux.yaml | 86 +++++++++++++++++++
1 file changed, 86 insertions(+)
create mode 100644 Documentation/devicetree/bindings/soc/renesas/renesas,rzn1-gpioirqmux.yaml
diff --git a/Documentation/devicetree/bindings/soc/renesas/renesas,rzn1-gpioirqmux.yaml b/Documentation/devicetree/bindings/soc/renesas/renesas,rzn1-gpioirqmux.yaml
new file mode 100644
index 000000000000..4a5aad8b2c44
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/renesas/renesas,rzn1-gpioirqmux.yaml
@@ -0,0 +1,86 @@
+# 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 <herve.codina@bootlin.com>
+
+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;
+ #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 */
+ };
--
2.51.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* Re: [PATCH v2 2/8] dt-bindings: soc: renesas: Add the Renesas RZ/N1 GPIO Interrupt Multiplexer
2025-09-09 12:00 ` [PATCH v2 2/8] dt-bindings: soc: renesas: Add the Renesas RZ/N1 GPIO Interrupt Multiplexer Herve Codina (Schneider Electric)
@ 2025-09-10 14:33 ` Rob Herring
2025-09-11 7:43 ` Herve Codina
0 siblings, 1 reply; 18+ messages in thread
From: Rob Herring @ 2025-09-10 14:33 UTC (permalink / raw)
To: Herve Codina (Schneider Electric)
Cc: Wolfram Sang, Hoan Tran, Linus Walleij, Bartosz Golaszewski,
Krzysztof Kozlowski, Conor Dooley, Geert Uytterhoeven,
Magnus Damm, Saravana Kannan, Serge Semin, Phil Edworthy,
linux-gpio, devicetree, linux-kernel, linux-renesas-soc,
Pascal Eberhard, Miquel Raynal, Thomas Petazzoni
On Tue, Sep 09, 2025 at 02:00:33PM +0200, Herve Codina (Schneider Electric) wrote:
> 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) <herve.codina@bootlin.com>
> ---
> .../soc/renesas/renesas,rzn1-gpioirqmux.yaml | 86 +++++++++++++++++++
> 1 file changed, 86 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/soc/renesas/renesas,rzn1-gpioirqmux.yaml
Documentation/devicetree/bindings/soc/renesas/renesas,rzn1-gpioirqmux.example.dts:42.13-45.34: Warning (interrupt_map): /example-0/interrupt-controller@51000480:interrupt-map: Missing property '#address-cells' in node /example-0/interrupt-controller, using 0 as fallback
Documentation/devicetree/bindings/soc/renesas/renesas,rzn1-gpioirqmux.example.dts:42.13-45.34: Warning (interrupt_map): /example-0/interrupt-controller@51000480:interrupt-map: Missing property '#address-cells' in node /example-0/interrupt-controller, using 0 as fallback
Documentation/devicetree/bindings/soc/renesas/renesas,rzn1-gpioirqmux.example.dts:42.13-45.34: Warning (interrupt_map): /example-0/interrupt-controller@51000480:interrupt-map: Missing property '#address-cells' in node /example-0/interrupt-controller, using 0 as fallback
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v2 2/8] dt-bindings: soc: renesas: Add the Renesas RZ/N1 GPIO Interrupt Multiplexer
2025-09-10 14:33 ` Rob Herring
@ 2025-09-11 7:43 ` Herve Codina
0 siblings, 0 replies; 18+ messages in thread
From: Herve Codina @ 2025-09-11 7:43 UTC (permalink / raw)
To: Rob Herring
Cc: Wolfram Sang, Hoan Tran, Linus Walleij, Bartosz Golaszewski,
Krzysztof Kozlowski, Conor Dooley, Geert Uytterhoeven,
Magnus Damm, Saravana Kannan, Serge Semin, Phil Edworthy,
linux-gpio, devicetree, linux-kernel, linux-renesas-soc,
Pascal Eberhard, Miquel Raynal, Thomas Petazzoni
Hi Rob,
On Wed, 10 Sep 2025 09:33:16 -0500
Rob Herring <robh@kernel.org> wrote:
> On Tue, Sep 09, 2025 at 02:00:33PM +0200, Herve Codina (Schneider Electric) wrote:
> > 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) <herve.codina@bootlin.com>
> > ---
> > .../soc/renesas/renesas,rzn1-gpioirqmux.yaml | 86 +++++++++++++++++++
> > 1 file changed, 86 insertions(+)
> > create mode 100644 Documentation/devicetree/bindings/soc/renesas/renesas,rzn1-gpioirqmux.yaml
>
> Documentation/devicetree/bindings/soc/renesas/renesas,rzn1-gpioirqmux.example.dts:42.13-45.34: Warning (interrupt_map): /example-0/interrupt-controller@51000480:interrupt-map: Missing property '#address-cells' in node /example-0/interrupt-controller, using 0 as fallback
> Documentation/devicetree/bindings/soc/renesas/renesas,rzn1-gpioirqmux.example.dts:42.13-45.34: Warning (interrupt_map): /example-0/interrupt-controller@51000480:interrupt-map: Missing property '#address-cells' in node /example-0/interrupt-controller, using 0 as fallback
> Documentation/devicetree/bindings/soc/renesas/renesas,rzn1-gpioirqmux.example.dts:42.13-45.34: Warning (interrupt_map): /example-0/interrupt-controller@51000480:interrupt-map: Missing property '#address-cells' in node /example-0/interrupt-controller, using 0 as fallback
Ok, I will add '#address-cells = <0>;' in the interrupt-controller node
available in the example.
Best regards,
Hervé
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v2 3/8] of/irq: Introduce for_each_of_imap_item
2025-09-09 12:00 [PATCH v2 0/8] gpio: renesas: Add support for GPIO and related interrupts in RZ/N1 SoC Herve Codina (Schneider Electric)
2025-09-09 12:00 ` [PATCH v2 1/8] ARM: dts: r9a06g032: Add GPIO controllers Herve Codina (Schneider Electric)
2025-09-09 12:00 ` [PATCH v2 2/8] dt-bindings: soc: renesas: Add the Renesas RZ/N1 GPIO Interrupt Multiplexer Herve Codina (Schneider Electric)
@ 2025-09-09 12:00 ` Herve Codina (Schneider Electric)
2025-09-10 10:33 ` kernel test robot
2025-09-10 20:38 ` kernel test robot
2025-09-09 12:00 ` [PATCH v2 4/8] of: unittest: Add a test case for for_each_of_imap_item iterator Herve Codina (Schneider Electric)
` (5 subsequent siblings)
8 siblings, 2 replies; 18+ messages in thread
From: Herve Codina (Schneider Electric) @ 2025-09-09 12:00 UTC (permalink / raw)
To: Wolfram Sang, Hoan Tran, Linus Walleij, Bartosz Golaszewski,
Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Geert Uytterhoeven, Magnus Damm, Saravana Kannan, Serge Semin,
Herve Codina
Cc: Phil Edworthy, linux-gpio, devicetree, linux-kernel,
linux-renesas-soc, Pascal Eberhard, Miquel Raynal,
Thomas Petazzoni
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.
Signed-off-by: Herve Codina (Schneider Electric) <herve.codina@bootlin.com>
---
drivers/of/irq.c | 70 ++++++++++++++++++++++++++++++++++++++++++
include/linux/of_irq.h | 41 ++++++++++++++++++++++++-
2 files changed, 110 insertions(+), 1 deletion(-)
diff --git a/drivers/of/irq.c b/drivers/of/irq.c
index 74aaea61de13..0723ae4153a0 100644
--- a/drivers/of/irq.c
+++ b/drivers/of/irq.c
@@ -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
diff --git a/include/linux/of_irq.h b/include/linux/of_irq.h
index a480063c9cb1..f42757b245c4 100644
--- a/include/linux/of_irq.h
+++ b/include/linux/of_irq.h
@@ -11,6 +11,30 @@
typedef int (*of_irq_init_cb_t)(struct device_node *, struct device_node *);
+struct of_imap_parser {
+ struct device_node *node;
+ const __be32 *imap;
+ const __be32 *imap_end;
+ u32 parent_offset;
+};
+
+struct of_imap_item {
+ struct of_phandle_args parent_args;
+ u32 child_imap_count;
+ u32 child_imap[16]; /* Arbitrary size.
+ * Should be #address-cells + #interrupt-cells but
+ * avoid using allocation and so, expect that 16
+ * should be enough
+ */
+};
+
+/*
+ * If the iterator is exited prematurely (break, goto, return) of_node_put() has
+ * to be called on item.parent_args.np
+ */
+#define for_each_of_imap_item(parser, item) \
+ for (; of_imap_parser_one(parser, item);)
+
/*
* Workarounds only applied to 32bit powermac machines
*/
@@ -47,6 +71,11 @@ extern int of_irq_get_byname(struct device_node *dev, const char *name);
extern int of_irq_to_resource_table(struct device_node *dev,
struct resource *res, int nr_irqs);
extern struct device_node *of_irq_find_parent(struct device_node *child);
+extern int of_imap_parser_init(struct of_imap_parser *parser,
+ struct device_node *node,
+ struct of_imap_item *item);
+extern struct of_imap_item *of_imap_parser_one(struct of_imap_parser *parser,
+ struct of_imap_item *item);
extern struct irq_domain *of_msi_get_domain(struct device *dev,
const struct device_node *np,
enum irq_domain_bus_token token);
@@ -86,7 +115,17 @@ static inline void *of_irq_find_parent(struct device_node *child)
{
return NULL;
}
-
+static inline int of_imap_parser_init(struct of_imap_parser *parser,
+ struct device_node *node,
+ struct of_imap_item *item)
+{
+ return -ENOSYS;
+}
+extern struct of_imap_item *of_imap_parser_one(struct of_imap_parser *parser,
+ struct of_imap_item *item)
+{
+ return NULL;
+}
static inline struct irq_domain *of_msi_get_domain(struct device *dev,
struct device_node *np,
enum irq_domain_bus_token token)
--
2.51.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* Re: [PATCH v2 3/8] of/irq: Introduce for_each_of_imap_item
2025-09-09 12:00 ` [PATCH v2 3/8] of/irq: Introduce for_each_of_imap_item Herve Codina (Schneider Electric)
@ 2025-09-10 10:33 ` kernel test robot
2025-09-10 20:38 ` kernel test robot
1 sibling, 0 replies; 18+ messages in thread
From: kernel test robot @ 2025-09-10 10:33 UTC (permalink / raw)
To: Herve Codina (Schneider Electric), Wolfram Sang, Hoan Tran,
Linus Walleij, Bartosz Golaszewski, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Geert Uytterhoeven,
Magnus Damm, Saravana Kannan, Serge Semin
Cc: oe-kbuild-all, Phil Edworthy, linux-gpio, devicetree,
linux-kernel, linux-renesas-soc, Pascal Eberhard, Miquel Raynal,
Thomas Petazzoni
Hi Herve,
kernel test robot noticed the following build errors:
[auto build test ERROR on robh/for-next]
[also build test ERROR on tip/irq/core linus/master v6.17-rc5]
[cannot apply to geert-renesas-devel/next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Herve-Codina-Schneider-Electric/ARM-dts-r9a06g032-Add-GPIO-controllers/20250909-200642
base: https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
patch link: https://lore.kernel.org/r/20250909120041.154459-4-herve.codina%40bootlin.com
patch subject: [PATCH v2 3/8] of/irq: Introduce for_each_of_imap_item
config: x86_64-buildonly-randconfig-005-20250910 (https://download.01.org/0day-ci/archive/20250911/202509110852.9fhL9uHp-lkp@intel.com/config)
compiler: gcc-14 (Debian 14.2.0-19) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250911/202509110852.9fhL9uHp-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202509110852.9fhL9uHp-lkp@intel.com/
All error/warnings (new ones prefixed by >>):
In file included from drivers/bluetooth/hci_bcm.c:16:
>> include/linux/of_irq.h:123:29: warning: no previous prototype for 'of_imap_parser_one' [-Wmissing-prototypes]
123 | extern struct of_imap_item *of_imap_parser_one(struct of_imap_parser *parser,
| ^~~~~~~~~~~~~~~~~~
--
In file included from drivers/spi/spi-pic32.c:20:
>> include/linux/of_irq.h:123:29: warning: no previous prototype for 'of_imap_parser_one' [-Wmissing-prototypes]
123 | extern struct of_imap_item *of_imap_parser_one(struct of_imap_parser *parser,
| ^~~~~~~~~~~~~~~~~~
drivers/spi/spi-pic32.c:850:34: warning: 'pic32_spi_of_match' defined but not used [-Wunused-const-variable=]
850 | static const struct of_device_id pic32_spi_of_match[] = {
| ^~~~~~~~~~~~~~~~~~
--
ld: drivers/irqchip/irq-renesas-rzv2h.o: in function `of_imap_parser_one':
>> include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/irqchip/irq-ingenic-tcu.o: in function `of_imap_parser_one':
>> include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/irqchip/irq-stm32mp-exti.o: in function `of_imap_parser_one':
>> include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/irqchip/irq-meson-gpio.o: in function `of_imap_parser_one':
>> include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/irqchip/irq-starfive-jh8100-intc.o: in function `of_imap_parser_one':
>> include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/irqchip/irq-imx-irqsteer.o: in function `of_imap_parser_one':
>> include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/irqchip/irq-imx-intmux.o: in function `of_imap_parser_one':
>> include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/irqchip/irq-lan966x-oic.o: in function `of_imap_parser_one':
>> include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/irqchip/irq-ti-sci-intr.o: in function `of_imap_parser_one':
>> include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/irqchip/irq-mst-intc.o: in function `of_imap_parser_one':
>> include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/irqchip/irq-mchp-eic.o: in function `of_imap_parser_one':
>> include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/irqchip/irq-sp7021-intc.o: in function `of_imap_parser_one':
>> include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/gpio/gpio-msc313.o: in function `of_imap_parser_one':
>> include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/gpio/gpio-rockchip.o: in function `of_imap_parser_one':
>> include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/gpio/gpio-rtd.o: in function `of_imap_parser_one':
>> include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/soc/mediatek/mtk-devapc.o: in function `of_imap_parser_one':
>> include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/regulator/qcom-labibb-regulator.o: in function `of_imap_parser_one':
>> include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/tty/serial/8250/8250_mtk.o: in function `of_imap_parser_one':
>> include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/tty/serial/arc_uart.o: in function `of_imap_parser_one':
>> include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/tty/serial/omap-serial.o: in function `of_imap_parser_one':
>> include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/iommu/mtk_iommu.o: in function `of_imap_parser_one':
include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/iommu/mtk_iommu_v1.o: in function `of_imap_parser_one':
include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/gpu/drm/bridge/analogix/analogix-anx78xx.o: in function `of_imap_parser_one':
include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/base/platform.o: in function `of_imap_parser_one':
include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/mfd/wcd934x.o: in function `of_imap_parser_one':
include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/nfc/nfcmrvl/i2c.o: in function `of_imap_parser_one':
include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/nfc/nfcmrvl/spi.o: in function `of_imap_parser_one':
include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/nfc/s3fwrn5/i2c.o: in function `of_imap_parser_one':
include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/ata/sata_fsl.o: in function `of_imap_parser_one':
include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/mtd/nand/raw/atmel/nand-controller.o: in function `of_imap_parser_one':
include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/mtd/nand/raw/atmel/pmecc.o: in function `of_imap_parser_one':
include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/spi/spi.o: in function `of_imap_parser_one':
include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/spi/spi-bcm2835.o: in function `of_imap_parser_one':
include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/spi/spi-cadence.o: in function `of_imap_parser_one':
include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/spi/spi-microchip-core-qspi.o: in function `of_imap_parser_one':
include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/spi/spi-pic32.o: in function `of_imap_parser_one':
include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/usb/mtu3/mtu3_plat.o: in function `of_imap_parser_one':
include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/usb/mtu3/mtu3_core.o: in function `of_imap_parser_one':
include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/usb/gadget/udc/max3420_udc.o: in function `of_imap_parser_one':
include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/input/keyboard/gpio_keys.o: in function `of_imap_parser_one':
include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/i2c/busses/i2c-stm32f4.o: in function `of_imap_parser_one':
include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/i2c/busses/i2c-viai2c-wmt.o: in function `of_imap_parser_one':
include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/i2c/busses/i2c-viai2c-common.o: in function `of_imap_parser_one':
include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/power/reset/brcmstb-reboot.o: in function `of_imap_parser_one':
include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/hwmon/npcm750-pwm-fan.o: in function `of_imap_parser_one':
include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/thermal/rockchip_thermal.o: in function `of_imap_parser_one':
include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/thermal/ti-soc-thermal/ti-bandgap.o: in function `of_imap_parser_one':
include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/watchdog/at91sam9_wdt.o: in function `of_imap_parser_one':
include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/watchdog/rzn1_wdt.o: in function `of_imap_parser_one':
include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/bluetooth/hci_bcm.o: in function `of_imap_parser_one':
include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/bluetooth/btusb.o: in function `of_imap_parser_one':
include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/firmware/qcom/qcom_scm.o: in function `of_imap_parser_one':
include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/clocksource/timer-of.o: in function `of_imap_parser_one':
include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/clocksource/timer-atmel-st.o: in function `of_imap_parser_one':
include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/clocksource/timer-davinci.o: in function `of_imap_parser_one':
include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/clocksource/timer-digicolor.o: in function `of_imap_parser_one':
include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/clocksource/timer-econet-en751221.o: in function `of_imap_parser_one':
include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/clocksource/timer-fttmr010.o: in function `of_imap_parser_one':
include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/clocksource/timer-ixp4xx.o: in function `of_imap_parser_one':
include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/clocksource/bcm2835_timer.o: in function `of_imap_parser_one':
include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/clocksource/timer-meson6.o: in function `of_imap_parser_one':
include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/clocksource/timer-zevio.o: in function `of_imap_parser_one':
include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/clocksource/timer-stm32-lp.o: in function `of_imap_parser_one':
include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/clocksource/timer-fsl-ftm.o: in function `of_imap_parser_one':
include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/clocksource/timer-owl.o: in function `of_imap_parser_one':
include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/clocksource/timer-integrator-ap.o: in function `of_imap_parser_one':
include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/clocksource/timer-msc313e.o: in function `of_imap_parser_one':
include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/clocksource/timer-ralink.o: in function `of_imap_parser_one':
include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/clocksource/timer-nxp-stm.o: in function `of_imap_parser_one':
include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
ld: drivers/bcma/main.o: in function `of_imap_parser_one':
include/linux/of_irq.h:125: multiple definition of `of_imap_parser_one'; kernel/irq/irqdomain.o:include/linux/of_irq.h:125: first defined here
vim +125 include/linux/of_irq.h
58
59 extern int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq);
60 extern unsigned int irq_create_of_mapping(struct of_phandle_args *irq_data);
61 extern int of_irq_to_resource(struct device_node *dev, int index,
62 struct resource *r);
63
64 #ifdef CONFIG_OF_IRQ
65 extern void of_irq_init(const struct of_device_id *matches);
66 extern int of_irq_parse_one(struct device_node *device, int index,
67 struct of_phandle_args *out_irq);
68 extern int of_irq_count(struct device_node *dev);
69 extern int of_irq_get(struct device_node *dev, int index);
70 extern int of_irq_get_byname(struct device_node *dev, const char *name);
71 extern int of_irq_to_resource_table(struct device_node *dev,
72 struct resource *res, int nr_irqs);
73 extern struct device_node *of_irq_find_parent(struct device_node *child);
74 extern int of_imap_parser_init(struct of_imap_parser *parser,
75 struct device_node *node,
76 struct of_imap_item *item);
77 extern struct of_imap_item *of_imap_parser_one(struct of_imap_parser *parser,
78 struct of_imap_item *item);
79 extern struct irq_domain *of_msi_get_domain(struct device *dev,
80 const struct device_node *np,
81 enum irq_domain_bus_token token);
82 extern struct irq_domain *of_msi_map_get_device_domain(struct device *dev,
83 u32 id,
84 u32 bus_token);
85 extern void of_msi_configure(struct device *dev, const struct device_node *np);
86 extern u32 of_msi_xlate(struct device *dev, struct device_node **msi_np, u32 id_in);
87 #else
88 static inline void of_irq_init(const struct of_device_id *matches)
89 {
90 }
91 static inline int of_irq_parse_one(struct device_node *device, int index,
92 struct of_phandle_args *out_irq)
93 {
94 return -EINVAL;
95 }
96 static inline int of_irq_count(struct device_node *dev)
97 {
98 return 0;
99 }
100 static inline int of_irq_get(struct device_node *dev, int index)
101 {
102 return 0;
103 }
104 static inline int of_irq_get_byname(struct device_node *dev, const char *name)
105 {
106 return 0;
107 }
108 static inline int of_irq_to_resource_table(struct device_node *dev,
109 struct resource *res, int nr_irqs)
110 {
111 return 0;
112 }
113 static inline void *of_irq_find_parent(struct device_node *child)
114 {
115 return NULL;
116 }
117 static inline int of_imap_parser_init(struct of_imap_parser *parser,
118 struct device_node *node,
119 struct of_imap_item *item)
120 {
121 return -ENOSYS;
122 }
> 123 extern struct of_imap_item *of_imap_parser_one(struct of_imap_parser *parser,
124 struct of_imap_item *item)
> 125 {
126 return NULL;
127 }
128 static inline struct irq_domain *of_msi_get_domain(struct device *dev,
129 struct device_node *np,
130 enum irq_domain_bus_token token)
131 {
132 return NULL;
133 }
134 static inline struct irq_domain *of_msi_map_get_device_domain(struct device *dev,
135 u32 id, u32 bus_token)
136 {
137 return NULL;
138 }
139 static inline void of_msi_configure(struct device *dev, struct device_node *np)
140 {
141 }
142 static inline u32 of_msi_xlate(struct device *dev, struct device_node **msi_np, u32 id_in)
143 {
144 return id_in;
145 }
146 #endif
147
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [PATCH v2 3/8] of/irq: Introduce for_each_of_imap_item
2025-09-09 12:00 ` [PATCH v2 3/8] of/irq: Introduce for_each_of_imap_item Herve Codina (Schneider Electric)
2025-09-10 10:33 ` kernel test robot
@ 2025-09-10 20:38 ` kernel test robot
1 sibling, 0 replies; 18+ messages in thread
From: kernel test robot @ 2025-09-10 20:38 UTC (permalink / raw)
To: Herve Codina (Schneider Electric), Wolfram Sang, Hoan Tran,
Linus Walleij, Bartosz Golaszewski, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Geert Uytterhoeven,
Magnus Damm, Saravana Kannan, Serge Semin
Cc: llvm, oe-kbuild-all, Phil Edworthy, linux-gpio, devicetree,
linux-kernel, linux-renesas-soc, Pascal Eberhard, Miquel Raynal,
Thomas Petazzoni
Hi Herve,
kernel test robot noticed the following build warnings:
[auto build test WARNING on robh/for-next]
[also build test WARNING on tip/irq/core linus/master v6.17-rc5 next-20250910]
[cannot apply to geert-renesas-devel/next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Herve-Codina-Schneider-Electric/ARM-dts-r9a06g032-Add-GPIO-controllers/20250909-200642
base: https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
patch link: https://lore.kernel.org/r/20250909120041.154459-4-herve.codina%40bootlin.com
patch subject: [PATCH v2 3/8] of/irq: Introduce for_each_of_imap_item
config: x86_64-allnoconfig (https://download.01.org/0day-ci/archive/20250911/202509110402.OHHgtxRA-lkp@intel.com/config)
compiler: clang version 20.1.8 (https://github.com/llvm/llvm-project 87f0227cb60147a26a1eeb4fb06e3b505e9c7261)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250911/202509110402.OHHgtxRA-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202509110402.OHHgtxRA-lkp@intel.com/
All warnings (new ones prefixed by >>):
In file included from drivers/base/platform.c:15:
>> include/linux/of_irq.h:123:29: warning: no previous prototype for function 'of_imap_parser_one' [-Wmissing-prototypes]
123 | extern struct of_imap_item *of_imap_parser_one(struct of_imap_parser *parser,
| ^
include/linux/of_irq.h:123:8: note: declare 'static' if the function is not intended to be used outside of this translation unit
123 | extern struct of_imap_item *of_imap_parser_one(struct of_imap_parser *parser,
| ^
1 warning generated.
vim +/of_imap_parser_one +123 include/linux/of_irq.h
58
59 extern int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq);
60 extern unsigned int irq_create_of_mapping(struct of_phandle_args *irq_data);
61 extern int of_irq_to_resource(struct device_node *dev, int index,
62 struct resource *r);
63
64 #ifdef CONFIG_OF_IRQ
65 extern void of_irq_init(const struct of_device_id *matches);
66 extern int of_irq_parse_one(struct device_node *device, int index,
67 struct of_phandle_args *out_irq);
68 extern int of_irq_count(struct device_node *dev);
69 extern int of_irq_get(struct device_node *dev, int index);
70 extern int of_irq_get_byname(struct device_node *dev, const char *name);
71 extern int of_irq_to_resource_table(struct device_node *dev,
72 struct resource *res, int nr_irqs);
73 extern struct device_node *of_irq_find_parent(struct device_node *child);
74 extern int of_imap_parser_init(struct of_imap_parser *parser,
75 struct device_node *node,
76 struct of_imap_item *item);
77 extern struct of_imap_item *of_imap_parser_one(struct of_imap_parser *parser,
78 struct of_imap_item *item);
79 extern struct irq_domain *of_msi_get_domain(struct device *dev,
80 const struct device_node *np,
81 enum irq_domain_bus_token token);
82 extern struct irq_domain *of_msi_map_get_device_domain(struct device *dev,
83 u32 id,
84 u32 bus_token);
85 extern void of_msi_configure(struct device *dev, const struct device_node *np);
86 extern u32 of_msi_xlate(struct device *dev, struct device_node **msi_np, u32 id_in);
87 #else
88 static inline void of_irq_init(const struct of_device_id *matches)
89 {
90 }
91 static inline int of_irq_parse_one(struct device_node *device, int index,
92 struct of_phandle_args *out_irq)
93 {
94 return -EINVAL;
95 }
96 static inline int of_irq_count(struct device_node *dev)
97 {
98 return 0;
99 }
100 static inline int of_irq_get(struct device_node *dev, int index)
101 {
102 return 0;
103 }
104 static inline int of_irq_get_byname(struct device_node *dev, const char *name)
105 {
106 return 0;
107 }
108 static inline int of_irq_to_resource_table(struct device_node *dev,
109 struct resource *res, int nr_irqs)
110 {
111 return 0;
112 }
113 static inline void *of_irq_find_parent(struct device_node *child)
114 {
115 return NULL;
116 }
117 static inline int of_imap_parser_init(struct of_imap_parser *parser,
118 struct device_node *node,
119 struct of_imap_item *item)
120 {
121 return -ENOSYS;
122 }
> 123 extern struct of_imap_item *of_imap_parser_one(struct of_imap_parser *parser,
124 struct of_imap_item *item)
125 {
126 return NULL;
127 }
128 static inline struct irq_domain *of_msi_get_domain(struct device *dev,
129 struct device_node *np,
130 enum irq_domain_bus_token token)
131 {
132 return NULL;
133 }
134 static inline struct irq_domain *of_msi_map_get_device_domain(struct device *dev,
135 u32 id, u32 bus_token)
136 {
137 return NULL;
138 }
139 static inline void of_msi_configure(struct device *dev, struct device_node *np)
140 {
141 }
142 static inline u32 of_msi_xlate(struct device *dev, struct device_node **msi_np, u32 id_in)
143 {
144 return id_in;
145 }
146 #endif
147
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v2 4/8] of: unittest: Add a test case for for_each_of_imap_item iterator
2025-09-09 12:00 [PATCH v2 0/8] gpio: renesas: Add support for GPIO and related interrupts in RZ/N1 SoC Herve Codina (Schneider Electric)
` (2 preceding siblings ...)
2025-09-09 12:00 ` [PATCH v2 3/8] of/irq: Introduce for_each_of_imap_item Herve Codina (Schneider Electric)
@ 2025-09-09 12:00 ` Herve Codina (Schneider Electric)
2025-09-09 12:00 ` [PATCH v2 5/8] irqchip/ls-extirq: Use " Herve Codina (Schneider Electric)
` (4 subsequent siblings)
8 siblings, 0 replies; 18+ messages in thread
From: Herve Codina (Schneider Electric) @ 2025-09-09 12:00 UTC (permalink / raw)
To: Wolfram Sang, Hoan Tran, Linus Walleij, Bartosz Golaszewski,
Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Geert Uytterhoeven, Magnus Damm, Saravana Kannan, Serge Semin,
Herve Codina
Cc: Phil Edworthy, linux-gpio, devicetree, linux-kernel,
linux-renesas-soc, Pascal Eberhard, Miquel Raynal,
Thomas Petazzoni
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.
Signed-off-by: Herve Codina (Schneider Electric) <herve.codina@bootlin.com>
---
.../of/unittest-data/tests-interrupts.dtsi | 9 ++
drivers/of/unittest.c | 116 ++++++++++++++++++
2 files changed, 125 insertions(+)
diff --git a/drivers/of/unittest-data/tests-interrupts.dtsi b/drivers/of/unittest-data/tests-interrupts.dtsi
index 4ccb54f91c30..974f888c9b15 100644
--- a/drivers/of/unittest-data/tests-interrupts.dtsi
+++ b/drivers/of/unittest-data/tests-interrupts.dtsi
@@ -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>;
diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c
index e3503ec20f6c..be4d9571f16e 100644
--- a/drivers/of/unittest.c
+++ b/drivers/of/unittest.c
@@ -1654,6 +1654,121 @@ static void __init of_unittest_parse_interrupts_extended(void)
of_node_put(np);
}
+struct of_unittest_expected_imap_item {
+ u32 child_imap_count;
+ u32 child_imap[2];
+ const char *parent_path;
+ int parent_args_count;
+ u32 parent_args[3];
+};
+
+static const struct of_unittest_expected_imap_item of_unittest_expected_imap_items[] = {
+ {
+ .child_imap_count = 2,
+ .child_imap = {1, 11},
+ .parent_path = "/testcase-data/interrupts/intc0",
+ .parent_args_count = 1,
+ .parent_args = {100},
+ }, {
+ .child_imap_count = 2,
+ .child_imap = {2, 22},
+ .parent_path = "/testcase-data/interrupts/intc1",
+ .parent_args_count = 3,
+ .parent_args = {200, 201, 202},
+ }, {
+ .child_imap_count = 2,
+ .child_imap = {3, 33},
+ .parent_path = "/testcase-data/interrupts/intc2",
+ .parent_args_count = 2,
+ .parent_args = {300, 301},
+ }, {
+ .child_imap_count = 2,
+ .child_imap = {4, 44},
+ .parent_path = "/testcase-data/interrupts/intc2",
+ .parent_args_count = 2,
+ .parent_args = {400, 401},
+ }
+};
+
+static void __init of_unittest_parse_interrupt_map(void)
+{
+ const struct of_unittest_expected_imap_item *expected_item;
+ struct device_node *imap_np, *expected_parent_np;
+ struct of_imap_parser imap_parser;
+ struct of_imap_item imap_item;
+ int count, ret, i;
+
+ if (of_irq_workarounds & (OF_IMAP_NO_PHANDLE | OF_IMAP_OLDWORLD_MAC))
+ return;
+
+ imap_np = of_find_node_by_path("/testcase-data/interrupts/intmap2");
+ if (!imap_np) {
+ pr_err("missing testcase data\n");
+ return;
+ }
+
+ ret = of_imap_parser_init(&imap_parser, imap_np, &imap_item);
+ if (unittest(!ret, "of_imap_parser_init(%pOF) returned error %d\n",
+ imap_np, ret))
+ goto end;
+
+ expected_item = of_unittest_expected_imap_items;
+ count = 0;
+
+ for_each_of_imap_item(&imap_parser, &imap_item) {
+ if (unittest(count < ARRAY_SIZE(of_unittest_expected_imap_items),
+ "imap item number %d not expected. Max number %zu\n",
+ count, ARRAY_SIZE(of_unittest_expected_imap_items) - 1)) {
+ of_node_put(imap_item.parent_args.np);
+ goto end;
+ }
+
+ expected_parent_np = of_find_node_by_path(expected_item->parent_path);
+ if (unittest(expected_parent_np,
+ "missing dependent testcase data (%s)\n",
+ expected_item->parent_path)) {
+ of_node_put(imap_item.parent_args.np);
+ goto end;
+ }
+
+ unittest(imap_item.child_imap_count == expected_item->child_imap_count,
+ "imap[%d] child_imap_count = %u, expected %u\n",
+ count, imap_item.child_imap_count,
+ expected_item->child_imap_count);
+
+ for (i = 0; i < expected_item->child_imap_count; i++)
+ unittest(imap_item.child_imap[i] == expected_item->child_imap[i],
+ "imap[%d] child_imap[%d] = %u, expected %u\n",
+ count, i, imap_item.child_imap[i],
+ expected_item->child_imap[i]);
+
+ unittest(imap_item.parent_args.np == expected_parent_np,
+ "imap[%d] parent np = %pOF, expected %pOF\n",
+ count, imap_item.parent_args.np, expected_parent_np);
+
+ unittest(imap_item.parent_args.args_count == expected_item->parent_args_count,
+ "imap[%d] parent param_count = %d, expected %d\n",
+ count, imap_item.parent_args.args_count,
+ expected_item->parent_args_count);
+
+ for (i = 0; i < expected_item->parent_args_count; i++)
+ unittest(imap_item.parent_args.args[i] == expected_item->parent_args[i],
+ "imap[%d] parent param[%d] = %u, expected %u\n",
+ count, i, imap_item.parent_args.args[i],
+ expected_item->parent_args[i]);
+
+ of_node_put(expected_parent_np);
+ count++;
+ expected_item++;
+ }
+
+ unittest(count == ARRAY_SIZE(of_unittest_expected_imap_items),
+ "Missing items. %d parsed, expected %zu\n",
+ count, ARRAY_SIZE(of_unittest_expected_imap_items));
+end:
+ of_node_put(imap_np);
+}
+
#if IS_ENABLED(CONFIG_OF_DYNAMIC)
static void __init of_unittest_irq_refcount(void)
{
@@ -4394,6 +4509,7 @@ static int __init of_unittest(void)
of_unittest_changeset_prop();
of_unittest_parse_interrupts();
of_unittest_parse_interrupts_extended();
+ of_unittest_parse_interrupt_map();
of_unittest_irq_refcount();
of_unittest_dma_get_max_cpu_address();
of_unittest_parse_dma_ranges();
--
2.51.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH v2 5/8] irqchip/ls-extirq: Use for_each_of_imap_item iterator
2025-09-09 12:00 [PATCH v2 0/8] gpio: renesas: Add support for GPIO and related interrupts in RZ/N1 SoC Herve Codina (Schneider Electric)
` (3 preceding siblings ...)
2025-09-09 12:00 ` [PATCH v2 4/8] of: unittest: Add a test case for for_each_of_imap_item iterator Herve Codina (Schneider Electric)
@ 2025-09-09 12:00 ` Herve Codina (Schneider Electric)
2025-09-09 12:00 ` [PATCH v2 6/8] irqchip/renesas-rza1: " Herve Codina (Schneider Electric)
` (3 subsequent siblings)
8 siblings, 0 replies; 18+ messages in thread
From: Herve Codina (Schneider Electric) @ 2025-09-09 12:00 UTC (permalink / raw)
To: Wolfram Sang, Hoan Tran, Linus Walleij, Bartosz Golaszewski,
Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Geert Uytterhoeven, Magnus Damm, Saravana Kannan, Serge Semin,
Herve Codina
Cc: Phil Edworthy, linux-gpio, devicetree, linux-kernel,
linux-renesas-soc, Pascal Eberhard, Miquel Raynal,
Thomas Petazzoni
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.
Signed-off-by: Herve Codina (Schneider Electric) <herve.codina@bootlin.com>
---
drivers/irqchip/irq-ls-extirq.c | 47 ++++++++++++---------------------
1 file changed, 17 insertions(+), 30 deletions(-)
diff --git a/drivers/irqchip/irq-ls-extirq.c b/drivers/irqchip/irq-ls-extirq.c
index 50a7b38381b9..ed8755777349 100644
--- a/drivers/irqchip/irq-ls-extirq.c
+++ b/drivers/irqchip/irq-ls-extirq.c
@@ -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;
}
--
2.51.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH v2 6/8] irqchip/renesas-rza1: Use for_each_of_imap_item iterator
2025-09-09 12:00 [PATCH v2 0/8] gpio: renesas: Add support for GPIO and related interrupts in RZ/N1 SoC Herve Codina (Schneider Electric)
` (4 preceding siblings ...)
2025-09-09 12:00 ` [PATCH v2 5/8] irqchip/ls-extirq: Use " Herve Codina (Schneider Electric)
@ 2025-09-09 12:00 ` Herve Codina (Schneider Electric)
2025-09-09 12:00 ` [PATCH v2 7/8] soc: renesas: Add support for Renesas RZ/N1 GPIO Interrupt Multiplexer Herve Codina (Schneider Electric)
` (2 subsequent siblings)
8 siblings, 0 replies; 18+ messages in thread
From: Herve Codina (Schneider Electric) @ 2025-09-09 12:00 UTC (permalink / raw)
To: Wolfram Sang, Hoan Tran, Linus Walleij, Bartosz Golaszewski,
Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Geert Uytterhoeven, Magnus Damm, Saravana Kannan, Serge Semin,
Herve Codina
Cc: Phil Edworthy, linux-gpio, devicetree, linux-kernel,
linux-renesas-soc, Pascal Eberhard, Miquel Raynal,
Thomas Petazzoni
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.
Signed-off-by: Herve Codina (Schneider Electric) <herve.codina@bootlin.com>
---
drivers/irqchip/irq-renesas-rza1.c | 43 +++++++++++-------------------
1 file changed, 16 insertions(+), 27 deletions(-)
diff --git a/drivers/irqchip/irq-renesas-rza1.c b/drivers/irqchip/irq-renesas-rza1.c
index a697eb55ac90..789196b71656 100644
--- a/drivers/irqchip/irq-renesas-rza1.c
+++ b/drivers/irqchip/irq-renesas-rza1.c
@@ -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;
--
2.51.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH v2 7/8] soc: renesas: Add support for Renesas RZ/N1 GPIO Interrupt Multiplexer
2025-09-09 12:00 [PATCH v2 0/8] gpio: renesas: Add support for GPIO and related interrupts in RZ/N1 SoC Herve Codina (Schneider Electric)
` (5 preceding siblings ...)
2025-09-09 12:00 ` [PATCH v2 6/8] irqchip/renesas-rza1: " Herve Codina (Schneider Electric)
@ 2025-09-09 12:00 ` Herve Codina (Schneider Electric)
2025-09-09 12:00 ` [PATCH v2 8/8] ARM: dts: r9a06g032: Add support for GPIO interrupts Herve Codina (Schneider Electric)
2025-09-09 20:51 ` [PATCH v2 0/8] gpio: renesas: Add support for GPIO and related interrupts in RZ/N1 SoC Thomas Gleixner
8 siblings, 0 replies; 18+ messages in thread
From: Herve Codina (Schneider Electric) @ 2025-09-09 12:00 UTC (permalink / raw)
To: Wolfram Sang, Hoan Tran, Linus Walleij, Bartosz Golaszewski,
Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Geert Uytterhoeven, Magnus Damm, Saravana Kannan, Serge Semin,
Herve Codina
Cc: Phil Edworthy, linux-gpio, devicetree, linux-kernel,
linux-renesas-soc, Pascal Eberhard, Miquel Raynal,
Thomas Petazzoni
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) <herve.codina@bootlin.com>
---
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
diff --git a/drivers/soc/renesas/Kconfig b/drivers/soc/renesas/Kconfig
index 719b7f4f376f..0878b6884515 100644
--- a/drivers/soc/renesas/Kconfig
+++ b/drivers/soc/renesas/Kconfig
@@ -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
diff --git a/drivers/soc/renesas/Makefile b/drivers/soc/renesas/Makefile
index 3bdcc6a395d5..daa932c7698d 100644
--- a/drivers/soc/renesas/Makefile
+++ b/drivers/soc/renesas/Makefile
@@ -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
diff --git a/drivers/soc/renesas/rzn1_irqmux.c b/drivers/soc/renesas/rzn1_irqmux.c
new file mode 100644
index 000000000000..3855e132c15f
--- /dev/null
+++ b/drivers/soc/renesas/rzn1_irqmux.c
@@ -0,0 +1,110 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * RZ/N1 GPIO Interrupt Multiplexer
+ *
+ * Copyright 2025 Schneider Electric
+ * Author: Herve Codina <herve.codina@bootlin.com>
+ */
+
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+
+#define IRQMUX_MAX_IRQS 8
+
+static int irqmux_setup(struct device *dev, struct device_node *np, u32 __iomem *regs)
+{
+ struct of_imap_parser imap_parser;
+ struct of_imap_item imap_item;
+ unsigned int index = 0;
+ u32 tmp;
+ int ret;
+
+ /* We support only #interrupt-cells = <1> and #address-cells = <0> */
+ ret = of_property_read_u32(np, "#interrupt-cells", &tmp);
+ if (ret)
+ return ret;
+ if (tmp != 1)
+ return -EINVAL;
+
+ ret = of_property_read_u32(np, "#address-cells", &tmp);
+ if (ret)
+ return ret;
+ if (tmp != 0)
+ return -EINVAL;
+
+ ret = of_imap_parser_init(&imap_parser, np, &imap_item);
+ if (ret)
+ return ret;
+
+ 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.
+ */
+ 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;
+ }
+
+ 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);
+ if (nr_irqs < 0)
+ return nr_irqs;
+
+ if (nr_irqs > IRQMUX_MAX_IRQS) {
+ dev_err(dev, "too many output interrupts\n");
+ return -ENOENT;
+ }
+
+ ret = irqmux_setup(dev, np, regs);
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to setup mux\n");
+
+ return 0;
+}
+
+static const struct of_device_id irqmux_of_match[] = {
+ { .compatible = "renesas,rzn1-gpioirqmux", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, irq_mux_of_match);
+
+static struct platform_driver irqmux_driver = {
+ .probe = irqmux_probe,
+ .driver = {
+ .name = "rzn1_irqmux",
+ .of_match_table = irqmux_of_match,
+ },
+};
+module_platform_driver(irqmux_driver);
+
+MODULE_AUTHOR("Herve Codina <herve.codina@bootlin.com>");
+MODULE_DESCRIPTION("Renesas RZ/N1 GPIO IRQ Multiplexer Driver");
+MODULE_LICENSE("GPL");
--
2.51.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH v2 8/8] ARM: dts: r9a06g032: Add support for GPIO interrupts
2025-09-09 12:00 [PATCH v2 0/8] gpio: renesas: Add support for GPIO and related interrupts in RZ/N1 SoC Herve Codina (Schneider Electric)
` (6 preceding siblings ...)
2025-09-09 12:00 ` [PATCH v2 7/8] soc: renesas: Add support for Renesas RZ/N1 GPIO Interrupt Multiplexer Herve Codina (Schneider Electric)
@ 2025-09-09 12:00 ` Herve Codina (Schneider Electric)
2025-09-09 20:51 ` [PATCH v2 0/8] gpio: renesas: Add support for GPIO and related interrupts in RZ/N1 SoC Thomas Gleixner
8 siblings, 0 replies; 18+ messages in thread
From: Herve Codina (Schneider Electric) @ 2025-09-09 12:00 UTC (permalink / raw)
To: Wolfram Sang, Hoan Tran, Linus Walleij, Bartosz Golaszewski,
Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Geert Uytterhoeven, Magnus Damm, Saravana Kannan, Serge Semin,
Herve Codina
Cc: Phil Edworthy, linux-gpio, devicetree, linux-kernel,
linux-renesas-soc, Pascal Eberhard, Miquel Raynal,
Thomas Petazzoni
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).
Signed-off-by: Herve Codina (Schneider Electric) <herve.codina@bootlin.com>
---
arch/arm/boot/dts/renesas/r9a06g032.dtsi | 49 ++++++++++++++++++++++++
1 file changed, 49 insertions(+)
diff --git a/arch/arm/boot/dts/renesas/r9a06g032.dtsi b/arch/arm/boot/dts/renesas/r9a06g032.dtsi
index da977cdd8487..3cd7ac38eb7a 100644
--- a/arch/arm/boot/dts/renesas/r9a06g032.dtsi
+++ b/arch/arm/boot/dts/renesas/r9a06g032.dtsi
@@ -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>;
--
2.51.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* Re: [PATCH v2 0/8] gpio: renesas: Add support for GPIO and related interrupts in RZ/N1 SoC
2025-09-09 12:00 [PATCH v2 0/8] gpio: renesas: Add support for GPIO and related interrupts in RZ/N1 SoC Herve Codina (Schneider Electric)
` (7 preceding siblings ...)
2025-09-09 12:00 ` [PATCH v2 8/8] ARM: dts: r9a06g032: Add support for GPIO interrupts Herve Codina (Schneider Electric)
@ 2025-09-09 20:51 ` Thomas Gleixner
2025-09-09 20:54 ` Thomas Gleixner
8 siblings, 1 reply; 18+ messages in thread
From: Thomas Gleixner @ 2025-09-09 20:51 UTC (permalink / raw)
To: Herve Codina (Schneider Electric), Wolfram Sang, Hoan Tran,
Linus Walleij, Bartosz Golaszewski, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Geert Uytterhoeven,
Magnus Damm, Saravana Kannan, Serge Semin, Herve Codina
Cc: Phil Edworthy, linux-gpio, devicetree, linux-kernel,
linux-renesas-soc, Pascal Eberhard, Miquel Raynal,
Thomas Petazzoni
On Tue, Sep 09 2025 at 14:00, Herve Codina wrote:
> 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
How are those two patches related to adding GPIO support?
AFAICT, they are completely unrelated and just randomly sprinkled into
this series, but I might be missing something.
Thanks,
tglx
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [PATCH v2 0/8] gpio: renesas: Add support for GPIO and related interrupts in RZ/N1 SoC
2025-09-09 20:51 ` [PATCH v2 0/8] gpio: renesas: Add support for GPIO and related interrupts in RZ/N1 SoC Thomas Gleixner
@ 2025-09-09 20:54 ` Thomas Gleixner
2025-09-11 7:04 ` Herve Codina
0 siblings, 1 reply; 18+ messages in thread
From: Thomas Gleixner @ 2025-09-09 20:54 UTC (permalink / raw)
To: Herve Codina (Schneider Electric), Wolfram Sang, Hoan Tran,
Linus Walleij, Bartosz Golaszewski, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Geert Uytterhoeven,
Magnus Damm, Saravana Kannan, Serge Semin, Herve Codina
Cc: Phil Edworthy, linux-gpio, devicetree, linux-kernel,
linux-renesas-soc, Pascal Eberhard, Miquel Raynal,
Thomas Petazzoni
On Tue, Sep 09 2025 at 22:51, Thomas Gleixner wrote:
> On Tue, Sep 09 2025 at 14:00, Herve Codina wrote:
>> 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
>
> How are those two patches related to adding GPIO support?
>
> AFAICT, they are completely unrelated and just randomly sprinkled into
> this series, but I might be missing something.
Ah. I missed that this iterator got introduced in this series. Did you
check whether that creates any conflicts against pending irqchip
patches?
Thanks,
tglx
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [PATCH v2 0/8] gpio: renesas: Add support for GPIO and related interrupts in RZ/N1 SoC
2025-09-09 20:54 ` Thomas Gleixner
@ 2025-09-11 7:04 ` Herve Codina
2025-09-11 13:52 ` Thomas Gleixner
0 siblings, 1 reply; 18+ messages in thread
From: Herve Codina @ 2025-09-11 7:04 UTC (permalink / raw)
To: Thomas Gleixner
Cc: Wolfram Sang, Hoan Tran, Linus Walleij, Bartosz Golaszewski,
Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Geert Uytterhoeven, Magnus Damm, Saravana Kannan, Serge Semin,
Phil Edworthy, linux-gpio, devicetree, linux-kernel,
linux-renesas-soc, Pascal Eberhard, Miquel Raynal,
Thomas Petazzoni
Hi Thomas,
On Tue, 09 Sep 2025 22:54:41 +0200
Thomas Gleixner <tglx@linutronix.de> wrote:
> On Tue, Sep 09 2025 at 22:51, Thomas Gleixner wrote:
> > On Tue, Sep 09 2025 at 14:00, Herve Codina wrote:
> >> 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
> >
> > How are those two patches related to adding GPIO support?
> >
> > AFAICT, they are completely unrelated and just randomly sprinkled into
> > this series, but I might be missing something.
>
> Ah. I missed that this iterator got introduced in this series. Did you
> check whether that creates any conflicts against pending irqchip
> patches?
>
Indeed, I have a conflict in my patch 6 with 40c26230a1bf ("irqchip: Use int
type to store negative error codes").
I can rebase my next iteration on top of 40c26230a1bf and mention this commit
in my next iteration cover letter but an immutable tag and referencing this
tag in the cover letter should be better.
What is the best approach?
Best regards,
Hervé
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [PATCH v2 0/8] gpio: renesas: Add support for GPIO and related interrupts in RZ/N1 SoC
2025-09-11 7:04 ` Herve Codina
@ 2025-09-11 13:52 ` Thomas Gleixner
0 siblings, 0 replies; 18+ messages in thread
From: Thomas Gleixner @ 2025-09-11 13:52 UTC (permalink / raw)
To: Herve Codina
Cc: Wolfram Sang, Hoan Tran, Linus Walleij, Bartosz Golaszewski,
Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Geert Uytterhoeven, Magnus Damm, Saravana Kannan, Serge Semin,
Phil Edworthy, linux-gpio, devicetree, linux-kernel,
linux-renesas-soc, Pascal Eberhard, Miquel Raynal,
Thomas Petazzoni
On Thu, Sep 11 2025 at 09:04, Herve Codina wrote:
> On Tue, 09 Sep 2025 22:54:41 +0200
> Thomas Gleixner <tglx@linutronix.de> wrote:
>
>> On Tue, Sep 09 2025 at 22:51, Thomas Gleixner wrote:
>> > On Tue, Sep 09 2025 at 14:00, Herve Codina wrote:
>> >> 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
>> >
>> > How are those two patches related to adding GPIO support?
>> >
>> > AFAICT, they are completely unrelated and just randomly sprinkled into
>> > this series, but I might be missing something.
>>
>> Ah. I missed that this iterator got introduced in this series. Did you
>> check whether that creates any conflicts against pending irqchip
>> patches?
>>
>
> Indeed, I have a conflict in my patch 6 with 40c26230a1bf ("irqchip: Use int
> type to store negative error codes").
>
> I can rebase my next iteration on top of 40c26230a1bf and mention this commit
> in my next iteration cover letter but an immutable tag and referencing this
> tag in the cover letter should be better.
No. Don't do that.
> What is the best approach?
Just base it on upstream and mentioning the conflict in the cover
letter. For actual merging, if it's ready before the merge window, we
can sort it out by:
1) You putting patch (3-6) in front of the queue
2) Me picking up these 4 patches into a separate branch based on rc1
or later, which gets tagged and is consumable by the GPIO
maintainers.
Then I can merge that branch into irq/drivers and resolve the
conflict, which is trivial enough
Alternatively GPIO folks pick up the whole lot and sort the conflict out
with -next and Linus themself. No real preference from my side.
Thanks,
tglx
^ permalink raw reply [flat|nested] 18+ messages in thread