pinctrl: starfive: jh7110: Add system pm ops to save and restore context
authorHal Feng <hal.feng@starfivetech.com>
Tue, 5 Sep 2023 12:21:05 +0000 (20:21 +0800)
committerLinus Walleij <linus.walleij@linaro.org>
Tue, 12 Sep 2023 08:09:40 +0000 (10:09 +0200)
Add system pm ops to save and restore pinctrl registers
when suspending and resuming the driver, respectively.

Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
Link: https://lore.kernel.org/r/20230905122105.117000-3-hal.feng@starfivetech.com
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
MAINTAINERS
drivers/pinctrl/starfive/pinctrl-starfive-jh7110-aon.c
drivers/pinctrl/starfive/pinctrl-starfive-jh7110-sys.c
drivers/pinctrl/starfive/pinctrl-starfive-jh7110.c
drivers/pinctrl/starfive/pinctrl-starfive-jh7110.h

index 90f13281d29708439ba448d26308109a3cfd747b..cbc16ca7a1fa38200bec2c7f0d377a178536a23b 100644 (file)
@@ -20489,6 +20489,7 @@ F:      include/dt-bindings/clock/starfive?jh71*.h
 STARFIVE JH71X0 PINCTRL DRIVERS
 M:     Emil Renner Berthing <kernel@esmil.dk>
 M:     Jianlong Huang <jianlong.huang@starfivetech.com>
+M:     Hal Feng <hal.feng@starfivetech.com>
 L:     linux-gpio@vger.kernel.org
 S:     Maintained
 F:     Documentation/devicetree/bindings/pinctrl/starfive,jh71*.yaml
index 4bfe3aa57f8a55d03928a156f908977a57bd9c0d..cf42e204cbf01bb4cde3c866cfdd8dffb8eed66d 100644 (file)
@@ -31,6 +31,8 @@
 #define JH7110_AON_NGPIO               4
 #define JH7110_AON_GC_BASE             64
 
+#define JH7110_AON_REGS_NUM            37
+
 /* registers */
 #define JH7110_AON_DOEN                        0x0
 #define JH7110_AON_DOUT                        0x4
@@ -145,6 +147,7 @@ static const struct jh7110_pinctrl_soc_info jh7110_aon_pinctrl_info = {
        .gpi_mask       = GENMASK(3, 0),
        .gpioin_reg_base           = JH7110_AON_GPIOIN,
        .irq_reg                   = &jh7110_aon_irq_reg,
+       .nsaved_regs               = JH7110_AON_REGS_NUM,
        .jh7110_set_one_pin_mux  = jh7110_aon_set_one_pin_mux,
        .jh7110_get_padcfg_base  = jh7110_aon_get_padcfg_base,
        .jh7110_gpio_irq_handler = jh7110_aon_irq_handler,
@@ -165,6 +168,7 @@ static struct platform_driver jh7110_aon_pinctrl_driver = {
        .driver = {
                .name = "starfive-jh7110-aon-pinctrl",
                .of_match_table = jh7110_aon_pinctrl_of_match,
+               .pm = pm_sleep_ptr(&jh7110_pinctrl_pm_ops),
        },
 };
 module_platform_driver(jh7110_aon_pinctrl_driver);
index 20c85db1cd3ab4521bb73bd8ee244ae170f468ab..03c2ad808d61c65d3137ef73ad6a208ec8e6ddb7 100644 (file)
@@ -31,6 +31,8 @@
 #define JH7110_SYS_NGPIO               64
 #define JH7110_SYS_GC_BASE             0
 
+#define JH7110_SYS_REGS_NUM            174
+
 /* registers */
 #define JH7110_SYS_DOEN                        0x000
 #define JH7110_SYS_DOUT                        0x040
@@ -417,6 +419,7 @@ static const struct jh7110_pinctrl_soc_info jh7110_sys_pinctrl_info = {
        .gpi_mask       = GENMASK(6, 0),
        .gpioin_reg_base           = JH7110_SYS_GPIOIN,
        .irq_reg                   = &jh7110_sys_irq_reg,
+       .nsaved_regs               = JH7110_SYS_REGS_NUM,
        .jh7110_set_one_pin_mux  = jh7110_sys_set_one_pin_mux,
        .jh7110_get_padcfg_base  = jh7110_sys_get_padcfg_base,
        .jh7110_gpio_irq_handler = jh7110_sys_irq_handler,
@@ -437,6 +440,7 @@ static struct platform_driver jh7110_sys_pinctrl_driver = {
        .driver = {
                .name = "starfive-jh7110-sys-pinctrl",
                .of_match_table = jh7110_sys_pinctrl_of_match,
+               .pm = pm_sleep_ptr(&jh7110_pinctrl_pm_ops),
        },
 };
 module_platform_driver(jh7110_sys_pinctrl_driver);
index ac6a0abe5534abbf4dc16e9ac6fe8614214e8522..640f827a9b2ca6c0e9e05364b00e29874f0078d9 100644 (file)
@@ -872,6 +872,13 @@ int jh7110_pinctrl_probe(struct platform_device *pdev)
        if (!sfp)
                return -ENOMEM;
 
+#if IS_ENABLED(CONFIG_PM_SLEEP)
+       sfp->saved_regs = devm_kcalloc(dev, info->nsaved_regs,
+                                      sizeof(*sfp->saved_regs), GFP_KERNEL);
+       if (!sfp->saved_regs)
+               return -ENOMEM;
+#endif
+
        sfp->base = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(sfp->base))
                return PTR_ERR(sfp->base);
@@ -973,6 +980,39 @@ int jh7110_pinctrl_probe(struct platform_device *pdev)
 }
 EXPORT_SYMBOL_GPL(jh7110_pinctrl_probe);
 
+static int jh7110_pinctrl_suspend(struct device *dev)
+{
+       struct jh7110_pinctrl *sfp = dev_get_drvdata(dev);
+       unsigned long flags;
+       unsigned int i;
+
+       raw_spin_lock_irqsave(&sfp->lock, flags);
+       for (i = 0 ; i < sfp->info->nsaved_regs ; i++)
+               sfp->saved_regs[i] = readl_relaxed(sfp->base + 4 * i);
+
+       raw_spin_unlock_irqrestore(&sfp->lock, flags);
+       return 0;
+}
+
+static int jh7110_pinctrl_resume(struct device *dev)
+{
+       struct jh7110_pinctrl *sfp = dev_get_drvdata(dev);
+       unsigned long flags;
+       unsigned int i;
+
+       raw_spin_lock_irqsave(&sfp->lock, flags);
+       for (i = 0 ; i < sfp->info->nsaved_regs ; i++)
+               writel_relaxed(sfp->saved_regs[i], sfp->base + 4 * i);
+
+       raw_spin_unlock_irqrestore(&sfp->lock, flags);
+       return 0;
+}
+
+const struct dev_pm_ops jh7110_pinctrl_pm_ops = {
+       LATE_SYSTEM_SLEEP_PM_OPS(jh7110_pinctrl_suspend, jh7110_pinctrl_resume)
+};
+EXPORT_SYMBOL_GPL(jh7110_pinctrl_pm_ops);
+
 MODULE_DESCRIPTION("Pinctrl driver for the StarFive JH7110 SoC");
 MODULE_AUTHOR("Emil Renner Berthing <kernel@esmil.dk>");
 MODULE_AUTHOR("Jianlong Huang <jianlong.huang@starfivetech.com>");
index 3f20b7ff96dd85c605f543a90948ec54b2aae9c1..a33d0d4e13820d8ca3adfb6316ca496206562827 100644 (file)
@@ -21,6 +21,7 @@ struct jh7110_pinctrl {
        /* register read/write mutex */
        struct mutex mutex;
        const struct jh7110_pinctrl_soc_info *info;
+       u32 *saved_regs;
 };
 
 struct jh7110_gpio_irq_reg {
@@ -50,6 +51,8 @@ struct jh7110_pinctrl_soc_info {
 
        const struct jh7110_gpio_irq_reg *irq_reg;
 
+       unsigned int nsaved_regs;
+
        /* generic pinmux */
        int (*jh7110_set_one_pin_mux)(struct jh7110_pinctrl *sfp,
                                      unsigned int pin,
@@ -66,5 +69,6 @@ void jh7110_set_gpiomux(struct jh7110_pinctrl *sfp, unsigned int pin,
                        unsigned int din, u32 dout, u32 doen);
 int jh7110_pinctrl_probe(struct platform_device *pdev);
 struct jh7110_pinctrl *jh7110_from_irq_desc(struct irq_desc *desc);
+extern const struct dev_pm_ops jh7110_pinctrl_pm_ops;
 
 #endif /* __PINCTRL_STARFIVE_JH7110_H__ */