]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
pinctrl: renesas: rzg2l: Add suspend/resume support for pull up/down
authorClaudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
Wed, 5 Feb 2025 10:01:16 +0000 (12:01 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 29 May 2025 09:13:23 +0000 (11:13 +0200)
[ Upstream commit b2bd65fbb617353e3c46ba5206b3b030fa0f260c ]

The Renesas RZ/G3S supports a power-saving mode where power to most of
the SoC components is lost, including the PIN controller.  Save and
restore the pull-up/pull-down register contents to ensure the
functionality is preserved after a suspend/resume cycle.

Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
Reviewed-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Link: https://lore.kernel.org/20250205100116.2032765-1-claudiu.beznea.uj@bp.renesas.com
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/pinctrl/renesas/pinctrl-rzg2l.c

index d1da7f53fc60087d83da0415f1bd7511cce7337c..c72e250f4a1544a15b81ffa246d1aee3b626fd98 100644 (file)
@@ -318,6 +318,7 @@ struct rzg2l_pinctrl_pin_settings {
  * @pmc: PMC registers cache
  * @pfc: PFC registers cache
  * @iolh: IOLH registers cache
+ * @pupd: PUPD registers cache
  * @ien: IEN registers cache
  * @sd_ch: SD_CH registers cache
  * @eth_poc: ET_POC registers cache
@@ -331,6 +332,7 @@ struct rzg2l_pinctrl_reg_cache {
        u32     *pfc;
        u32     *iolh[2];
        u32     *ien[2];
+       u32     *pupd[2];
        u8      sd_ch[2];
        u8      eth_poc[2];
        u8      eth_mode;
@@ -2712,6 +2714,11 @@ static int rzg2l_pinctrl_reg_cache_alloc(struct rzg2l_pinctrl *pctrl)
                if (!cache->ien[i])
                        return -ENOMEM;
 
+               cache->pupd[i] = devm_kcalloc(pctrl->dev, nports, sizeof(*cache->pupd[i]),
+                                             GFP_KERNEL);
+               if (!cache->pupd[i])
+                       return -ENOMEM;
+
                /* Allocate dedicated cache. */
                dedicated_cache->iolh[i] = devm_kcalloc(pctrl->dev, n_dedicated_pins,
                                                        sizeof(*dedicated_cache->iolh[i]),
@@ -2955,7 +2962,7 @@ static void rzg2l_pinctrl_pm_setup_regs(struct rzg2l_pinctrl *pctrl, bool suspen
        struct rzg2l_pinctrl_reg_cache *cache = pctrl->cache;
 
        for (u32 port = 0; port < nports; port++) {
-               bool has_iolh, has_ien;
+               bool has_iolh, has_ien, has_pupd;
                u32 off, caps;
                u8 pincnt;
                u64 cfg;
@@ -2967,6 +2974,7 @@ static void rzg2l_pinctrl_pm_setup_regs(struct rzg2l_pinctrl *pctrl, bool suspen
                caps = FIELD_GET(PIN_CFG_MASK, cfg);
                has_iolh = !!(caps & (PIN_CFG_IOLH_A | PIN_CFG_IOLH_B | PIN_CFG_IOLH_C));
                has_ien = !!(caps & PIN_CFG_IEN);
+               has_pupd = !!(caps & PIN_CFG_PUPD);
 
                if (suspend)
                        RZG2L_PCTRL_REG_ACCESS32(suspend, pctrl->base + PFC(off), cache->pfc[port]);
@@ -2985,6 +2993,15 @@ static void rzg2l_pinctrl_pm_setup_regs(struct rzg2l_pinctrl *pctrl, bool suspen
                        }
                }
 
+               if (has_pupd) {
+                       RZG2L_PCTRL_REG_ACCESS32(suspend, pctrl->base + PUPD(off),
+                                                cache->pupd[0][port]);
+                       if (pincnt >= 4) {
+                               RZG2L_PCTRL_REG_ACCESS32(suspend, pctrl->base + PUPD(off),
+                                                        cache->pupd[1][port]);
+                       }
+               }
+
                RZG2L_PCTRL_REG_ACCESS16(suspend, pctrl->base + PM(off), cache->pm[port]);
                RZG2L_PCTRL_REG_ACCESS8(suspend, pctrl->base + P(off), cache->p[port]);