Even though some pins are set correctly during resume(e.g.: PS0), due to the unconditional switch to GPIO for restoring the PFC register is triggering spurious IRQ on RZ/G3E. So avoid switch to GPIO if the pin is configured correctly during resume. Signed-off-by: Biju Das <biju.das.jz@xxxxxxxxxxxxxx> --- drivers/pinctrl/renesas/pinctrl-rzg2l.c | 35 ++++++++++++++++--------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c index 2a10ae0bf5bd..09ee771b1e36 100644 --- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c +++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c @@ -3118,27 +3118,36 @@ 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_mask; + u32 pfc_val; + u8 pmc_val; /* Nothing to do if PFC was not configured before. */ if (!(cache->pmc[port] & BIT(pin))) continue; - /* Set pin to 'Non-use (Hi-Z input protection)' */ - pm &= ~(PM_MASK << (pin * 2)); - writew(pm, pctrl->base + PM(off)); + pfc_val = readl(pctrl->base + PFC(off)); + pmc_val = readb(pctrl->base + PMC(off)) & BIT(pin); + pfc_mask = PFC_MASK << (pin * 4); - /* Temporarily switch to GPIO mode with PMC register */ - pmc &= ~BIT(pin); - writeb(pmc, pctrl->base + PMC(off)); + if (!pmc_val || ((cache->pfc[port] & pfc_mask) != (pfc_val & pfc_mask))) { + /* Set pin to 'Non-use (Hi-Z input protection)' */ + pm &= ~(PM_MASK << (pin * 2)); + writew(pm, pctrl->base + PM(off)); - /* Select Pin function mode. */ - pfc &= ~(PFC_MASK << (pin * 4)); - pfc |= (cache->pfc[port] & (PFC_MASK << (pin * 4))); - writel(pfc, pctrl->base + PFC(off)); + /* Temporarily switch to GPIO mode with PMC register */ + pmc &= ~BIT(pin); + writeb(pmc, pctrl->base + PMC(off)); - /* Switch to Peripheral pin function. */ - pmc |= BIT(pin); - writeb(pmc, pctrl->base + PMC(off)); + /* Select Pin function mode. */ + pfc &= ~pfc_mask; + pfc |= cache->pfc[port] & pfc_mask; + writel(pfc, pctrl->base + PFC(off)); + + /* Switch to Peripheral pin function. */ + pmc |= BIT(pin); + writeb(pmc, pctrl->base + PMC(off)); + } } } -- 2.43.0