]> git.ipfire.org Git - thirdparty/kernel/stable.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)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 19 Jun 2025 13:32:23 +0000 (15:32 +0200)
[ Upstream commit bdbe0a0f71003b997d6a2dbe4bc7b5b0438207c7 ]

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>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/pinctrl/samsung/pinctrl-exynos-arm64.c
drivers/pinctrl/samsung/pinctrl-exynos.c
drivers/pinctrl/samsung/pinctrl-exynos.h

index ce61a85c7784a23bab5cbf8c60b3cf2e01d49a0f..a2ac1702d0dfae41350e624bbaf477ffaed62609 100644 (file)
@@ -1024,15 +1024,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,
@@ -1046,29 +1046,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 af4fb1cde8de942707d932072bb237521e30c9c6..7887fd41665111d7c4b47e2d74f4e6e335914915 100644 (file)
@@ -799,6 +799,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;
@@ -818,6 +853,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 837b737c6f0a7c5bd5770537e25a3fdf87268bad..c70b8ead56b4bcd1a879aca29d91f2944085b471 100644 (file)
@@ -215,6 +215,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);