* [PATCH] clocksource: stm32-lptimer: add support for PM
@ 2025-02-24 17:21 Fabrice Gasnier
2025-03-04 20:46 ` Daniel Lezcano
2025-03-25 8:14 ` [tip: timers/clocksource] clocksource/drivers/stm32-lptimer: Add support for suspend / resume tip-bot2 for Fabrice Gasnier
0 siblings, 2 replies; 3+ messages in thread
From: Fabrice Gasnier @ 2025-02-24 17:21 UTC (permalink / raw)
To: daniel.lezcano, tglx
Cc: alexandre.torgue, olivier.moysan, fabrice.gasnier, linux-kernel,
linux-arm-kernel, linux-stm32
Add support for power management on STM32 LPTIMER clocksource driver:
- Upon clockevents_suspend(), shutdown the LPTIMER, and balance the
clk_prepare_enable() from the probe routine.
- Upon clockevents_resume(), restore the prescaler that may have been lost
during low power mode, and restore the clock.
Signed-off-by: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
---
drivers/clocksource/timer-stm32-lp.c | 32 +++++++++++++++++++++++++---
1 file changed, 29 insertions(+), 3 deletions(-)
diff --git a/drivers/clocksource/timer-stm32-lp.c b/drivers/clocksource/timer-stm32-lp.c
index a4c95161cb22..9cd487dd5a3a 100644
--- a/drivers/clocksource/timer-stm32-lp.c
+++ b/drivers/clocksource/timer-stm32-lp.c
@@ -24,7 +24,9 @@ struct stm32_lp_private {
struct regmap *reg;
struct clock_event_device clkevt;
unsigned long period;
+ u32 psc;
struct device *dev;
+ struct clk *clk;
};
static struct stm32_lp_private*
@@ -120,6 +122,27 @@ static void stm32_clkevent_lp_set_prescaler(struct stm32_lp_private *priv,
/* Adjust rate and period given the prescaler value */
*rate = DIV_ROUND_CLOSEST(*rate, (1 << i));
priv->period = DIV_ROUND_UP(*rate, HZ);
+ priv->psc = i;
+}
+
+static void stm32_clkevent_lp_suspend(struct clock_event_device *clkevt)
+{
+ struct stm32_lp_private *priv = to_priv(clkevt);
+
+ stm32_clkevent_lp_shutdown(clkevt);
+
+ /* balance clk_prepare_enable() from the probe */
+ clk_disable_unprepare(priv->clk);
+}
+
+static void stm32_clkevent_lp_resume(struct clock_event_device *clkevt)
+{
+ struct stm32_lp_private *priv = to_priv(clkevt);
+
+ clk_prepare_enable(priv->clk);
+
+ /* restore prescaler */
+ regmap_write(priv->reg, STM32_LPTIM_CFGR, priv->psc << CFGR_PSC_OFFSET);
}
static void stm32_clkevent_lp_init(struct stm32_lp_private *priv,
@@ -134,6 +157,8 @@ static void stm32_clkevent_lp_init(struct stm32_lp_private *priv,
priv->clkevt.set_state_oneshot = stm32_clkevent_lp_set_oneshot;
priv->clkevt.set_next_event = stm32_clkevent_lp_set_next_event;
priv->clkevt.rating = STM32_LP_RATING;
+ priv->clkevt.suspend = stm32_clkevent_lp_suspend;
+ priv->clkevt.resume = stm32_clkevent_lp_resume;
clockevents_config_and_register(&priv->clkevt, rate, 0x1,
STM32_LPTIM_MAX_ARR);
@@ -151,11 +176,12 @@ static int stm32_clkevent_lp_probe(struct platform_device *pdev)
return -ENOMEM;
priv->reg = ddata->regmap;
- ret = clk_prepare_enable(ddata->clk);
+ priv->clk = ddata->clk;
+ ret = clk_prepare_enable(priv->clk);
if (ret)
return -EINVAL;
- rate = clk_get_rate(ddata->clk);
+ rate = clk_get_rate(priv->clk);
if (!rate) {
ret = -EINVAL;
goto out_clk_disable;
@@ -191,7 +217,7 @@ static int stm32_clkevent_lp_probe(struct platform_device *pdev)
return 0;
out_clk_disable:
- clk_disable_unprepare(ddata->clk);
+ clk_disable_unprepare(priv->clk);
return ret;
}
--
2.25.1
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: [PATCH] clocksource: stm32-lptimer: add support for PM
2025-02-24 17:21 [PATCH] clocksource: stm32-lptimer: add support for PM Fabrice Gasnier
@ 2025-03-04 20:46 ` Daniel Lezcano
2025-03-25 8:14 ` [tip: timers/clocksource] clocksource/drivers/stm32-lptimer: Add support for suspend / resume tip-bot2 for Fabrice Gasnier
1 sibling, 0 replies; 3+ messages in thread
From: Daniel Lezcano @ 2025-03-04 20:46 UTC (permalink / raw)
To: Fabrice Gasnier, tglx
Cc: alexandre.torgue, olivier.moysan, linux-kernel, linux-arm-kernel,
linux-stm32
On 24/02/2025 18:21, Fabrice Gasnier wrote:
> Add support for power management on STM32 LPTIMER clocksource driver:
> - Upon clockevents_suspend(), shutdown the LPTIMER, and balance the
> clk_prepare_enable() from the probe routine.
> - Upon clockevents_resume(), restore the prescaler that may have been lost
> during low power mode, and restore the clock.
>
> Signed-off-by: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
> ---
Applied, thanks
--
<http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs
Follow Linaro: <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog
^ permalink raw reply [flat|nested] 3+ messages in thread
* [tip: timers/clocksource] clocksource/drivers/stm32-lptimer: Add support for suspend / resume
2025-02-24 17:21 [PATCH] clocksource: stm32-lptimer: add support for PM Fabrice Gasnier
2025-03-04 20:46 ` Daniel Lezcano
@ 2025-03-25 8:14 ` tip-bot2 for Fabrice Gasnier
1 sibling, 0 replies; 3+ messages in thread
From: tip-bot2 for Fabrice Gasnier @ 2025-03-25 8:14 UTC (permalink / raw)
To: linux-tip-commits; +Cc: Fabrice Gasnier, Daniel Lezcano, x86, linux-kernel
The following commit has been merged into the timers/clocksource branch of tip:
Commit-ID: b5a497a7972a49c31d39b057f86dd6f58b882a72
Gitweb: https://git.kernel.org/tip/b5a497a7972a49c31d39b057f86dd6f58b882a72
Author: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
AuthorDate: Mon, 24 Feb 2025 18:21:01 +01:00
Committer: Daniel Lezcano <daniel.lezcano@linaro.org>
CommitterDate: Fri, 07 Mar 2025 17:55:59 +01:00
clocksource/drivers/stm32-lptimer: Add support for suspend / resume
Add support for power management on STM32 LPTIMER clocksource driver:
- Upon clockevents_suspend(), shutdown the LPTIMER, and balance the
clk_prepare_enable() from the probe routine.
- Upon clockevents_resume(), restore the prescaler that may have been lost
during low power mode, and restore the clock.
Signed-off-by: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
Link: https://lore.kernel.org/r/20250224172101.3448398-1-fabrice.gasnier@foss.st.com
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
drivers/clocksource/timer-stm32-lp.c | 32 ++++++++++++++++++++++++---
1 file changed, 29 insertions(+), 3 deletions(-)
diff --git a/drivers/clocksource/timer-stm32-lp.c b/drivers/clocksource/timer-stm32-lp.c
index a4c9516..9cd487d 100644
--- a/drivers/clocksource/timer-stm32-lp.c
+++ b/drivers/clocksource/timer-stm32-lp.c
@@ -24,7 +24,9 @@ struct stm32_lp_private {
struct regmap *reg;
struct clock_event_device clkevt;
unsigned long period;
+ u32 psc;
struct device *dev;
+ struct clk *clk;
};
static struct stm32_lp_private*
@@ -120,6 +122,27 @@ static void stm32_clkevent_lp_set_prescaler(struct stm32_lp_private *priv,
/* Adjust rate and period given the prescaler value */
*rate = DIV_ROUND_CLOSEST(*rate, (1 << i));
priv->period = DIV_ROUND_UP(*rate, HZ);
+ priv->psc = i;
+}
+
+static void stm32_clkevent_lp_suspend(struct clock_event_device *clkevt)
+{
+ struct stm32_lp_private *priv = to_priv(clkevt);
+
+ stm32_clkevent_lp_shutdown(clkevt);
+
+ /* balance clk_prepare_enable() from the probe */
+ clk_disable_unprepare(priv->clk);
+}
+
+static void stm32_clkevent_lp_resume(struct clock_event_device *clkevt)
+{
+ struct stm32_lp_private *priv = to_priv(clkevt);
+
+ clk_prepare_enable(priv->clk);
+
+ /* restore prescaler */
+ regmap_write(priv->reg, STM32_LPTIM_CFGR, priv->psc << CFGR_PSC_OFFSET);
}
static void stm32_clkevent_lp_init(struct stm32_lp_private *priv,
@@ -134,6 +157,8 @@ static void stm32_clkevent_lp_init(struct stm32_lp_private *priv,
priv->clkevt.set_state_oneshot = stm32_clkevent_lp_set_oneshot;
priv->clkevt.set_next_event = stm32_clkevent_lp_set_next_event;
priv->clkevt.rating = STM32_LP_RATING;
+ priv->clkevt.suspend = stm32_clkevent_lp_suspend;
+ priv->clkevt.resume = stm32_clkevent_lp_resume;
clockevents_config_and_register(&priv->clkevt, rate, 0x1,
STM32_LPTIM_MAX_ARR);
@@ -151,11 +176,12 @@ static int stm32_clkevent_lp_probe(struct platform_device *pdev)
return -ENOMEM;
priv->reg = ddata->regmap;
- ret = clk_prepare_enable(ddata->clk);
+ priv->clk = ddata->clk;
+ ret = clk_prepare_enable(priv->clk);
if (ret)
return -EINVAL;
- rate = clk_get_rate(ddata->clk);
+ rate = clk_get_rate(priv->clk);
if (!rate) {
ret = -EINVAL;
goto out_clk_disable;
@@ -191,7 +217,7 @@ static int stm32_clkevent_lp_probe(struct platform_device *pdev)
return 0;
out_clk_disable:
- clk_disable_unprepare(ddata->clk);
+ clk_disable_unprepare(priv->clk);
return ret;
}
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2025-03-25 8:14 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-02-24 17:21 [PATCH] clocksource: stm32-lptimer: add support for PM Fabrice Gasnier
2025-03-04 20:46 ` Daniel Lezcano
2025-03-25 8:14 ` [tip: timers/clocksource] clocksource/drivers/stm32-lptimer: Add support for suspend / resume tip-bot2 for Fabrice Gasnier
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®