* [PATCH v2 0/8] Add support for GPIO IRQs for RZ/T2H and RZ/N2H
@ 2025-12-05 15:02 Cosmin Tanislav
2025-12-05 15:02 ` [PATCH v2 1/8] pinctrl: renesas: rzt2h: move GPIO enable/disable into separate function Cosmin Tanislav
` (7 more replies)
0 siblings, 8 replies; 12+ messages in thread
From: Cosmin Tanislav @ 2025-12-05 15:02 UTC (permalink / raw)
To: Geert Uytterhoeven, Linus Walleij, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Magnus Damm, Lad Prabhakar
Cc: linux-renesas-soc, linux-gpio, devicetree, linux-kernel,
Cosmin Tanislav
The Renesas RZ/T2H and RZ/N2H SoCs have IRQ-capable pins handled by the
ICU, which forwards them to the GIC.
The ICU supports 16 IRQ lines, the pins map to these lines arbitrarily,
and the mapping is not configurable.
Add a GPIO IRQ chip that can be used to configure these pins as IRQ
lines, and add the user switches present on the board.
The ICU driver has been submitted as part of a separate series [1].
[1]: https://lore.kernel.org/lkml/20251201112933.488801-1-cosmin-gabriel.tanislav.xa@renesas.com/
V2:
* drop interrupt-controller and #interrupt-cells from required to keep
compatibility
* select GPIOLIB_IRQCHIP
* select IRQ_DOMAIN_HIERARCHY
* add comment to clarify wakeup_path atomic usage
* add more details to the commit message, including usage of the
hierarchical IRQ domain and wakeup capability implementation
Cosmin Tanislav (8):
pinctrl: renesas: rzt2h: move GPIO enable/disable into separate
function
pinctrl: renesas: rzt2h: allow .get_direction() for IRQ function GPIOs
dt-bindings: pinctrl: renesas,r9a09g077-pinctrl: Document GPIO IRQ
pinctrl: renesas: rzt2h: add GPIO IRQ chip to handle interrupts
arm64: dts: renesas: r9a09g077: add GPIO IRQ support
arm64: dts: renesas: r9a09g087: add GPIO IRQ support
arm64: dts: renesas: r9a09g077m44-rzt2h-evk: add GPIO keys
arm64: dts: renesas: r9a09g087m44-rzn2h-evk: add GPIO keys
.../pinctrl/renesas,r9a09g077-pinctrl.yaml | 13 +
arch/arm64/boot/dts/renesas/r9a09g077.dtsi | 3 +
.../dts/renesas/r9a09g077m44-rzt2h-evk.dts | 33 +++
arch/arm64/boot/dts/renesas/r9a09g087.dtsi | 3 +
.../dts/renesas/r9a09g087m44-rzn2h-evk.dts | 30 +++
drivers/pinctrl/renesas/Kconfig | 2 +
drivers/pinctrl/renesas/pinctrl-rzt2h.c | 245 +++++++++++++++++-
7 files changed, 320 insertions(+), 9 deletions(-)
--
2.52.0
^ permalink raw reply [flat|nested] 12+ messages in thread* [PATCH v2 1/8] pinctrl: renesas: rzt2h: move GPIO enable/disable into separate function 2025-12-05 15:02 [PATCH v2 0/8] Add support for GPIO IRQs for RZ/T2H and RZ/N2H Cosmin Tanislav @ 2025-12-05 15:02 ` Cosmin Tanislav 2025-12-05 15:02 ` [PATCH v2 2/8] pinctrl: renesas: rzt2h: allow .get_direction() for IRQ function GPIOs Cosmin Tanislav ` (6 subsequent siblings) 7 siblings, 0 replies; 12+ messages in thread From: Cosmin Tanislav @ 2025-12-05 15:02 UTC (permalink / raw) To: Geert Uytterhoeven, Linus Walleij, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Magnus Damm, Lad Prabhakar Cc: linux-renesas-soc, linux-gpio, devicetree, linux-kernel, Cosmin Tanislav GPIO is enabled or disabled in multiple places, simplify code by moving this logic into a separate function. Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com> --- V2: * no changes drivers/pinctrl/renesas/pinctrl-rzt2h.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/drivers/pinctrl/renesas/pinctrl-rzt2h.c b/drivers/pinctrl/renesas/pinctrl-rzt2h.c index 4826ff91cd90..c8ca5e13bba7 100644 --- a/drivers/pinctrl/renesas/pinctrl-rzt2h.c +++ b/drivers/pinctrl/renesas/pinctrl-rzt2h.c @@ -119,6 +119,19 @@ static int rzt2h_validate_pin(struct rzt2h_pinctrl *pctrl, unsigned int offset) return (pincfg & BIT(pin)) ? 0 : -EINVAL; } +static void rzt2h_pinctrl_set_gpio_en(struct rzt2h_pinctrl *pctrl, + u8 port, u8 pin, bool en) +{ + u8 reg = rzt2h_pinctrl_readb(pctrl, port, PMC(port)); + + if (en) + reg &= ~BIT(pin); + else + reg |= BIT(pin); + + rzt2h_pinctrl_writeb(pctrl, port, reg, PMC(port)); +} + static void rzt2h_pinctrl_set_pfc_mode(struct rzt2h_pinctrl *pctrl, u8 port, u8 pin, u8 func) { @@ -133,8 +146,7 @@ static void rzt2h_pinctrl_set_pfc_mode(struct rzt2h_pinctrl *pctrl, rzt2h_pinctrl_writew(pctrl, port, reg16, PM(port)); /* Temporarily switch to GPIO mode with PMC register */ - reg16 = rzt2h_pinctrl_readb(pctrl, port, PMC(port)); - rzt2h_pinctrl_writeb(pctrl, port, reg16 & ~BIT(pin), PMC(port)); + rzt2h_pinctrl_set_gpio_en(pctrl, port, pin, true); /* Select Pin function mode with PFC register */ reg64 = rzt2h_pinctrl_readq(pctrl, port, PFC(port)); @@ -142,8 +154,7 @@ static void rzt2h_pinctrl_set_pfc_mode(struct rzt2h_pinctrl *pctrl, rzt2h_pinctrl_writeq(pctrl, port, reg64 | ((u64)func << (pin * 8)), PFC(port)); /* Switch to Peripheral pin function with PMC register */ - reg16 = rzt2h_pinctrl_readb(pctrl, port, PMC(port)); - rzt2h_pinctrl_writeb(pctrl, port, reg16 | BIT(pin), PMC(port)); + rzt2h_pinctrl_set_gpio_en(pctrl, port, pin, false); } static int rzt2h_pinctrl_set_mux(struct pinctrl_dev *pctldev, @@ -447,7 +458,6 @@ static int rzt2h_gpio_request(struct gpio_chip *chip, unsigned int offset) u8 port = RZT2H_PIN_ID_TO_PORT(offset); u8 bit = RZT2H_PIN_ID_TO_PIN(offset); int ret; - u8 reg; ret = rzt2h_validate_pin(pctrl, offset); if (ret) @@ -460,9 +470,7 @@ static int rzt2h_gpio_request(struct gpio_chip *chip, unsigned int offset) guard(spinlock_irqsave)(&pctrl->lock); /* Select GPIO mode in PMC Register */ - reg = rzt2h_pinctrl_readb(pctrl, port, PMC(port)); - reg &= ~BIT(bit); - rzt2h_pinctrl_writeb(pctrl, port, reg, PMC(port)); + rzt2h_pinctrl_set_gpio_en(pctrl, port, bit, true); return 0; } -- 2.52.0 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v2 2/8] pinctrl: renesas: rzt2h: allow .get_direction() for IRQ function GPIOs 2025-12-05 15:02 [PATCH v2 0/8] Add support for GPIO IRQs for RZ/T2H and RZ/N2H Cosmin Tanislav 2025-12-05 15:02 ` [PATCH v2 1/8] pinctrl: renesas: rzt2h: move GPIO enable/disable into separate function Cosmin Tanislav @ 2025-12-05 15:02 ` Cosmin Tanislav 2025-12-05 15:02 ` [PATCH v2 3/8] dt-bindings: pinctrl: renesas,r9a09g077-pinctrl: Document GPIO IRQ Cosmin Tanislav ` (5 subsequent siblings) 7 siblings, 0 replies; 12+ messages in thread From: Cosmin Tanislav @ 2025-12-05 15:02 UTC (permalink / raw) To: Geert Uytterhoeven, Linus Walleij, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Magnus Damm, Lad Prabhakar Cc: linux-renesas-soc, linux-gpio, devicetree, linux-kernel, Cosmin Tanislav Setting up an IRQ would normally be done in the .activate() and .deactivate() ops of the IRQ domain, but for hierarchical IRQ domains the .activate() and .deactivate() ops are overridden in the gpiochip_hierarchy_setup_domain_ops() function. As such, activating and deactivating need to be done in the .translate() and .free() ops of the IRQ domain. For RZ/T2H and RZ/N2H, interrupts go through the pin controller, into the ICU, which level-translates them and forwards them to the GIC. To use a GPIO as an interrupt it needs to be put into peripheral function mode 0, which will connect it to the IRQ lines of the ICU. The IRQ chip .child_to_parent_hwirq() callback is called as part of the IRQ fwspec parsing logic (as part of irq_create_of_mapping()) which happens before the IRQ is requested (as part of gpiochip_lock_as_irq()). gpiochip_lock_as_irq() calls gpiod_get_direction() if the .get_direction() callback is provided to ensure that the GPIO line is set up as input. In our case, IRQ function is separate from GPIO, and both cannot be true at the same time. Return GPIO_LINE_DIRECTION_IN even if pin is in IRQ function to allow this setup to work. Hold the spinlock to ensure atomicity between reading the PMC register (which determines whether the pin is in GPIO mode or not) and reading the function of the pin when it is not in GPIO mode. Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com> --- V2: * no changes drivers/pinctrl/renesas/pinctrl-rzt2h.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/renesas/pinctrl-rzt2h.c b/drivers/pinctrl/renesas/pinctrl-rzt2h.c index c8ca5e13bba7..722551723e06 100644 --- a/drivers/pinctrl/renesas/pinctrl-rzt2h.c +++ b/drivers/pinctrl/renesas/pinctrl-rzt2h.c @@ -51,6 +51,7 @@ #define PFC_MASK GENMASK_ULL(5, 0) #define PFC_PIN_MASK(pin) (PFC_MASK << ((pin) * 8)) +#define PFC_FUNC_INTERRUPT 0 /* * Use 16 lower bits [15:0] for pin identifier @@ -494,6 +495,7 @@ static int rzt2h_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) struct rzt2h_pinctrl *pctrl = gpiochip_get_data(chip); u8 port = RZT2H_PIN_ID_TO_PORT(offset); u8 bit = RZT2H_PIN_ID_TO_PIN(offset); + u64 reg64; u16 reg; int ret; @@ -501,8 +503,25 @@ static int rzt2h_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) if (ret) return ret; - if (rzt2h_pinctrl_readb(pctrl, port, PMC(port)) & BIT(bit)) + guard(spinlock_irqsave)(&pctrl->lock); + + if (rzt2h_pinctrl_readb(pctrl, port, PMC(port)) & BIT(bit)) { + /* + * When a GPIO is being requested as an IRQ, the pinctrl + * framework expects to be able to read the GPIO's direction. + * IRQ function is separate from GPIO, and enabling it takes the + * pin out of GPIO mode. + * At this point, .child_to_parent_hwirq() has already been + * called to enable the IRQ function. + * Default to input direction for IRQ function. + */ + reg64 = rzt2h_pinctrl_readq(pctrl, port, PFC(port)); + reg64 = (reg64 >> (bit * 8)) & PFC_MASK; + if (reg64 == PFC_FUNC_INTERRUPT) + return GPIO_LINE_DIRECTION_IN; + return -EINVAL; + } reg = rzt2h_pinctrl_readw(pctrl, port, PM(port)); reg = (reg >> (bit * 2)) & PM_MASK; -- 2.52.0 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v2 3/8] dt-bindings: pinctrl: renesas,r9a09g077-pinctrl: Document GPIO IRQ 2025-12-05 15:02 [PATCH v2 0/8] Add support for GPIO IRQs for RZ/T2H and RZ/N2H Cosmin Tanislav 2025-12-05 15:02 ` [PATCH v2 1/8] pinctrl: renesas: rzt2h: move GPIO enable/disable into separate function Cosmin Tanislav 2025-12-05 15:02 ` [PATCH v2 2/8] pinctrl: renesas: rzt2h: allow .get_direction() for IRQ function GPIOs Cosmin Tanislav @ 2025-12-05 15:02 ` Cosmin Tanislav 2025-12-09 21:06 ` Rob Herring (Arm) 2025-12-10 23:42 ` Linus Walleij 2025-12-05 15:02 ` [PATCH v2 4/8] pinctrl: renesas: rzt2h: add GPIO IRQ chip to handle interrupts Cosmin Tanislav ` (4 subsequent siblings) 7 siblings, 2 replies; 12+ messages in thread From: Cosmin Tanislav @ 2025-12-05 15:02 UTC (permalink / raw) To: Geert Uytterhoeven, Linus Walleij, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Magnus Damm, Lad Prabhakar Cc: linux-renesas-soc, linux-gpio, devicetree, linux-kernel, Cosmin Tanislav The Renesas RZ/T2H (R9A09G077) and Renesas RZ/N2H (R9A09G087) SoCs have IRQ-capable pins handled by the ICU, which forwards them to the GIC. The ICU supports 16 IRQ lines, the pins map to these lines arbitrarily, and the mapping is not configurable. Document the required properties to handle GPIO IRQ. Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com> --- V2: * drop interrupt-controller and #interrupt-cells from required to keep compatibility .../bindings/pinctrl/renesas,r9a09g077-pinctrl.yaml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Documentation/devicetree/bindings/pinctrl/renesas,r9a09g077-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/renesas,r9a09g077-pinctrl.yaml index 36d665971484..f049013a4e0c 100644 --- a/Documentation/devicetree/bindings/pinctrl/renesas,r9a09g077-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/renesas,r9a09g077-pinctrl.yaml @@ -49,6 +49,17 @@ properties: gpio-ranges: maxItems: 1 + interrupt-controller: true + + '#interrupt-cells': + const: 2 + description: + The first cell contains the global GPIO port index, constructed using the + RZT2H_GPIO() helper macro from <dt-bindings/pinctrl/renesas,r9a09g077-pinctrl.h> + and the second cell is used to specify the flag. + E.g. "interrupts = <RZT2H_GPIO(8, 6) IRQ_TYPE_EDGE_FALLING>;" if P08_6 is + being used as an interrupt. + clocks: maxItems: 1 @@ -139,6 +150,8 @@ examples: gpio-controller; #gpio-cells = <2>; gpio-ranges = <&pinctrl 0 0 288>; + interrupt-controller; + #interrupt-cells = <2>; power-domains = <&cpg>; serial0-pins { -- 2.52.0 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH v2 3/8] dt-bindings: pinctrl: renesas,r9a09g077-pinctrl: Document GPIO IRQ 2025-12-05 15:02 ` [PATCH v2 3/8] dt-bindings: pinctrl: renesas,r9a09g077-pinctrl: Document GPIO IRQ Cosmin Tanislav @ 2025-12-09 21:06 ` Rob Herring (Arm) 2025-12-10 23:42 ` Linus Walleij 1 sibling, 0 replies; 12+ messages in thread From: Rob Herring (Arm) @ 2025-12-09 21:06 UTC (permalink / raw) To: Cosmin Tanislav Cc: Lad Prabhakar, Magnus Damm, Conor Dooley, Geert Uytterhoeven, linux-kernel, linux-gpio, linux-renesas-soc, Krzysztof Kozlowski, devicetree, Linus Walleij On Fri, 05 Dec 2025 17:02:29 +0200, Cosmin Tanislav wrote: > The Renesas RZ/T2H (R9A09G077) and Renesas RZ/N2H (R9A09G087) SoCs have > IRQ-capable pins handled by the ICU, which forwards them to the GIC. > > The ICU supports 16 IRQ lines, the pins map to these lines arbitrarily, > and the mapping is not configurable. > > Document the required properties to handle GPIO IRQ. > > Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com> > --- > > V2: > * drop interrupt-controller and #interrupt-cells from required to keep > compatibility > > .../bindings/pinctrl/renesas,r9a09g077-pinctrl.yaml | 13 +++++++++++++ > 1 file changed, 13 insertions(+) > Reviewed-by: Rob Herring (Arm) <robh@kernel.org> ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 3/8] dt-bindings: pinctrl: renesas,r9a09g077-pinctrl: Document GPIO IRQ 2025-12-05 15:02 ` [PATCH v2 3/8] dt-bindings: pinctrl: renesas,r9a09g077-pinctrl: Document GPIO IRQ Cosmin Tanislav 2025-12-09 21:06 ` Rob Herring (Arm) @ 2025-12-10 23:42 ` Linus Walleij 1 sibling, 0 replies; 12+ messages in thread From: Linus Walleij @ 2025-12-10 23:42 UTC (permalink / raw) To: Cosmin Tanislav Cc: Geert Uytterhoeven, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Magnus Damm, Lad Prabhakar, linux-renesas-soc, linux-gpio, devicetree, linux-kernel On Fri, Dec 5, 2025 at 4:03 PM Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com> wrote: > The Renesas RZ/T2H (R9A09G077) and Renesas RZ/N2H (R9A09G087) SoCs have > IRQ-capable pins handled by the ICU, which forwards them to the GIC. > > The ICU supports 16 IRQ lines, the pins map to these lines arbitrarily, > and the mapping is not configurable. > > Document the required properties to handle GPIO IRQ. > > Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com> Reviewed-by: Linus Walleij <linusw@kernel.org> Yours, Linus Walleij ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v2 4/8] pinctrl: renesas: rzt2h: add GPIO IRQ chip to handle interrupts 2025-12-05 15:02 [PATCH v2 0/8] Add support for GPIO IRQs for RZ/T2H and RZ/N2H Cosmin Tanislav ` (2 preceding siblings ...) 2025-12-05 15:02 ` [PATCH v2 3/8] dt-bindings: pinctrl: renesas,r9a09g077-pinctrl: Document GPIO IRQ Cosmin Tanislav @ 2025-12-05 15:02 ` Cosmin Tanislav 2025-12-10 23:45 ` Linus Walleij 2025-12-05 15:02 ` [PATCH v2 5/8] arm64: dts: renesas: r9a09g077: add GPIO IRQ support Cosmin Tanislav ` (3 subsequent siblings) 7 siblings, 1 reply; 12+ messages in thread From: Cosmin Tanislav @ 2025-12-05 15:02 UTC (permalink / raw) To: Geert Uytterhoeven, Linus Walleij, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Magnus Damm, Lad Prabhakar Cc: linux-renesas-soc, linux-gpio, devicetree, linux-kernel, Cosmin Tanislav The Renesas RZ/T2H (R9A09G077) and Renesas RZ/N2H (R9A09G087) SoCs have IRQ-capable pins handled by the ICU, which forwards them to the GIC. The ICU supports 16 IRQ lines, the pins map to these lines arbitrarily, and the mapping is not configurable. Add a GPIO IRQ chip to the pin controller that can be used to configure these pins as IRQ lines. The pin controller places the requested pins into IRQ function, disabling GPIO mode. A hierarchical IRQ domain is used to forward other functionality to the parent IRQ domain, the ICU. The ICU does level translation and then forwards other functionality to the GIC. Wakeup capability is implemented by placing the entire pin controller on the wakeup path if any pins are requested to be wakeup-capable. Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com> --- V2: * select GPIOLIB_IRQCHIP * select IRQ_DOMAIN_HIERARCHY * add comment to clarify wakeup_path atomic usage * add more details to the commit message, including usage of the hierarchical IRQ domain and wakeup capability implementation drivers/pinctrl/renesas/Kconfig | 2 + drivers/pinctrl/renesas/pinctrl-rzt2h.c | 200 ++++++++++++++++++++++++ 2 files changed, 202 insertions(+) diff --git a/drivers/pinctrl/renesas/Kconfig b/drivers/pinctrl/renesas/Kconfig index 8cbd79a13414..d979e25e5088 100644 --- a/drivers/pinctrl/renesas/Kconfig +++ b/drivers/pinctrl/renesas/Kconfig @@ -308,9 +308,11 @@ config PINCTRL_RZT2H bool "pin control support for RZ/N2H and RZ/T2H" if COMPILE_TEST depends on 64BIT && OF select GPIOLIB + select GPIOLIB_IRQCHIP select GENERIC_PINCTRL_GROUPS select GENERIC_PINMUX_FUNCTIONS select GENERIC_PINCONF + select IRQ_DOMAIN_HIERARCHY help This selects GPIO and pinctrl driver for Renesas RZ/T2H platforms. diff --git a/drivers/pinctrl/renesas/pinctrl-rzt2h.c b/drivers/pinctrl/renesas/pinctrl-rzt2h.c index 722551723e06..c276cbd3f87a 100644 --- a/drivers/pinctrl/renesas/pinctrl-rzt2h.c +++ b/drivers/pinctrl/renesas/pinctrl-rzt2h.c @@ -18,6 +18,7 @@ #include <linux/module.h> #include <linux/mutex.h> #include <linux/of_device.h> +#include <linux/of_irq.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> #include <linux/spinlock.h> @@ -65,6 +66,9 @@ #define RZT2H_MAX_SAFETY_PORTS 12 +#define RZT2H_INTERRUPTS_START 16 +#define RZT2H_INTERRUPTS_NUM 17 + struct rzt2h_pinctrl_data { unsigned int n_port_pins; const u8 *port_pin_configs; @@ -80,9 +84,11 @@ struct rzt2h_pinctrl { struct device *dev; struct gpio_chip gpio_chip; struct pinctrl_gpio_range gpio_range; + DECLARE_BITMAP(used_irqs, RZT2H_INTERRUPTS_NUM); spinlock_t lock; /* lock read/write registers */ struct mutex mutex; /* serialize adding groups and functions */ bool safety_port_enabled; + atomic_t wakeup_path; }; #define RZT2H_GET_BASE(pctrl, port) \ @@ -644,14 +650,194 @@ static const char * const rzt2h_gpio_names[] = { "P35_0", "P35_1", "P35_2", "P35_3", "P35_4", "P35_5", "P35_6", "P35_7", }; +/* + * Interrupts 0-15 are for INTCPUn, which are not exposed externally. + * Interrupts 16-31 are for IRQn. SEI is 32. + * This table matches the information found in User Manual's Table 17.2, + * List of multiplexed pin configurations (5 of 51). + * RZ/N2H has the same GPIO to IRQ mapping, except for the pins which + * are not present. + */ +static const u8 rzt2h_gpio_irq_map[] = { + 32, 16, 17, 18, 19, 0, 20, 21, + 22, 0, 0, 0, 0, 0, 0, 0, + 23, 24, 25, 26, 27, 0, 0, 0, + 0, 0, 28, 29, 30, 31, 0, 0, + 0, 0, 0, 0, 0, 32, 16, 17, + 18, 19, 20, 21, 22, 0, 0, 0, + 0, 0, 24, 25, 26, 27, 0, 28, + 29, 30, 31, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 24, 32, 16, + 0, 0, 0, 0, 0, 0, 0, 0, + 20, 23, 17, 18, 19, 0, 16, 25, + 29, 20, 21, 22, 23, 0, 0, 0, + 0, 0, 0, 0, 17, 0, 0, 18, + 0, 0, 19, 0, 0, 20, 0, 30, + 21, 0, 0, 22, 0, 0, 24, 25, + 0, 0, 0, 0, 0, 16, 17, 0, + 18, 0, 0, 26, 27, 0, 0, 0, + 28, 29, 30, 31, 0, 0, 0, 0, + 23, 31, 32, 16, 17, 18, 19, 20, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 27, 0, 0, 21, 22, 23, 24, 25, + 26, 0, 0, 0, 0, 0, 0, 0, + 27, 28, 29, 30, 31, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 28, 32, 16, + 17, 18, 19, 0, 0, 0, 0, 20, + 21, 22, 23, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 24, 25, 0, 0, + 0, 0, 26, 27, 0, 0, 0, 30, + 0, 29, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 28, 29, 30, 31, 0, + 0, 0, 0, 0, 0, 0, 0, 30, + 0, 0, 0, 0, 0, 0, 0, 0, +}; + +static void rzt2h_gpio_irq_disable(struct irq_data *d) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + unsigned int hwirq = irqd_to_hwirq(d); + + irq_chip_disable_parent(d); + gpiochip_disable_irq(gc, hwirq); +} + +static void rzt2h_gpio_irq_enable(struct irq_data *d) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + unsigned int hwirq = irqd_to_hwirq(d); + + gpiochip_enable_irq(gc, hwirq); + irq_chip_enable_parent(d); +} + +static int rzt2h_gpio_irq_set_wake(struct irq_data *d, unsigned int on) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct rzt2h_pinctrl *pctrl = container_of(gc, struct rzt2h_pinctrl, gpio_chip); + int ret; + + ret = irq_chip_set_wake_parent(d, on); + if (ret) + return ret; + + /* + * If any of the IRQs are in use, put the entire pin controller on the + * device wakeup path. + */ + if (on) + atomic_inc(&pctrl->wakeup_path); + else + atomic_dec(&pctrl->wakeup_path); + + return 0; +} + +static const struct irq_chip rzt2h_gpio_irqchip = { + .name = "rzt2h-gpio", + .irq_disable = rzt2h_gpio_irq_disable, + .irq_enable = rzt2h_gpio_irq_enable, + .irq_mask = irq_chip_mask_parent, + .irq_unmask = irq_chip_unmask_parent, + .irq_set_type = irq_chip_set_type_parent, + .irq_set_wake = rzt2h_gpio_irq_set_wake, + .irq_eoi = irq_chip_eoi_parent, + .irq_set_affinity = irq_chip_set_affinity_parent, + .flags = IRQCHIP_IMMUTABLE, + GPIOCHIP_IRQ_RESOURCE_HELPERS, +}; + +static int rzt2h_pinctrl_suspend_noirq(struct device *dev) +{ + struct rzt2h_pinctrl *pctrl = dev_get_drvdata(dev); + + if (atomic_read(&pctrl->wakeup_path)) + device_set_wakeup_path(dev); + + return 0; +} + +static int rzt2h_gpio_child_to_parent_hwirq(struct gpio_chip *gc, + unsigned int child, + unsigned int child_type, + unsigned int *parent, + unsigned int *parent_type) +{ + struct rzt2h_pinctrl *pctrl = gpiochip_get_data(gc); + u8 port = RZT2H_PIN_ID_TO_PORT(child); + u8 pin = RZT2H_PIN_ID_TO_PIN(child); + u8 parent_irq; + + parent_irq = rzt2h_gpio_irq_map[child]; + if (parent_irq < RZT2H_INTERRUPTS_START) + return -EINVAL; + + if (test_and_set_bit(parent_irq - RZT2H_INTERRUPTS_START, + pctrl->used_irqs)) + return -EBUSY; + + rzt2h_pinctrl_set_pfc_mode(pctrl, port, pin, PFC_FUNC_INTERRUPT); + + *parent = parent_irq; + *parent_type = child_type; + + return 0; +} + +static void rzt2h_gpio_irq_domain_free(struct irq_domain *domain, unsigned int virq, + unsigned int nr_irqs) +{ + struct irq_data *d = irq_domain_get_irq_data(domain, virq); + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct rzt2h_pinctrl *pctrl = container_of(gc, struct rzt2h_pinctrl, gpio_chip); + irq_hw_number_t hwirq = irqd_to_hwirq(d); + u8 port = RZT2H_PIN_ID_TO_PORT(hwirq); + u8 pin = RZT2H_PIN_ID_TO_PIN(hwirq); + + if (test_and_clear_bit(hwirq - RZT2H_INTERRUPTS_START, pctrl->used_irqs)) + rzt2h_pinctrl_set_gpio_en(pctrl, port, pin, false); + + irq_domain_free_irqs_common(domain, virq, nr_irqs); +} + +static void rzt2h_gpio_init_irq_valid_mask(struct gpio_chip *gc, + unsigned long *valid_mask, + unsigned int ngpios) +{ + struct rzt2h_pinctrl *pctrl = gpiochip_get_data(gc); + unsigned int offset; + + for (offset = 0; offset < ngpios; offset++) { + if (!rzt2h_gpio_irq_map[offset] || rzt2h_validate_pin(pctrl, offset)) + clear_bit(offset, valid_mask); + } +} + static int rzt2h_gpio_register(struct rzt2h_pinctrl *pctrl) { struct pinctrl_gpio_range *range = &pctrl->gpio_range; struct gpio_chip *chip = &pctrl->gpio_chip; + struct device_node *np = pctrl->dev->of_node; + struct irq_domain *parent_domain; struct device *dev = pctrl->dev; struct of_phandle_args of_args; + struct device_node *parent_np; + struct gpio_irq_chip *girq; int ret; + parent_np = of_irq_find_parent(np); + if (!parent_np) + return -ENXIO; + + parent_domain = irq_find_host(parent_np); + of_node_put(parent_np); + if (!parent_domain) + return -EPROBE_DEFER; + ret = of_parse_phandle_with_fixed_args(dev->of_node, "gpio-ranges", 3, 0, &of_args); if (ret) return dev_err_probe(dev, ret, "Unable to parse gpio-ranges\n"); @@ -675,6 +861,15 @@ static int rzt2h_gpio_register(struct rzt2h_pinctrl *pctrl) chip->set = rzt2h_gpio_set; chip->label = dev_name(dev); + girq = &chip->irq; + gpio_irq_chip_set_chip(girq, &rzt2h_gpio_irqchip); + girq->fwnode = dev_fwnode(pctrl->dev); + girq->parent_domain = parent_domain; + girq->child_to_parent_hwirq = rzt2h_gpio_child_to_parent_hwirq; + girq->populate_parent_alloc_arg = gpiochip_populate_parent_fwspec_twocell; + girq->child_irq_domain_ops.free = rzt2h_gpio_irq_domain_free; + girq->init_valid_mask = rzt2h_gpio_init_irq_valid_mask; + range->id = 0; range->pin_base = 0; range->base = 0; @@ -819,10 +1014,15 @@ static const struct of_device_id rzt2h_pinctrl_of_table[] = { { /* sentinel */ } }; +static const struct dev_pm_ops rzt2h_pinctrl_pm_ops = { + NOIRQ_SYSTEM_SLEEP_PM_OPS(rzt2h_pinctrl_suspend_noirq, NULL) +}; + static struct platform_driver rzt2h_pinctrl_driver = { .driver = { .name = DRV_NAME, .of_match_table = of_match_ptr(rzt2h_pinctrl_of_table), + .pm = pm_sleep_ptr(&rzt2h_pinctrl_pm_ops), .suppress_bind_attrs = true, }, .probe = rzt2h_pinctrl_probe, -- 2.52.0 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH v2 4/8] pinctrl: renesas: rzt2h: add GPIO IRQ chip to handle interrupts 2025-12-05 15:02 ` [PATCH v2 4/8] pinctrl: renesas: rzt2h: add GPIO IRQ chip to handle interrupts Cosmin Tanislav @ 2025-12-10 23:45 ` Linus Walleij 0 siblings, 0 replies; 12+ messages in thread From: Linus Walleij @ 2025-12-10 23:45 UTC (permalink / raw) To: Cosmin Tanislav Cc: Geert Uytterhoeven, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Magnus Damm, Lad Prabhakar, linux-renesas-soc, linux-gpio, devicetree, linux-kernel On Fri, Dec 5, 2025 at 4:03 PM Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com> wrote: > The Renesas RZ/T2H (R9A09G077) and Renesas RZ/N2H (R9A09G087) SoCs have > IRQ-capable pins handled by the ICU, which forwards them to the GIC. > > The ICU supports 16 IRQ lines, the pins map to these lines arbitrarily, > and the mapping is not configurable. > > Add a GPIO IRQ chip to the pin controller that can be used to configure > these pins as IRQ lines. > > The pin controller places the requested pins into IRQ function, > disabling GPIO mode. A hierarchical IRQ domain is used to forward other > functionality to the parent IRQ domain, the ICU. The ICU does level > translation and then forwards other functionality to the GIC. > > Wakeup capability is implemented by placing the entire pin controller on > the wakeup path if any pins are requested to be wakeup-capable. > > Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com> Reviewed-by: Linus Walleij <linusw@kernel.org> Yours, Linus Walleij ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v2 5/8] arm64: dts: renesas: r9a09g077: add GPIO IRQ support 2025-12-05 15:02 [PATCH v2 0/8] Add support for GPIO IRQs for RZ/T2H and RZ/N2H Cosmin Tanislav ` (3 preceding siblings ...) 2025-12-05 15:02 ` [PATCH v2 4/8] pinctrl: renesas: rzt2h: add GPIO IRQ chip to handle interrupts Cosmin Tanislav @ 2025-12-05 15:02 ` Cosmin Tanislav 2025-12-05 15:02 ` [PATCH v2 6/8] arm64: dts: renesas: r9a09g087: " Cosmin Tanislav ` (2 subsequent siblings) 7 siblings, 0 replies; 12+ messages in thread From: Cosmin Tanislav @ 2025-12-05 15:02 UTC (permalink / raw) To: Geert Uytterhoeven, Linus Walleij, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Magnus Damm, Lad Prabhakar Cc: linux-renesas-soc, linux-gpio, devicetree, linux-kernel, Cosmin Tanislav The Renesas RZ/T2H (R9A09G077) SoC includes pins which can be routed via the ICU to generate interrupts. Add support for using the pin controller as an interrupt chip. Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com> --- V2: * no changes arch/arm64/boot/dts/renesas/r9a09g077.dtsi | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm64/boot/dts/renesas/r9a09g077.dtsi b/arch/arm64/boot/dts/renesas/r9a09g077.dtsi index 0af41287e6a8..6812af127684 100644 --- a/arch/arm64/boot/dts/renesas/r9a09g077.dtsi +++ b/arch/arm64/boot/dts/renesas/r9a09g077.dtsi @@ -945,6 +945,9 @@ pinctrl: pinctrl@802c0000 { gpio-controller; #gpio-cells = <2>; gpio-ranges = <&pinctrl 0 0 288>; + #interrupt-cells = <2>; + interrupt-controller; + interrupt-parent = <&icu>; power-domains = <&cpg>; }; -- 2.52.0 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v2 6/8] arm64: dts: renesas: r9a09g087: add GPIO IRQ support 2025-12-05 15:02 [PATCH v2 0/8] Add support for GPIO IRQs for RZ/T2H and RZ/N2H Cosmin Tanislav ` (4 preceding siblings ...) 2025-12-05 15:02 ` [PATCH v2 5/8] arm64: dts: renesas: r9a09g077: add GPIO IRQ support Cosmin Tanislav @ 2025-12-05 15:02 ` Cosmin Tanislav 2025-12-05 15:02 ` [PATCH v2 7/8] arm64: dts: renesas: r9a09g077m44-rzt2h-evk: add GPIO keys Cosmin Tanislav 2025-12-05 15:02 ` [PATCH v2 8/8] arm64: dts: renesas: r9a09g087m44-rzn2h-evk: " Cosmin Tanislav 7 siblings, 0 replies; 12+ messages in thread From: Cosmin Tanislav @ 2025-12-05 15:02 UTC (permalink / raw) To: Geert Uytterhoeven, Linus Walleij, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Magnus Damm, Lad Prabhakar Cc: linux-renesas-soc, linux-gpio, devicetree, linux-kernel, Cosmin Tanislav The Renesas RZ/N2H (R9A09G087) SoC includes pins which can be routed via the ICU to generate interrupts. Add support for using the pin controller as an interrupt chip. Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com> --- V2: * no changes arch/arm64/boot/dts/renesas/r9a09g087.dtsi | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm64/boot/dts/renesas/r9a09g087.dtsi b/arch/arm64/boot/dts/renesas/r9a09g087.dtsi index 6b5693e5c1f9..19475c72017f 100644 --- a/arch/arm64/boot/dts/renesas/r9a09g087.dtsi +++ b/arch/arm64/boot/dts/renesas/r9a09g087.dtsi @@ -948,6 +948,9 @@ pinctrl: pinctrl@802c0000 { gpio-controller; #gpio-cells = <2>; gpio-ranges = <&pinctrl 0 0 280>; + #interrupt-cells = <2>; + interrupt-controller; + interrupt-parent = <&icu>; power-domains = <&cpg>; }; -- 2.52.0 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v2 7/8] arm64: dts: renesas: r9a09g077m44-rzt2h-evk: add GPIO keys 2025-12-05 15:02 [PATCH v2 0/8] Add support for GPIO IRQs for RZ/T2H and RZ/N2H Cosmin Tanislav ` (5 preceding siblings ...) 2025-12-05 15:02 ` [PATCH v2 6/8] arm64: dts: renesas: r9a09g087: " Cosmin Tanislav @ 2025-12-05 15:02 ` Cosmin Tanislav 2025-12-05 15:02 ` [PATCH v2 8/8] arm64: dts: renesas: r9a09g087m44-rzn2h-evk: " Cosmin Tanislav 7 siblings, 0 replies; 12+ messages in thread From: Cosmin Tanislav @ 2025-12-05 15:02 UTC (permalink / raw) To: Geert Uytterhoeven, Linus Walleij, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Magnus Damm, Lad Prabhakar Cc: linux-renesas-soc, linux-gpio, devicetree, linux-kernel, Cosmin Tanislav The Renesas RZ/T2H Evaluation Kit has three user buttons connected to GPIOs that can be used as input keys. Add support for them. Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com> --- V2: * no changes .../dts/renesas/r9a09g077m44-rzt2h-evk.dts | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/arch/arm64/boot/dts/renesas/r9a09g077m44-rzt2h-evk.dts b/arch/arm64/boot/dts/renesas/r9a09g077m44-rzt2h-evk.dts index d1474f1bd523..a2584a3afb01 100644 --- a/arch/arm64/boot/dts/renesas/r9a09g077m44-rzt2h-evk.dts +++ b/arch/arm64/boot/dts/renesas/r9a09g077m44-rzt2h-evk.dts @@ -7,6 +7,8 @@ /dts-v1/; +#include <dt-bindings/input/input.h> + #include "r9a09g077m44.dtsi" /* @@ -60,6 +62,37 @@ / { model = "Renesas RZ/T2H EVK Board based on r9a09g077m44"; compatible = "renesas,rzt2h-evk", "renesas,r9a09g077m44", "renesas,r9a09g077"; + keys { + compatible = "gpio-keys"; + +#if (!SD1_MICRO_SD) + /* SW2-3: ON */ + key-1 { + interrupts-extended = <&pinctrl RZT2H_GPIO(8, 6) IRQ_TYPE_EDGE_FALLING>; + linux,code = <KEY_1>; + label = "SW9"; + wakeup-source; + debounce-interval = <20>; + }; +#endif + + key-2 { + interrupts-extended = <&pinctrl RZT2H_GPIO(0, 3) IRQ_TYPE_EDGE_FALLING>; + linux,code = <KEY_2>; + label = "SW10"; + wakeup-source; + debounce-interval = <20>; + }; + + key-3 { + interrupts-extended = <&pinctrl RZT2H_GPIO(8, 7) IRQ_TYPE_EDGE_FALLING>; + linux,code = <KEY_3>; + label = "SW11"; + wakeup-source; + debounce-interval = <20>; + }; + }; + leds { compatible = "gpio-leds"; -- 2.52.0 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v2 8/8] arm64: dts: renesas: r9a09g087m44-rzn2h-evk: add GPIO keys 2025-12-05 15:02 [PATCH v2 0/8] Add support for GPIO IRQs for RZ/T2H and RZ/N2H Cosmin Tanislav ` (6 preceding siblings ...) 2025-12-05 15:02 ` [PATCH v2 7/8] arm64: dts: renesas: r9a09g077m44-rzt2h-evk: add GPIO keys Cosmin Tanislav @ 2025-12-05 15:02 ` Cosmin Tanislav 7 siblings, 0 replies; 12+ messages in thread From: Cosmin Tanislav @ 2025-12-05 15:02 UTC (permalink / raw) To: Geert Uytterhoeven, Linus Walleij, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Magnus Damm, Lad Prabhakar Cc: linux-renesas-soc, linux-gpio, devicetree, linux-kernel, Cosmin Tanislav The Renesas RZ/N2H Evaluation Kit has three user buttons connected to GPIOs that can be used as input keys. Add support for them. Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com> --- V2: * no changes .../dts/renesas/r9a09g087m44-rzn2h-evk.dts | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/arch/arm64/boot/dts/renesas/r9a09g087m44-rzn2h-evk.dts b/arch/arm64/boot/dts/renesas/r9a09g087m44-rzn2h-evk.dts index eaf73868783b..252f1c21ff90 100644 --- a/arch/arm64/boot/dts/renesas/r9a09g087m44-rzn2h-evk.dts +++ b/arch/arm64/boot/dts/renesas/r9a09g087m44-rzn2h-evk.dts @@ -7,6 +7,8 @@ /dts-v1/; +#include <dt-bindings/input/input.h> + #include "r9a09g087m44.dtsi" /* @@ -77,6 +79,34 @@ / { model = "Renesas RZ/N2H EVK Board based on r9a09g087m44"; compatible = "renesas,rzn2h-evk", "renesas,r9a09g087m44", "renesas,r9a09g087"; + keys { + compatible = "gpio-keys"; + + key-1 { + interrupts-extended = <&pinctrl RZT2H_GPIO(18, 2) IRQ_TYPE_EDGE_FALLING>; + linux,code = <KEY_1>; + label = "SW2"; + wakeup-source; + debounce-interval = <20>; + }; + + key-2 { + interrupts-extended = <&pinctrl RZT2H_GPIO(0, 4) IRQ_TYPE_EDGE_FALLING>; + linux,code = <KEY_2>; + label = "SW3"; + wakeup-source; + debounce-interval = <20>; + }; + + key-3 { + interrupts-extended = <&pinctrl RZT2H_GPIO(18, 7) IRQ_TYPE_EDGE_FALLING>; + linux,code = <KEY_3>; + label = "SW4"; + wakeup-source; + debounce-interval = <20>; + }; + }; + leds { compatible = "gpio-leds"; -- 2.52.0 ^ permalink raw reply related [flat|nested] 12+ messages in thread
end of thread, other threads:[~2025-12-10 23:45 UTC | newest] Thread overview: 12+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-12-05 15:02 [PATCH v2 0/8] Add support for GPIO IRQs for RZ/T2H and RZ/N2H Cosmin Tanislav 2025-12-05 15:02 ` [PATCH v2 1/8] pinctrl: renesas: rzt2h: move GPIO enable/disable into separate function Cosmin Tanislav 2025-12-05 15:02 ` [PATCH v2 2/8] pinctrl: renesas: rzt2h: allow .get_direction() for IRQ function GPIOs Cosmin Tanislav 2025-12-05 15:02 ` [PATCH v2 3/8] dt-bindings: pinctrl: renesas,r9a09g077-pinctrl: Document GPIO IRQ Cosmin Tanislav 2025-12-09 21:06 ` Rob Herring (Arm) 2025-12-10 23:42 ` Linus Walleij 2025-12-05 15:02 ` [PATCH v2 4/8] pinctrl: renesas: rzt2h: add GPIO IRQ chip to handle interrupts Cosmin Tanislav 2025-12-10 23:45 ` Linus Walleij 2025-12-05 15:02 ` [PATCH v2 5/8] arm64: dts: renesas: r9a09g077: add GPIO IRQ support Cosmin Tanislav 2025-12-05 15:02 ` [PATCH v2 6/8] arm64: dts: renesas: r9a09g087: " Cosmin Tanislav 2025-12-05 15:02 ` [PATCH v2 7/8] arm64: dts: renesas: r9a09g077m44-rzt2h-evk: add GPIO keys Cosmin Tanislav 2025-12-05 15:02 ` [PATCH v2 8/8] arm64: dts: renesas: r9a09g087m44-rzn2h-evk: " Cosmin Tanislav
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).