There is no need to reconfigure the pin if the pin's configuration values
are same as the reset values. E.g.: PS0 pin configuration for NMI function
is PMC = 1 and PFC = 0 and is same as that of reset values. Currently the
code is first setting it to GPIO HI-Z state and then again reconfiguring
to NMI function leading to spurious IRQ. Drop the unnecessary pin
configurations from the driver.
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
v3->v4:
* No change.
v2->v3:
* Dropped extra space before the == operator.
* Moved spinlock acquire before reading pfc value.
* Make sure it is configured for function in PMC register for
skipping GPIO switch.
v1->v2:
* Updated commit header and description.
* Added check in rzg2l_pinctrl_set_pfc_mode() to avoid unnecessary
configuration
---
drivers/pinctrl/renesas/pinctrl-rzg2l.c | 22 ++++++++++++++++------
1 file changed, 16 insertions(+), 6 deletions(-)
diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
index 94cb77949f59..5ae8d28199d5 100644
--- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c
+++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
@@ -541,7 +541,11 @@ static void rzg2l_pinctrl_set_pfc_mode(struct rzg2l_pinctrl *pctrl,
u8 pin, u8 off, u8 func)
{
unsigned long flags;
- u32 reg;
+ u32 reg, pfc;
+
+ pfc = readl(pctrl->base + PFC(off));
+ if (((pfc >> (pin * 4)) & PFC_MASK) == func)
+ return;
spin_lock_irqsave(&pctrl->lock, flags);
@@ -557,9 +561,8 @@ static void rzg2l_pinctrl_set_pfc_mode(struct rzg2l_pinctrl *pctrl,
writeb(reg & ~BIT(pin), pctrl->base + PMC(off));
/* Select Pin function mode with PFC register */
- reg = readl(pctrl->base + PFC(off));
- reg &= ~(PFC_MASK << (pin * 4));
- writel(reg | (func << (pin * 4)), pctrl->base + PFC(off));
+ pfc &= ~(PFC_MASK << (pin * 4));
+ writel(pfc | (func << (pin * 4)), pctrl->base + PFC(off));
/* Switch to Peripheral pin function with PMC register */
reg = readb(pctrl->base + PMC(off));
@@ -3117,11 +3120,18 @@ static void rzg2l_pinctrl_pm_setup_pfc(struct rzg2l_pinctrl *pctrl)
pm = readw(pctrl->base + PM(off));
for_each_set_bit(pin, &pinmap, max_pin) {
struct rzg2l_pinctrl_reg_cache *cache = pctrl->cache;
+ u32 pfc_val, pfc_mask;
/* Nothing to do if PFC was not configured before. */
if (!(cache->pmc[port] & BIT(pin)))
continue;
+ pfc_val = readl(pctrl->base + PFC(off));
+ pfc_mask = PFC_MASK << (pin * 4);
+ /* Nothing to do if reset value of the pin is same as cached value */
+ if ((cache->pfc[port] & pfc_mask) == (pfc_val & pfc_mask))
+ continue;
+
/* Set pin to 'Non-use (Hi-Z input protection)' */
pm &= ~(PM_MASK << (pin * 2));
writew(pm, pctrl->base + PM(off));
@@ -3131,8 +3141,8 @@ static void rzg2l_pinctrl_pm_setup_pfc(struct rzg2l_pinctrl *pctrl)
writeb(pmc, pctrl->base + PMC(off));
/* Select Pin function mode. */
- pfc &= ~(PFC_MASK << (pin * 4));
- pfc |= (cache->pfc[port] & (PFC_MASK << (pin * 4)));
+ pfc &= ~pfc_mask;
+ pfc |= (cache->pfc[port] & pfc_mask);
writel(pfc, pctrl->base + PFC(off));
/* Switch to Peripheral pin function. */
--
2.43.0
Hi Biju, On Sun, 21 Sept 2025 at 13:16, Biju Das <biju.das.jz@bp.renesas.com> wrote: > There is no need to reconfigure the pin if the pin's configuration values > are same as the reset values. E.g.: PS0 pin configuration for NMI function > is PMC = 1 and PFC = 0 and is same as that of reset values. Currently the > code is first setting it to GPIO HI-Z state and then again reconfiguring > to NMI function leading to spurious IRQ. Drop the unnecessary pin > configurations from the driver. > > Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com> > --- > v3->v4: > * No change. > v2->v3: > * Dropped extra space before the == operator. > * Moved spinlock acquire before reading pfc value. > * Make sure it is configured for function in PMC register for > skipping GPIO switch. Thanks for the update! > --- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c > +++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c > @@ -541,7 +541,11 @@ static void rzg2l_pinctrl_set_pfc_mode(struct rzg2l_pinctrl *pctrl, > u8 pin, u8 off, u8 func) > { > unsigned long flags; > - u32 reg; > + u32 reg, pfc; > + > + pfc = readl(pctrl->base + PFC(off)); > + if (((pfc >> (pin * 4)) & PFC_MASK) == func) > + return; > > spin_lock_irqsave(&pctrl->lock, flags); > Looks like you accidentally switched back to the code from v2? Shall I take v3 instead? Thanks! Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org 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
© 2016 - 2025 Red Hat, Inc.