]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
pinctrl: renesas: rzg2l: Drop unnecessary pin configurations
authorBiju Das <biju.das.jz@bp.renesas.com>
Tue, 9 Sep 2025 10:42:44 +0000 (11:42 +0100)
committerGeert Uytterhoeven <geert+renesas@glider.be>
Tue, 14 Oct 2025 08:32:51 +0000 (10:32 +0200)
There is no need to reconfigure a pin if the pin's configuration
values are the same as the reset values.  E.g. the PS0 pin configuration
for the NMI function is PMC = 1 and PFC = 0, which is the same as the
reset values.  Currently the code is first setting it to GPIO HI-Z state
and then again reconfiguring to the NMI function, leading to spurious
IRQs.  Fix this by dropping unnecessary pin configuration from the
driver.

Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Link: https://patch.msgid.link/20250909104247.3309-1-biju.das.jz@bp.renesas.com
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
drivers/pinctrl/renesas/pinctrl-rzg2l.c

index c360e473488c333e3a2dbead98c3cd776c29ffc0..efb406046f1a62baebfa90496471fe5be0aaa961 100644 (file)
@@ -541,9 +541,16 @@ 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;
 
+       /* Switching to GPIO is not required if reset value is same as func */
        raw_spin_lock_irqsave(&pctrl->lock, flags);
+       reg = readb(pctrl->base + PMC(off));
+       pfc = readl(pctrl->base + PFC(off));
+       if ((reg & BIT(pin)) && (((pfc >> (pin * 4)) & PFC_MASK) == func)) {
+               raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+               return;
+       }
 
        /* Set pin to 'Non-use (Hi-Z input protection)'  */
        reg = readw(pctrl->base + PM(off));
@@ -557,9 +564,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));
@@ -3130,11 +3136,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));
@@ -3144,8 +3157,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. */