Commit 64061b67 authored by Hal Feng's avatar Hal Feng Committed by Linus Walleij
Browse files

pinctrl: starfive: jh7110: Add system pm ops to save and restore context



Add system pm ops to save and restore pinctrl registers
when suspending and resuming the driver, respectively.

Signed-off-by: default avatarHal Feng <hal.feng@starfivetech.com>
Link: https://lore.kernel.org/r/20230905122105.117000-3-hal.feng@starfivetech.com


Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
parent 8406d6b5
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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
+4 −0
Original line number Diff line number Diff line
@@ -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);
+4 −0
Original line number Diff line number Diff line
@@ -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);
+40 −0
Original line number Diff line number Diff line
@@ -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>");
+4 −0
Original line number Diff line number Diff line
@@ -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__ */