]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
pinctrl: samsung: add gs101 specific eint suspend/resume callbacks
authorPeter Griffin <peter.griffin@linaro.org>
Wed, 2 Apr 2025 15:17:32 +0000 (16:17 +0100)
committerKrzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Tue, 8 Apr 2025 18:57:47 +0000 (20:57 +0200)
gs101 differs to other SoCs in that fltcon1 register doesn't
always exist. Additionally the offset of fltcon0 is not fixed
and needs to use the newly added eint_fltcon_offset variable.

Fixes: 4a8be01a1a7a ("pinctrl: samsung: Add gs101 SoC pinctrl configuration")
Cc: stable@vger.kernel.org # depends on the previous three patches
Reviewed-by: André Draszik <andre.draszik@linaro.org>
Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
Link: https://lore.kernel.org/r/20250402-pinctrl-fltcon-suspend-v6-3-78ce0d4eb30c@linaro.org
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
drivers/pinctrl/samsung/pinctrl-exynos-arm64.c
drivers/pinctrl/samsung/pinctrl-exynos.c
drivers/pinctrl/samsung/pinctrl-exynos.h

index 4b5d4e436a337ff13dee6ef740a1500eaf86cc12..9fd894729a7b87c3e144ff90921a1cadbde93d3d 100644 (file)
@@ -1762,15 +1762,15 @@ static const struct samsung_pin_ctrl gs101_pin_ctrl[] __initconst = {
                .pin_banks      = gs101_pin_alive,
                .nr_banks       = ARRAY_SIZE(gs101_pin_alive),
                .eint_wkup_init = exynos_eint_wkup_init,
-               .suspend        = exynos_pinctrl_suspend,
-               .resume         = exynos_pinctrl_resume,
+               .suspend        = gs101_pinctrl_suspend,
+               .resume         = gs101_pinctrl_resume,
        }, {
                /* pin banks of gs101 pin-controller (FAR_ALIVE) */
                .pin_banks      = gs101_pin_far_alive,
                .nr_banks       = ARRAY_SIZE(gs101_pin_far_alive),
                .eint_wkup_init = exynos_eint_wkup_init,
-               .suspend        = exynos_pinctrl_suspend,
-               .resume         = exynos_pinctrl_resume,
+               .suspend        = gs101_pinctrl_suspend,
+               .resume         = gs101_pinctrl_resume,
        }, {
                /* pin banks of gs101 pin-controller (GSACORE) */
                .pin_banks      = gs101_pin_gsacore,
@@ -1784,29 +1784,29 @@ static const struct samsung_pin_ctrl gs101_pin_ctrl[] __initconst = {
                .pin_banks      = gs101_pin_peric0,
                .nr_banks       = ARRAY_SIZE(gs101_pin_peric0),
                .eint_gpio_init = exynos_eint_gpio_init,
-               .suspend        = exynos_pinctrl_suspend,
-               .resume         = exynos_pinctrl_resume,
+               .suspend        = gs101_pinctrl_suspend,
+               .resume         = gs101_pinctrl_resume,
        }, {
                /* pin banks of gs101 pin-controller (PERIC1) */
                .pin_banks      = gs101_pin_peric1,
                .nr_banks       = ARRAY_SIZE(gs101_pin_peric1),
                .eint_gpio_init = exynos_eint_gpio_init,
-               .suspend        = exynos_pinctrl_suspend,
-               .resume = exynos_pinctrl_resume,
+               .suspend        = gs101_pinctrl_suspend,
+               .resume         = gs101_pinctrl_resume,
        }, {
                /* pin banks of gs101 pin-controller (HSI1) */
                .pin_banks      = gs101_pin_hsi1,
                .nr_banks       = ARRAY_SIZE(gs101_pin_hsi1),
                .eint_gpio_init = exynos_eint_gpio_init,
-               .suspend        = exynos_pinctrl_suspend,
-               .resume         = exynos_pinctrl_resume,
+               .suspend        = gs101_pinctrl_suspend,
+               .resume         = gs101_pinctrl_resume,
        }, {
                /* pin banks of gs101 pin-controller (HSI2) */
                .pin_banks      = gs101_pin_hsi2,
                .nr_banks       = ARRAY_SIZE(gs101_pin_hsi2),
                .eint_gpio_init = exynos_eint_gpio_init,
-               .suspend        = exynos_pinctrl_suspend,
-               .resume         = exynos_pinctrl_resume,
+               .suspend        = gs101_pinctrl_suspend,
+               .resume         = gs101_pinctrl_resume,
        },
 };
 
index 18c327f7e313355c4aba72f49a79b1697244f1ba..0879684338c772e484174a94ac2c274cc7d932ed 100644 (file)
@@ -800,6 +800,41 @@ void exynos_pinctrl_suspend(struct samsung_pin_bank *bank)
        }
 }
 
+void gs101_pinctrl_suspend(struct samsung_pin_bank *bank)
+{
+       struct exynos_eint_gpio_save *save = bank->soc_priv;
+       const void __iomem *regs = bank->eint_base;
+
+       if (bank->eint_type == EINT_TYPE_GPIO) {
+               save->eint_con = readl(regs + EXYNOS_GPIO_ECON_OFFSET
+                                      + bank->eint_offset);
+
+               save->eint_fltcon0 = readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET
+                                          + bank->eint_fltcon_offset);
+
+               /* fltcon1 register only exists for pins 4-7 */
+               if (bank->nr_pins > 4)
+                       save->eint_fltcon1 = readl(regs +
+                                               EXYNOS_GPIO_EFLTCON_OFFSET
+                                               + bank->eint_fltcon_offset + 4);
+
+               save->eint_mask = readl(regs + bank->irq_chip->eint_mask
+                                       + bank->eint_offset);
+
+               pr_debug("%s: save     con %#010x\n",
+                        bank->name, save->eint_con);
+               pr_debug("%s: save fltcon0 %#010x\n",
+                        bank->name, save->eint_fltcon0);
+               if (bank->nr_pins > 4)
+                       pr_debug("%s: save fltcon1 %#010x\n",
+                                bank->name, save->eint_fltcon1);
+               pr_debug("%s: save    mask %#010x\n",
+                        bank->name, save->eint_mask);
+       } else if (bank->eint_type == EINT_TYPE_WKUP) {
+               exynos_set_wakeup(bank);
+       }
+}
+
 void exynosautov920_pinctrl_suspend(struct samsung_pin_bank *bank)
 {
        struct exynos_eint_gpio_save *save = bank->soc_priv;
@@ -819,6 +854,42 @@ void exynosautov920_pinctrl_suspend(struct samsung_pin_bank *bank)
        }
 }
 
+void gs101_pinctrl_resume(struct samsung_pin_bank *bank)
+{
+       struct exynos_eint_gpio_save *save = bank->soc_priv;
+
+       void __iomem *regs = bank->eint_base;
+       void __iomem *eint_fltcfg0 = regs + EXYNOS_GPIO_EFLTCON_OFFSET
+                    + bank->eint_fltcon_offset;
+
+       if (bank->eint_type == EINT_TYPE_GPIO) {
+               pr_debug("%s:     con %#010x => %#010x\n", bank->name,
+                        readl(regs + EXYNOS_GPIO_ECON_OFFSET
+                              + bank->eint_offset), save->eint_con);
+
+               pr_debug("%s: fltcon0 %#010x => %#010x\n", bank->name,
+                        readl(eint_fltcfg0), save->eint_fltcon0);
+
+               /* fltcon1 register only exists for pins 4-7 */
+               if (bank->nr_pins > 4)
+                       pr_debug("%s: fltcon1 %#010x => %#010x\n", bank->name,
+                                readl(eint_fltcfg0 + 4), save->eint_fltcon1);
+
+               pr_debug("%s:    mask %#010x => %#010x\n", bank->name,
+                        readl(regs + bank->irq_chip->eint_mask
+                              + bank->eint_offset), save->eint_mask);
+
+               writel(save->eint_con, regs + EXYNOS_GPIO_ECON_OFFSET
+                      + bank->eint_offset);
+               writel(save->eint_fltcon0, eint_fltcfg0);
+
+               if (bank->nr_pins > 4)
+                       writel(save->eint_fltcon1, eint_fltcfg0 + 4);
+               writel(save->eint_mask, regs + bank->irq_chip->eint_mask
+                      + bank->eint_offset);
+       }
+}
+
 void exynos_pinctrl_resume(struct samsung_pin_bank *bank)
 {
        struct exynos_eint_gpio_save *save = bank->soc_priv;
index 3a771862b4b1762b32f9e067b011e80cfebb99d2..2bee52b61b9317ff79c618c1dc53e98242805087 100644 (file)
@@ -244,6 +244,8 @@ void exynosautov920_pinctrl_resume(struct samsung_pin_bank *bank);
 void exynosautov920_pinctrl_suspend(struct samsung_pin_bank *bank);
 void exynos_pinctrl_suspend(struct samsung_pin_bank *bank);
 void exynos_pinctrl_resume(struct samsung_pin_bank *bank);
+void gs101_pinctrl_suspend(struct samsung_pin_bank *bank);
+void gs101_pinctrl_resume(struct samsung_pin_bank *bank);
 struct samsung_retention_ctrl *
 exynos_retention_init(struct samsung_pinctrl_drv_data *drvdata,
                      const struct samsung_retention_data *data);