]> git.ipfire.org Git - thirdparty/kernel/linux.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)
committerGeert Uytterhoeven <geert+renesas@glider.be>
Fri, 14 Feb 2025 08:36:00 +0000 (09:36 +0100)
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>
drivers/pinctrl/renesas/pinctrl-rzg2l.c

index ce4a07a3df49aded07edd1508b247bea0a7f4681..298e1aa89c8f0d0cfc3f0b83a827fc17087416a0 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]),
@@ -2953,7 +2960,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;
@@ -2965,6 +2972,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]);
@@ -2983,6 +2991,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]);