summaryrefslogtreecommitdiff
path: root/drivers/clocksource
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2025-03-26 13:30:27 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2025-03-26 13:30:27 -0700
commit1e1ba8d23dae91e6a9cfeb1236b02749e8a49ab3 (patch)
tree6bb1f481950adc71fb9bc659c0cb7e9c4a0e0212 /drivers/clocksource
parent87dc996d56b7871da02ea6047cd46bb879443974 (diff)
parentabfa6d6fe2e9539a6e080088a6e5762f4651017b (diff)
Merge tag 'timers-clocksource-2025-03-26' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull clocksource/event updates from Thomas Gleixner: - Add support for suspend/resume in the STM32 LP-Timer driver with a follow up fix, which uses the proper method to setup the timer as a optional wakeup source instead of trying to force it as mandatory wakeup source. - The usual device tree updates to enable new SoC models in existing drivers. - Trivial spelling, style and indentation fixes * tag 'timers-clocksource-2025-03-26' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: dt-bindings: timer: Add SiFive CLINT2 clocksource/drivers/stm32-lptimer: Use wakeup capable instead of init wakeup clocksource/drivers/exynos_mct: Fixed a spelling error clocksource/drivers/stm32-lptimer: Add support for suspend / resume dt-bindings: timer: exynos4210-mct: add samsung,exynos2200-mct-peris compatible dt-bindings: timer: exynos4210-mct: Add samsung,exynos990-mct compatible dt-bindings: timer: Correct indentation and style in DTS example
Diffstat (limited to 'drivers/clocksource')
-rw-r--r--drivers/clocksource/exynos_mct.c2
-rw-r--r--drivers/clocksource/timer-stm32-lp.c36
2 files changed, 31 insertions, 7 deletions
diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_mct.c
index e6a02e351d77..da09f467a6bb 100644
--- a/drivers/clocksource/exynos_mct.c
+++ b/drivers/clocksource/exynos_mct.c
@@ -238,7 +238,7 @@ static cycles_t exynos4_read_current_timer(void)
static int __init exynos4_clocksource_init(bool frc_shared)
{
/*
- * When the frc is shared, the main processer should have already
+ * When the frc is shared, the main processor should have already
* turned it on and we shouldn't be writing to TCON.
*/
if (frc_shared)
diff --git a/drivers/clocksource/timer-stm32-lp.c b/drivers/clocksource/timer-stm32-lp.c
index a4c95161cb22..928da2f6de69 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;
@@ -168,9 +194,7 @@ static int stm32_clkevent_lp_probe(struct platform_device *pdev)
}
if (of_property_read_bool(pdev->dev.parent->of_node, "wakeup-source")) {
- ret = device_init_wakeup(&pdev->dev, true);
- if (ret)
- goto out_clk_disable;
+ device_set_wakeup_capable(&pdev->dev, true);
ret = dev_pm_set_wake_irq(&pdev->dev, irq);
if (ret)
@@ -191,7 +215,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;
}