gpio: renesas: Add support for GPIO and related interrupts in RZ/N1 SoC
Subsystems (5)
v7 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 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 v6 -> v7
v6: https://lore.kernel.org/all/[email protected]/
Rebase on top of v6.19-rc1.
Patches 1 to 4 :
- Add 'Reviewed-by: Linus Walleij'.
Patch 5:
- Fix a typo (Synopsys) in commit log.
- GPIO controllers enabled by default.
- Move "reg" just below "compatible".
- Add 'Reviewed-by: Linus Walleij'.
- Add 'Reviewed-by: Geert Uytterhoeven'.
Patch 6:
- Add 'Reviewed-by: Linus Walleij'.
- Add 'Reviewed-by: Geert Uytterhoeven'.
Patch 7:
- Enable RZN1_IRQMUX only if GPIO_DWAPB is enabled.
- Move a 'if' condition to a single line.
- Print the output line index in the 'already defined' error message.
- Move rzn1_irqmux_setup() code directly into rzn1_irqmux_probe().
- Add 'Reviewed-by: Linus Walleij'.
- Add 'Tested-by: Wolfram Sang'.
- Add 'Reviewed-by: Wolfram Sang'.
- Add 'Reviewed-by: Geert Uytterhoeven'.
Patch 8:
- Remove unneeded spaces.
- Add 'Reviewed-by: Linus Walleij'
- Add 'Reviewed-by: Wolfram Sang'
- Add 'Reviewed-by: Geert Uytterhoeven'
Changes v5 -> v6
v5: https://lore.kernel.org/lkml/[email protected]/
Patches 1 and 2:
Add 'Reviewed-by: Rob Herring'
Patches 3, and 5:
No changes
Patch 6:
Add 'Reviewed-by: Rob Herring'
Patch 7:
Remove an unneeded TAB in Makefile.
Use RZN1_IRQMUX_GIC_SPI_BASE and RZN1_IRQMUX_NUM_OUTPUTS to replace the irq/output mapping table.
Use DECLARE_BITMAP().
Patch 8:
No changes
Changes v4 -> v5
v4: https://lore.kernel.org/lkml/[email protected]/
Rebase on top of v6.18-rc1
Patches 1 to 3:
No changes
Patch 4:
Fix conflict.
Add 'Tested-by: Wolfram Sang'.
Patch 5:
Add 'Reviewed-by: Bartosz Golaszewski'.
Patch 6:
Add 'Reviewed-by: Wolfram Sang'.
Patch 7:
Add a missing 'const' qualifier.
Remove an unneeded dev_err_probe() call.
Add a check to avoid setting the same output line multiple times.
Patch 8:
Update comment
Add 'Reviewed-by: Bartosz Golaszewski'
Changes v3 -> v4
v3: https://lore.kernel.org/lkml/[email protected]/
Patch 1:
- Add 'Tested-by: Wolfram Sang'
Patch 2..5:
- No changes
Patch 6:
- Add minItems and maxItems
- Update the 'interrup-map' description
Patch 7:
- Use rzn1_irqmux prefix instead of irqmux.
- Introduce rzn1_irqmux_output_lines[] to give the mapping between the interrupt output line index and the GIC controller interrupt number.
- Remove of_irq_count() call and related checks
Patch 8:
- Describe the irq mux node using a reduced (one item) interrupt-map property.
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 | 159 ++++++++++++++++++ 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 | 127 ++++++++++++++ include/linux/of_irq.h | 41 ++++- 11 files changed, 646 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.52.0
PATCH v7 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.52.0
PATCH v7 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.52.0
PATCH v7 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.52.0
PATCH v7 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,47 +142,36 @@ 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) { +struct of_imap_parser imap_parser;struct device *dev = priv->dev; -unsigned int imaplen, i, j; +struct of_imap_item imap_item;struct device_node *ipar; -const __be32 *imap; -u32 intsize; +unsigned int j; +u32 i =0 ;int ret; - 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.52.0
PATCH v7 5/8 ARM: dts: r9a06g032: Add GPIO controllers
In reply to Herve Codina (Schneider Electric)Add GPIO controllers (Synopsys DesignWare IPs) available in the r9a06g032 (RZ/N1D) SoC.
--- arch/arm/boot/dts/renesas/r9a06g032.dtsi | 118 +++++++++++++++++++++++ 1 file changed, 118 insertions(+)
arch/arm/boot/dts/renesas/r9a06g032.dtsi +118 -0
@@ -509,6 +509,124 @@ 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"; + + /* 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"; + reg = <0>; + gpio-controller; + #gpio-cells = <2>; + snps,nr-gpios = <32>; + }; + + /* 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"; + reg = <1>; + gpio-controller; + #gpio-cells = <2>; + snps,nr-gpios = <32>; + }; + }; + + 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"; + + /* 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"; + reg = <0>; + gpio-controller; + #gpio-cells = <2>; + snps,nr-gpios = <32>; + }; + + /* 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"; + reg = <1>; + gpio-controller; + #gpio-cells = <2>; + snps,nr-gpios = <32>; + }; + }; + + 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"; + + /* 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"; + reg = <0>; + gpio-controller; + #gpio-cells = <2>; + snps,nr-gpios = <32>; + }; + + /* GPIO2b[0..9] connected to pins GPIO160..169 */ + gpio2b: gpio-port@1 { + compatible = "snps,dw-apb-gpio-port"; + reg = <1>; + gpio-controller; + #gpio-cells = <2>; + snps,nr-gpios = <10>; + }; + }; + can0: can@52104000 { compatible = "renesas,r9a06g032-sja1000", "renesas,rzn1-sja1000"; reg = <0x52104000 0x800>;
Signature · 1 line
2.52.0
PATCH v7 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 has up to 8 items defining the mapping related to + the output line 0 (GIC 103) up to the output line 7 (GIC 110). + + The child interrupt number set in arrays items 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) + minItems: 1 + maxItems: 8 + +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>; + interrupt-map = + <32 &gic GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>, /* line 0, GPIO1A.0 */ + <89 &gic GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>, /* line 1, GPIO2A.25 */ + <9 &gic GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>; /* line 3, GPIO0A.9 */ + };
Signature · 1 line
2.52.0
PATCH v7 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 | 127 ++++++++++++++++++++++++++++++ 3 files changed, 132 insertions(+) create mode 100644 drivers/soc/renesas/rzn1_irqmux.c
drivers/soc/renesas/Kconfig +4 -0
@@ -62,6 +62,7 @@ config ARCH_RZN1 select PM select PM_GENERIC_DOMAINS select ARM_AMBA + select RZN1_IRQMUX if GPIO_DWAPB if ARM && ARCH_RENESAS
@@ -459,6 +460,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 select MFD_SYSCON
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 +127 -0
127 lines not on this page · raw message
Signature · 1 line
2.52.0
PATCH v7 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 | 41 ++++++++++++++++++++++++ 1 file changed, 41 insertions(+)
arch/arm/boot/dts/renesas/r9a06g032.dtsi +41 -0
@@ -543,6 +543,14 @@ gpio0a: gpio-port@0 { gpio-controller; #gpio-cells = <2>; snps,nr-gpios = <32>; + + 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 */
@@ -584,6 +592,14 @@ gpio1a: gpio-port@0 { gpio-controller; #gpio-cells = <2>; snps,nr-gpios = <32>; + + 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 */
@@ -615,6 +631,14 @@ gpio2a: gpio-port@0 { gpio-controller; #gpio-cells = <2>; snps,nr-gpios = <32>; + + 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 */
@@ -627,6 +651,23 @@ 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>; + + /* + * Example mapping entry. Board DTs need to overwrite + * 'interrupt-map' with their specific mapping. Check + * the irqmux binding documentation for details. + */ + interrupt-map = <0 &gic GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>; + + status = "disabled"; + }; + can0: can@52104000 { compatible = "renesas,r9a06g032-sja1000", "renesas,rzn1-sja1000"; reg = <0x52104000 0x800>;
Signature · 1 line
2.52.0
Re: [PATCH v7 8/8] ARM: dts: r9a06g032: Add support for GPIO interrupts
Quoted 10 lines · 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.
Quoted 7 lines
Up to 8 GPIOs can be used as an interrupt line (one per multiplexer output interrupt).
Signed-off-by Herve Codina (Schneider Electric) <[email protected]>Reviewed-by Bartosz Golaszewski <[email protected]>Reviewed-by Linus Walleij <[email protected]>Reviewed-by Wolfram Sang <[email protected]>
I used this patch successfully with my N1D demo board. I will upstream the board changes once this series hits mainline.
Hi everyone,
Quoted 9 lines
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
Quoted 4 lines
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.
I think this series is ready and I would really like to see it upstream soon. I wonder, however, if the path to upstream has already been discussed? It touches various subsystems, so I don't see immediately who should pick the whole series? Or if parts should go to different subsystems offering immutable branches? I bring this up because I want to avoid losing a cycle just because this is unclear...
Happy hacking,
Wolfram
Hi Wolfram, Rob, Thomas,
Quoted 14 lines · Wolfram Sang
Quoted 9 lines
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 helperQuoted 4 lines
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.
Quoted 6 lines
I think this series is ready and I would really like to see it upstream soon. I wonder, however, if the path to upstream has already been discussed? It touches various subsystems, so I don't see immediately who should pick the whole series? Or if parts should go to different subsystems offering immutable branches? I bring this up because I want to avoid losing a cycle just because this is unclear...
We actually did[1]. Unfortunately that plan was never executed. The DTS patches I can easily take through renesas-devel, as they have no hard dependencies.
For the remaining patches, I see two options:
A. Rob takes the first two patches, and provides an immutable branch.
Then Thomas takes the irqchip patches, and I take the rest.
B. Rob and Thomas provide acks, and I take the whole series.
Thanks!
[1] https://lore.kernel.org/[email protected]
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
Quoted 8 lines
Quoted 7 lines
I think this series is ready and I would really like to see it upstream soon. I wonder, however, if the path to upstream has already been discussed? It touches various subsystems, so I don't see immediately who should pick the whole series? Or if parts should go to different subsystems offering immutable branches? I bring this up because I want to avoid losing a cycle just because this is unclear...
Quoted 7 lines
We actually did[1]. Unfortunately that plan was never executed. The DTS patches I can easily take through renesas-devel, as they have no hard dependencies.
For the remaining patches, I see two options:
A. Rob takes the first two patches, and provides an immutable branch.
Then Thomas takes the irqchip patches, and I take the rest.
B. Rob and Thomas provide acks, and I take the whole series.
B) should be the easiest for everyone. Rob, Thomas, are you okay to ack these patches? If no reply here, maybe a resend is in place with proper description of the suggested path upstream in the cover letter?