--- /dev/null
+From 357ac8ecfd9a8b4fee0f0f12931a14b966882320 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Apr 2025 16:17:31 +0100
+Subject: pinctrl: samsung: add dedicated SoC eint suspend/resume callbacks
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Peter Griffin <peter.griffin@linaro.org>
+
+[ Upstream commit 77ac6b742eba063a5b6600cda67834a7a212281a ]
+
+Refactor the existing platform specific suspend/resume callback
+so that each SoC variant has it's own callback containing the
+SoC specific logic.
+
+This allows exynosautov920 to have a dedicated function for using
+eint_con_offset and eint_mask_offset. Also it is easily extendable
+for gs101 which will need dedicated logic for handling the varying
+register offset of fltcon0 via eint_fltcon_offset.
+
+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-2-78ce0d4eb30c@linaro.org
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Stable-dep-of: bdbe0a0f7100 ("pinctrl: samsung: add gs101 specific eint suspend/resume callbacks")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../pinctrl/samsung/pinctrl-exynos-arm64.c | 28 ++--
+ drivers/pinctrl/samsung/pinctrl-exynos.c | 152 ++++++++++--------
+ drivers/pinctrl/samsung/pinctrl-exynos.h | 2 +
+ 3 files changed, 97 insertions(+), 85 deletions(-)
+
+diff --git a/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c b/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c
+index dd07720e32cc0..4b5d4e436a337 100644
+--- a/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c
++++ b/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c
+@@ -1419,8 +1419,8 @@ static const struct samsung_pin_ctrl exynosautov920_pin_ctrl[] = {
+ .pin_banks = exynosautov920_pin_banks0,
+ .nr_banks = ARRAY_SIZE(exynosautov920_pin_banks0),
+ .eint_wkup_init = exynos_eint_wkup_init,
+- .suspend = exynos_pinctrl_suspend,
+- .resume = exynos_pinctrl_resume,
++ .suspend = exynosautov920_pinctrl_suspend,
++ .resume = exynosautov920_pinctrl_resume,
+ .retention_data = &exynosautov920_retention_data,
+ }, {
+ /* pin-controller instance 1 AUD data */
+@@ -1431,43 +1431,43 @@ static const struct samsung_pin_ctrl exynosautov920_pin_ctrl[] = {
+ .pin_banks = exynosautov920_pin_banks2,
+ .nr_banks = ARRAY_SIZE(exynosautov920_pin_banks2),
+ .eint_gpio_init = exynos_eint_gpio_init,
+- .suspend = exynos_pinctrl_suspend,
+- .resume = exynos_pinctrl_resume,
++ .suspend = exynosautov920_pinctrl_suspend,
++ .resume = exynosautov920_pinctrl_resume,
+ }, {
+ /* pin-controller instance 3 HSI1 data */
+ .pin_banks = exynosautov920_pin_banks3,
+ .nr_banks = ARRAY_SIZE(exynosautov920_pin_banks3),
+ .eint_gpio_init = exynos_eint_gpio_init,
+- .suspend = exynos_pinctrl_suspend,
+- .resume = exynos_pinctrl_resume,
++ .suspend = exynosautov920_pinctrl_suspend,
++ .resume = exynosautov920_pinctrl_resume,
+ }, {
+ /* pin-controller instance 4 HSI2 data */
+ .pin_banks = exynosautov920_pin_banks4,
+ .nr_banks = ARRAY_SIZE(exynosautov920_pin_banks4),
+ .eint_gpio_init = exynos_eint_gpio_init,
+- .suspend = exynos_pinctrl_suspend,
+- .resume = exynos_pinctrl_resume,
++ .suspend = exynosautov920_pinctrl_suspend,
++ .resume = exynosautov920_pinctrl_resume,
+ }, {
+ /* pin-controller instance 5 HSI2UFS data */
+ .pin_banks = exynosautov920_pin_banks5,
+ .nr_banks = ARRAY_SIZE(exynosautov920_pin_banks5),
+ .eint_gpio_init = exynos_eint_gpio_init,
+- .suspend = exynos_pinctrl_suspend,
+- .resume = exynos_pinctrl_resume,
++ .suspend = exynosautov920_pinctrl_suspend,
++ .resume = exynosautov920_pinctrl_resume,
+ }, {
+ /* pin-controller instance 6 PERIC0 data */
+ .pin_banks = exynosautov920_pin_banks6,
+ .nr_banks = ARRAY_SIZE(exynosautov920_pin_banks6),
+ .eint_gpio_init = exynos_eint_gpio_init,
+- .suspend = exynos_pinctrl_suspend,
+- .resume = exynos_pinctrl_resume,
++ .suspend = exynosautov920_pinctrl_suspend,
++ .resume = exynosautov920_pinctrl_resume,
+ }, {
+ /* pin-controller instance 7 PERIC1 data */
+ .pin_banks = exynosautov920_pin_banks7,
+ .nr_banks = ARRAY_SIZE(exynosautov920_pin_banks7),
+ .eint_gpio_init = exynos_eint_gpio_init,
+- .suspend = exynos_pinctrl_suspend,
+- .resume = exynos_pinctrl_resume,
++ .suspend = exynosautov920_pinctrl_suspend,
++ .resume = exynosautov920_pinctrl_resume,
+ },
+ };
+
+diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c
+index ae82f42be83cf..18c327f7e3133 100644
+--- a/drivers/pinctrl/samsung/pinctrl-exynos.c
++++ b/drivers/pinctrl/samsung/pinctrl-exynos.c
+@@ -762,105 +762,115 @@ __init int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d)
+ return 0;
+ }
+
+-static void exynos_pinctrl_suspend_bank(struct samsung_pin_bank *bank)
++static void exynos_set_wakeup(struct samsung_pin_bank *bank)
+ {
+- struct exynos_eint_gpio_save *save = bank->soc_priv;
+- const void __iomem *regs = bank->eint_base;
++ struct exynos_irq_chip *irq_chip;
+
+- save->eint_con = readl(regs + EXYNOS_GPIO_ECON_OFFSET
+- + bank->eint_offset);
+- save->eint_fltcon0 = readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET
+- + 2 * bank->eint_offset);
+- save->eint_fltcon1 = readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET
+- + 2 * bank->eint_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);
+- pr_debug("%s: save fltcon1 %#010x\n", bank->name, save->eint_fltcon1);
+- pr_debug("%s: save mask %#010x\n", bank->name, save->eint_mask);
++ if (bank->irq_chip) {
++ irq_chip = bank->irq_chip;
++ irq_chip->set_eint_wakeup_mask(bank->drvdata, irq_chip);
++ }
+ }
+
+-static void exynosauto_pinctrl_suspend_bank(struct samsung_pin_bank *bank)
++void exynos_pinctrl_suspend(struct samsung_pin_bank *bank)
+ {
+ struct exynos_eint_gpio_save *save = bank->soc_priv;
+ const void __iomem *regs = bank->eint_base;
+
+- save->eint_con = readl(regs + bank->pctl_offset + bank->eint_con_offset);
+- save->eint_mask = readl(regs + bank->pctl_offset + bank->eint_mask_offset);
+-
+- pr_debug("%s: save con %#010x\n", bank->name, save->eint_con);
+- pr_debug("%s: save mask %#010x\n", bank->name, save->eint_mask);
++ 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
++ + 2 * bank->eint_offset);
++ save->eint_fltcon1 = readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET
++ + 2 * bank->eint_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);
++ 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 exynos_pinctrl_suspend(struct samsung_pin_bank *bank)
++void exynosautov920_pinctrl_suspend(struct samsung_pin_bank *bank)
+ {
+- struct exynos_irq_chip *irq_chip = NULL;
++ struct exynos_eint_gpio_save *save = bank->soc_priv;
++ const void __iomem *regs = bank->eint_base;
+
+ if (bank->eint_type == EINT_TYPE_GPIO) {
+- if (bank->eint_con_offset)
+- exynosauto_pinctrl_suspend_bank(bank);
+- else
+- exynos_pinctrl_suspend_bank(bank);
++ save->eint_con = readl(regs + bank->pctl_offset +
++ bank->eint_con_offset);
++ save->eint_mask = readl(regs + bank->pctl_offset +
++ bank->eint_mask_offset);
++ pr_debug("%s: save con %#010x\n",
++ bank->name, save->eint_con);
++ pr_debug("%s: save mask %#010x\n",
++ bank->name, save->eint_mask);
+ } else if (bank->eint_type == EINT_TYPE_WKUP) {
+- if (!irq_chip) {
+- irq_chip = bank->irq_chip;
+- irq_chip->set_eint_wakeup_mask(bank->drvdata, irq_chip);
+- }
++ exynos_set_wakeup(bank);
+ }
+ }
+
+-static void exynos_pinctrl_resume_bank(struct samsung_pin_bank *bank)
++void exynos_pinctrl_resume(struct samsung_pin_bank *bank)
+ {
+ struct exynos_eint_gpio_save *save = bank->soc_priv;
+ void __iomem *regs = bank->eint_base;
+
+- 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(regs + EXYNOS_GPIO_EFLTCON_OFFSET
+- + 2 * bank->eint_offset), save->eint_fltcon0);
+- pr_debug("%s: fltcon1 %#010x => %#010x\n", bank->name,
+- readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET
+- + 2 * bank->eint_offset + 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, regs + EXYNOS_GPIO_EFLTCON_OFFSET
+- + 2 * bank->eint_offset);
+- writel(save->eint_fltcon1, regs + EXYNOS_GPIO_EFLTCON_OFFSET
+- + 2 * bank->eint_offset + 4);
+- writel(save->eint_mask, regs + bank->irq_chip->eint_mask
+- + bank->eint_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(regs + EXYNOS_GPIO_EFLTCON_OFFSET
++ + 2 * bank->eint_offset), save->eint_fltcon0);
++ pr_debug("%s: fltcon1 %#010x => %#010x\n", bank->name,
++ readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET
++ + 2 * bank->eint_offset + 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, regs + EXYNOS_GPIO_EFLTCON_OFFSET
++ + 2 * bank->eint_offset);
++ writel(save->eint_fltcon1, regs + EXYNOS_GPIO_EFLTCON_OFFSET
++ + 2 * bank->eint_offset + 4);
++ writel(save->eint_mask, regs + bank->irq_chip->eint_mask
++ + bank->eint_offset);
++ }
+ }
+
+-static void exynosauto_pinctrl_resume_bank(struct samsung_pin_bank *bank)
++void exynosautov920_pinctrl_resume(struct samsung_pin_bank *bank)
+ {
+ struct exynos_eint_gpio_save *save = bank->soc_priv;
+ void __iomem *regs = bank->eint_base;
+
+- pr_debug("%s: con %#010x => %#010x\n", bank->name,
+- readl(regs + bank->pctl_offset + bank->eint_con_offset), save->eint_con);
+- pr_debug("%s: mask %#010x => %#010x\n", bank->name,
+- readl(regs + bank->pctl_offset + bank->eint_mask_offset), save->eint_mask);
+-
+- writel(save->eint_con, regs + bank->pctl_offset + bank->eint_con_offset);
+- writel(save->eint_mask, regs + bank->pctl_offset + bank->eint_mask_offset);
+-
+-}
+-
+-void exynos_pinctrl_resume(struct samsung_pin_bank *bank)
+-{
+ if (bank->eint_type == EINT_TYPE_GPIO) {
+- if (bank->eint_con_offset)
+- exynosauto_pinctrl_resume_bank(bank);
+- else
+- exynos_pinctrl_resume_bank(bank);
++ /* exynosautov920 has eint_con_offset for all but one bank */
++ if (!bank->eint_con_offset)
++ exynos_pinctrl_resume(bank);
++
++ pr_debug("%s: con %#010x => %#010x\n", bank->name,
++ readl(regs + bank->pctl_offset + bank->eint_con_offset),
++ save->eint_con);
++ pr_debug("%s: mask %#010x => %#010x\n", bank->name,
++ readl(regs + bank->pctl_offset +
++ bank->eint_mask_offset), save->eint_mask);
++
++ writel(save->eint_con,
++ regs + bank->pctl_offset + bank->eint_con_offset);
++ writel(save->eint_mask,
++ regs + bank->pctl_offset + bank->eint_mask_offset);
+ }
+ }
+
+diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.h b/drivers/pinctrl/samsung/pinctrl-exynos.h
+index 341155c1abd15..3a771862b4b17 100644
+--- a/drivers/pinctrl/samsung/pinctrl-exynos.h
++++ b/drivers/pinctrl/samsung/pinctrl-exynos.h
+@@ -240,6 +240,8 @@ struct exynos_muxed_weint_data {
+
+ int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d);
+ int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d);
++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);
+ struct samsung_retention_ctrl *
+--
+2.39.5
+
--- /dev/null
+From 79380757a0c11403da4e07c8efd3731e5aae0826 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Apr 2025 16:17:32 +0100
+Subject: pinctrl: samsung: add gs101 specific eint suspend/resume callbacks
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Peter Griffin <peter.griffin@linaro.org>
+
+[ 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>
+---
+ .../pinctrl/samsung/pinctrl-exynos-arm64.c | 24 +++----
+ drivers/pinctrl/samsung/pinctrl-exynos.c | 71 +++++++++++++++++++
+ drivers/pinctrl/samsung/pinctrl-exynos.h | 2 +
+ 3 files changed, 85 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c b/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c
+index 4b5d4e436a337..9fd894729a7b8 100644
+--- a/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c
++++ b/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c
+@@ -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,
+ },
+ };
+
+diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c
+index 18c327f7e3133..0879684338c77 100644
+--- a/drivers/pinctrl/samsung/pinctrl-exynos.c
++++ b/drivers/pinctrl/samsung/pinctrl-exynos.c
+@@ -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;
+diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.h b/drivers/pinctrl/samsung/pinctrl-exynos.h
+index 3a771862b4b17..2bee52b61b931 100644
+--- a/drivers/pinctrl/samsung/pinctrl-exynos.h
++++ b/drivers/pinctrl/samsung/pinctrl-exynos.h
+@@ -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);
+--
+2.39.5
+
--- /dev/null
+From cc74ee4b7a396be6f6010682c220cb0cc2086b3b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Apr 2025 16:17:30 +0100
+Subject: pinctrl: samsung: refactor drvdata suspend & resume callbacks
+
+From: Peter Griffin <peter.griffin@linaro.org>
+
+[ Upstream commit 3ade961e97f3b05dcdd9a4fabfe179c9e75571e0 ]
+
+This enables the clk_enable() and clk_disable() logic to be removed
+from each callback, but otherwise should have no functional impact.
+
+It is a prepatory patch so that the callbacks can become SoC
+specific.
+
+Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
+Link: https://lore.kernel.org/r/20250402-pinctrl-fltcon-suspend-v6-1-78ce0d4eb30c@linaro.org
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Stable-dep-of: bdbe0a0f7100 ("pinctrl: samsung: add gs101 specific eint suspend/resume callbacks")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/samsung/pinctrl-exynos.c | 89 ++++++-----------------
+ drivers/pinctrl/samsung/pinctrl-exynos.h | 4 +-
+ drivers/pinctrl/samsung/pinctrl-samsung.c | 21 ++++--
+ drivers/pinctrl/samsung/pinctrl-samsung.h | 8 +-
+ 4 files changed, 42 insertions(+), 80 deletions(-)
+
+diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c
+index 42093bae8bb79..ae82f42be83cf 100644
+--- a/drivers/pinctrl/samsung/pinctrl-exynos.c
++++ b/drivers/pinctrl/samsung/pinctrl-exynos.c
+@@ -762,19 +762,11 @@ __init int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d)
+ return 0;
+ }
+
+-static void exynos_pinctrl_suspend_bank(
+- struct samsung_pinctrl_drv_data *drvdata,
+- struct samsung_pin_bank *bank)
++static void exynos_pinctrl_suspend_bank(struct samsung_pin_bank *bank)
+ {
+ struct exynos_eint_gpio_save *save = bank->soc_priv;
+ const void __iomem *regs = bank->eint_base;
+
+- if (clk_enable(bank->drvdata->pclk)) {
+- dev_err(bank->gpio_chip.parent,
+- "unable to enable clock for saving state\n");
+- return;
+- }
+-
+ save->eint_con = readl(regs + EXYNOS_GPIO_ECON_OFFSET
+ + bank->eint_offset);
+ save->eint_fltcon0 = readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET
+@@ -784,71 +776,46 @@ static void exynos_pinctrl_suspend_bank(
+ save->eint_mask = readl(regs + bank->irq_chip->eint_mask
+ + bank->eint_offset);
+
+- clk_disable(bank->drvdata->pclk);
+-
+ pr_debug("%s: save con %#010x\n", bank->name, save->eint_con);
+ pr_debug("%s: save fltcon0 %#010x\n", bank->name, save->eint_fltcon0);
+ pr_debug("%s: save fltcon1 %#010x\n", bank->name, save->eint_fltcon1);
+ pr_debug("%s: save mask %#010x\n", bank->name, save->eint_mask);
+ }
+
+-static void exynosauto_pinctrl_suspend_bank(struct samsung_pinctrl_drv_data *drvdata,
+- struct samsung_pin_bank *bank)
++static void exynosauto_pinctrl_suspend_bank(struct samsung_pin_bank *bank)
+ {
+ struct exynos_eint_gpio_save *save = bank->soc_priv;
+ const void __iomem *regs = bank->eint_base;
+
+- if (clk_enable(bank->drvdata->pclk)) {
+- dev_err(bank->gpio_chip.parent,
+- "unable to enable clock for saving state\n");
+- return;
+- }
+-
+ save->eint_con = readl(regs + bank->pctl_offset + bank->eint_con_offset);
+ save->eint_mask = readl(regs + bank->pctl_offset + bank->eint_mask_offset);
+
+- clk_disable(bank->drvdata->pclk);
+-
+ pr_debug("%s: save con %#010x\n", bank->name, save->eint_con);
+ pr_debug("%s: save mask %#010x\n", bank->name, save->eint_mask);
+ }
+
+-void exynos_pinctrl_suspend(struct samsung_pinctrl_drv_data *drvdata)
++void exynos_pinctrl_suspend(struct samsung_pin_bank *bank)
+ {
+- struct samsung_pin_bank *bank = drvdata->pin_banks;
+ struct exynos_irq_chip *irq_chip = NULL;
+- int i;
+
+- for (i = 0; i < drvdata->nr_banks; ++i, ++bank) {
+- if (bank->eint_type == EINT_TYPE_GPIO) {
+- if (bank->eint_con_offset)
+- exynosauto_pinctrl_suspend_bank(drvdata, bank);
+- else
+- exynos_pinctrl_suspend_bank(drvdata, bank);
+- }
+- else if (bank->eint_type == EINT_TYPE_WKUP) {
+- if (!irq_chip) {
+- irq_chip = bank->irq_chip;
+- irq_chip->set_eint_wakeup_mask(drvdata,
+- irq_chip);
+- }
++ if (bank->eint_type == EINT_TYPE_GPIO) {
++ if (bank->eint_con_offset)
++ exynosauto_pinctrl_suspend_bank(bank);
++ else
++ exynos_pinctrl_suspend_bank(bank);
++ } else if (bank->eint_type == EINT_TYPE_WKUP) {
++ if (!irq_chip) {
++ irq_chip = bank->irq_chip;
++ irq_chip->set_eint_wakeup_mask(bank->drvdata, irq_chip);
+ }
+ }
+ }
+
+-static void exynos_pinctrl_resume_bank(
+- struct samsung_pinctrl_drv_data *drvdata,
+- struct samsung_pin_bank *bank)
++static void exynos_pinctrl_resume_bank(struct samsung_pin_bank *bank)
+ {
+ struct exynos_eint_gpio_save *save = bank->soc_priv;
+ void __iomem *regs = bank->eint_base;
+
+- if (clk_enable(bank->drvdata->pclk)) {
+- dev_err(bank->gpio_chip.parent,
+- "unable to enable clock for restoring state\n");
+- return;
+- }
+-
+ pr_debug("%s: con %#010x => %#010x\n", bank->name,
+ readl(regs + EXYNOS_GPIO_ECON_OFFSET
+ + bank->eint_offset), save->eint_con);
+@@ -870,22 +837,13 @@ static void exynos_pinctrl_resume_bank(
+ + 2 * bank->eint_offset + 4);
+ writel(save->eint_mask, regs + bank->irq_chip->eint_mask
+ + bank->eint_offset);
+-
+- clk_disable(bank->drvdata->pclk);
+ }
+
+-static void exynosauto_pinctrl_resume_bank(struct samsung_pinctrl_drv_data *drvdata,
+- struct samsung_pin_bank *bank)
++static void exynosauto_pinctrl_resume_bank(struct samsung_pin_bank *bank)
+ {
+ struct exynos_eint_gpio_save *save = bank->soc_priv;
+ void __iomem *regs = bank->eint_base;
+
+- if (clk_enable(bank->drvdata->pclk)) {
+- dev_err(bank->gpio_chip.parent,
+- "unable to enable clock for restoring state\n");
+- return;
+- }
+-
+ pr_debug("%s: con %#010x => %#010x\n", bank->name,
+ readl(regs + bank->pctl_offset + bank->eint_con_offset), save->eint_con);
+ pr_debug("%s: mask %#010x => %#010x\n", bank->name,
+@@ -894,21 +852,16 @@ static void exynosauto_pinctrl_resume_bank(struct samsung_pinctrl_drv_data *drvd
+ writel(save->eint_con, regs + bank->pctl_offset + bank->eint_con_offset);
+ writel(save->eint_mask, regs + bank->pctl_offset + bank->eint_mask_offset);
+
+- clk_disable(bank->drvdata->pclk);
+ }
+
+-void exynos_pinctrl_resume(struct samsung_pinctrl_drv_data *drvdata)
++void exynos_pinctrl_resume(struct samsung_pin_bank *bank)
+ {
+- struct samsung_pin_bank *bank = drvdata->pin_banks;
+- int i;
+-
+- for (i = 0; i < drvdata->nr_banks; ++i, ++bank)
+- if (bank->eint_type == EINT_TYPE_GPIO) {
+- if (bank->eint_con_offset)
+- exynosauto_pinctrl_resume_bank(drvdata, bank);
+- else
+- exynos_pinctrl_resume_bank(drvdata, bank);
+- }
++ if (bank->eint_type == EINT_TYPE_GPIO) {
++ if (bank->eint_con_offset)
++ exynosauto_pinctrl_resume_bank(bank);
++ else
++ exynos_pinctrl_resume_bank(bank);
++ }
+ }
+
+ static void exynos_retention_enable(struct samsung_pinctrl_drv_data *drvdata)
+diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.h b/drivers/pinctrl/samsung/pinctrl-exynos.h
+index b483270ddc53c..341155c1abd15 100644
+--- a/drivers/pinctrl/samsung/pinctrl-exynos.h
++++ b/drivers/pinctrl/samsung/pinctrl-exynos.h
+@@ -240,8 +240,8 @@ struct exynos_muxed_weint_data {
+
+ int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d);
+ int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d);
+-void exynos_pinctrl_suspend(struct samsung_pinctrl_drv_data *drvdata);
+-void exynos_pinctrl_resume(struct samsung_pinctrl_drv_data *drvdata);
++void exynos_pinctrl_suspend(struct samsung_pin_bank *bank);
++void exynos_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);
+diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c
+index 2896eb2de2c09..ef557217e173a 100644
+--- a/drivers/pinctrl/samsung/pinctrl-samsung.c
++++ b/drivers/pinctrl/samsung/pinctrl-samsung.c
+@@ -1333,6 +1333,7 @@ static int samsung_pinctrl_probe(struct platform_device *pdev)
+ static int __maybe_unused samsung_pinctrl_suspend(struct device *dev)
+ {
+ struct samsung_pinctrl_drv_data *drvdata = dev_get_drvdata(dev);
++ struct samsung_pin_bank *bank;
+ int i;
+
+ i = clk_enable(drvdata->pclk);
+@@ -1343,7 +1344,7 @@ static int __maybe_unused samsung_pinctrl_suspend(struct device *dev)
+ }
+
+ for (i = 0; i < drvdata->nr_banks; i++) {
+- struct samsung_pin_bank *bank = &drvdata->pin_banks[i];
++ bank = &drvdata->pin_banks[i];
+ const void __iomem *reg = bank->pctl_base + bank->pctl_offset;
+ const u8 *offs = bank->type->reg_offset;
+ const u8 *widths = bank->type->fld_width;
+@@ -1371,10 +1372,14 @@ static int __maybe_unused samsung_pinctrl_suspend(struct device *dev)
+ }
+ }
+
++ for (i = 0; i < drvdata->nr_banks; i++) {
++ bank = &drvdata->pin_banks[i];
++ if (drvdata->suspend)
++ drvdata->suspend(bank);
++ }
++
+ clk_disable(drvdata->pclk);
+
+- if (drvdata->suspend)
+- drvdata->suspend(drvdata);
+ if (drvdata->retention_ctrl && drvdata->retention_ctrl->enable)
+ drvdata->retention_ctrl->enable(drvdata);
+
+@@ -1392,6 +1397,7 @@ static int __maybe_unused samsung_pinctrl_suspend(struct device *dev)
+ static int __maybe_unused samsung_pinctrl_resume(struct device *dev)
+ {
+ struct samsung_pinctrl_drv_data *drvdata = dev_get_drvdata(dev);
++ struct samsung_pin_bank *bank;
+ int ret;
+ int i;
+
+@@ -1406,11 +1412,14 @@ static int __maybe_unused samsung_pinctrl_resume(struct device *dev)
+ return ret;
+ }
+
+- if (drvdata->resume)
+- drvdata->resume(drvdata);
++ for (i = 0; i < drvdata->nr_banks; i++) {
++ bank = &drvdata->pin_banks[i];
++ if (drvdata->resume)
++ drvdata->resume(bank);
++ }
+
+ for (i = 0; i < drvdata->nr_banks; i++) {
+- struct samsung_pin_bank *bank = &drvdata->pin_banks[i];
++ bank = &drvdata->pin_banks[i];
+ void __iomem *reg = bank->pctl_base + bank->pctl_offset;
+ const u8 *offs = bank->type->reg_offset;
+ const u8 *widths = bank->type->fld_width;
+diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.h b/drivers/pinctrl/samsung/pinctrl-samsung.h
+index 3cf758df7d691..fcc57c244d167 100644
+--- a/drivers/pinctrl/samsung/pinctrl-samsung.h
++++ b/drivers/pinctrl/samsung/pinctrl-samsung.h
+@@ -285,8 +285,8 @@ struct samsung_pin_ctrl {
+ int (*eint_gpio_init)(struct samsung_pinctrl_drv_data *);
+ int (*eint_wkup_init)(struct samsung_pinctrl_drv_data *);
+ void (*pud_value_init)(struct samsung_pinctrl_drv_data *drvdata);
+- void (*suspend)(struct samsung_pinctrl_drv_data *);
+- void (*resume)(struct samsung_pinctrl_drv_data *);
++ void (*suspend)(struct samsung_pin_bank *bank);
++ void (*resume)(struct samsung_pin_bank *bank);
+ };
+
+ /**
+@@ -335,8 +335,8 @@ struct samsung_pinctrl_drv_data {
+
+ struct samsung_retention_ctrl *retention_ctrl;
+
+- void (*suspend)(struct samsung_pinctrl_drv_data *);
+- void (*resume)(struct samsung_pinctrl_drv_data *);
++ void (*suspend)(struct samsung_pin_bank *bank);
++ void (*resume)(struct samsung_pin_bank *bank);
+ };
+
+ /**
+--
+2.39.5
+
do_change_type-refuse-to-operate-on-unmounted-not-ou.patch
genksyms-fix-enum-consts-from-a-reference-affecting-.patch
tools-power-turbostat-fix-amd-package-energy-reporti.patch
+pinctrl-samsung-refactor-drvdata-suspend-resume-call.patch
+pinctrl-samsung-add-dedicated-soc-eint-suspend-resum.patch
+pinctrl-samsung-add-gs101-specific-eint-suspend-resu.patch