Hi folks,
This series fixes support for correctly saving and restoring fltcon0 and fltcon1 registers on gs101 for non-alive banks where the fltcon register offset is not at a fixed offset (unlike previous SoCs). This is done by adding a eint_fltcon_offset and providing GS101 specific pin macros that take an additional parameter (similar to how exynosautov920 handles it's eint_con_offset).
Additionally the SoC specific suspend and resume callbacks are re-factored so that each SoC variant has it's own callback containing the peculiarities for that SoC.
Finally support for filter selection on alive banks is added, this is currently only enabled for gs101. The code path can be excercised using `echo mem > /sys/power/state`
regards,
Peter
To: Krzysztof Kozlowski krzk@kernel.org To: Sylwester Nawrocki s.nawrocki@samsung.com To: Alim Akhtar alim.akhtar@samsung.com To: Linus Walleij linus.walleij@linaro.org Cc: linux-arm-kernel@lists.infradead.org Cc: linux-samsung-soc@vger.kernel.org Cc: linux-gpio@vger.kernel.org Cc: linux-kernel@vger.kernel.org Cc: andre.draszik@linaro.org Cc: tudor.ambarus@linaro.org Cc: willmcvicker@google.com Cc: semen.protsenko@linaro.org Cc: kernel-team@android.com Cc: jaewon02.kim@samsung.com
Signed-off-by: Peter Griffin peter.griffin@linaro.org --- Changes in v6: - Make drvdata->suspend/resume symmetrically reversed (Krzysztof) - rebase on linux-next - Link to v5: https://lore.kernel.org/r/20250312-pinctrl-fltcon-suspend-v5-0-d98d5b271242@...
Changes in v5: - Split drvdata suspend & resume callbacks into a dedicated patch (Krzysztof) - Add comment about stable dependency (Krzysztof) - Add back in {} braces (Krzysztof) - Link to v4: https://lore.kernel.org/r/20250307-pinctrl-fltcon-suspend-v4-0-2d775e486036@...
Changes in v4: - save->eint_fltcon1 is an argument to pr_debug(), not readl() change alignment accordingly (Andre) - Link to v3: https://lore.kernel.org/r/20250306-pinctrl-fltcon-suspend-v3-0-f9ab4ff6a24e@...
Changes in v3: - Ensure EXYNOS_FLTCON_DIGITAL bit is cleared (Andre) - Make it obvious that exynos_eint_set_filter() is conditional on bank type (Andre) - Make it obvious exynos_set_wakeup() is conditional on bank type (Andre) - Align style where the '+' is placed first (Andre) - Remove unnecessary braces (Andre) - Link to v2: https://lore.kernel.org/r/20250301-pinctrl-fltcon-suspend-v2-0-a7eef9bb443b@...
Changes in v2: - Remove eint_flt_selectable bool as it can be deduced from EINT_TYPE_WKUP (Peter) - Move filter config register comment to header file (Andre) - Rename EXYNOS_FLTCON_DELAY to EXYNOS_FLTCON_ANALOG (Andre) - Remove misleading old comment (Andre) - Refactor exynos_eint_update_flt_reg() into a loop (Andre) - Split refactor of suspend/resume callbacks & gs101 parts into separate patches (Andre) - Link to v1: https://lore.kernel.org/r/20250120-pinctrl-fltcon-suspend-v1-0-e77900b2a854@...
--- Peter Griffin (4): pinctrl: samsung: refactor drvdata suspend & resume callbacks pinctrl: samsung: add dedicated SoC eint suspend/resume callbacks pinctrl: samsung: add gs101 specific eint suspend/resume callbacks pinctrl: samsung: Add filter selection support for alive bank on gs101
drivers/pinctrl/samsung/pinctrl-exynos-arm64.c | 52 ++--- drivers/pinctrl/samsung/pinctrl-exynos.c | 294 +++++++++++++++---------- drivers/pinctrl/samsung/pinctrl-exynos.h | 28 ++- drivers/pinctrl/samsung/pinctrl-samsung.c | 21 +- drivers/pinctrl/samsung/pinctrl-samsung.h | 8 +- 5 files changed, 252 insertions(+), 151 deletions(-) --- base-commit: cd37a617b4bfb43f84dbbf8058317b487f5203ae change-id: 20250120-pinctrl-fltcon-suspend-2333a137c4d4
Best regards,
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 --- Changes since v2: * make it clear exynos_set_wakeup(bank) is conditional on bank type (Andre) * align style where the '+' is placed (Andre) * remove unnecessary braces (Andre) --- drivers/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 4b5d4e436a337ff13dee6ef740a1500eaf86cc12..9fd894729a7b87c3e144ff90921a1cadbde93d3d 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 18c327f7e313355c4aba72f49a79b1697244f1ba..0879684338c772e484174a94ac2c274cc7d932ed 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 3a771862b4b1762b32f9e067b011e80cfebb99d2..2bee52b61b9317ff79c618c1dc53e98242805087 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);
linux-stable-mirror@lists.linaro.org