RE: [PATCH 4/7] pinctrl: renesas: rzt2h: fix reading pin value in IRQ function

From: Cosmin-Gabriel Tanislav

Date: Tue Sep 08 2026 - 09:37:59 EST


> From: Geert Uytterhoeven <geert@xxxxxxxxxxxxxx>
> Sent: Tuesday, September 8, 2026 12:56 PM
>
> Hi Cosmin,
>
> On Mon, 17 Aug 2026 at 20:58, Cosmin Tanislav
> <cosmin-gabriel.tanislav.xa@xxxxxxxxxxx> wrote:
> > rzt2h_gpio_get() only reports a level for pins in input or output mode
> > and returns -EINVAL otherwise. When a pin is requested as an interrupt
> > it is switched to IRQ function and its I/O mode is set to Hi-Z, so its
> > value can no longer be read.
> >
> > gpiolib calls gpiod_get_value_cansleep() to determine the edge's
> > direction when a line is watched with GPIO_V2_LINE_FLAG_EDGE_BOTH.
> > Non-zero values are translated to a rising edge, zero to a falling edge.
> >
> > Since gpiod_get_value_cansleep() ends up calling rzt2h_gpio_get() which
> > returns -EINVAL when the pin is in IRQ function, every edge is reported
> > as rising.
> >
> > When using the IRQ function, the input buffers are enabled and the PINm
> > registers reflect the live state of the input.
> >
> > Report the input level even when the pin is used as an IRQ.
> >
> > Cc: stable@xxxxxxxxxx
> > Fixes: 829dde3369a9 ("pinctrl: renesas: rzt2h: Add GPIO IRQ chip to handle interrupts")
> > Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@xxxxxxxxxxx>
>
> Thanks for your patch!
>
> > --- a/drivers/pinctrl/renesas/pinctrl-rzt2h.c
> > +++ b/drivers/pinctrl/renesas/pinctrl-rzt2h.c
> > @@ -171,6 +171,23 @@ static int rzt2h_validate_pin(struct rzt2h_pinctrl *pctrl, unsigned int offset)
> > return (pincfg & BIT(pin)) ? 0 : -EINVAL;
> > }
> >
> > +static bool rzt2h_pin_mode_is_peripheral(struct rzt2h_pinctrl *pctrl, u8 port, u8 bit)
> > +{
> > + return rzt2h_pinctrl_readb(pctrl, port, PMC(port)) & BIT(bit);
> > +}
> > +
> > +static u8 rzt2h_pin_read_pfc(struct rzt2h_pinctrl *pctrl, u8 port, u8 pin)
> > +{
> > + u64 reg64 = rzt2h_pinctrl_readq(pctrl, port, PFC(port));
> > +
> > + return field_get(PFC_PIN_MASK(pin), reg64);
> > +}
> > +
> > +static bool rzt2h_pin_read_input(struct rzt2h_pinctrl *pctrl, u8 port, u8 bit)
> > +{
> > + return rzt2h_pinctrl_readb(pctrl, port, PIN(port)) & BIT(bit);
> > +}
> > +
> > static u8 rzt2h_pin_read_pm(struct rzt2h_pinctrl *pctrl, u8 port, u8 pin)
> > {
> > u16 reg = rzt2h_pinctrl_readw(pctrl, port, PM(port));
> > @@ -847,6 +864,13 @@ static int rzt2h_gpio_get(struct gpio_chip *chip, unsigned int offset)
> > u8 bit = RZT2H_PIN_ID_TO_PIN(offset);
> > u16 reg;
> >
> > + if (rzt2h_pin_mode_is_peripheral(pctrl, port, bit)) {
> > + if (rzt2h_pin_read_pfc(pctrl, port, bit) == PFC_FUNC_INTERRUPT)
>
> Section 17.4.5 ("PINm : Port m Input Register (m = 00 to 35)") states:
>
> "The PINm register is valid not only for general I/O mode (PMCn = 0b)
> but also when peripheral function is selected (PMCn = 1b) and it works
> as input."
>
> this is not limited to PFC_FUNC_INTERRUPT, so I think you can drop
> this check?
>

Ack.