[PATCH] clocksource/drivers/atmel-st: Fix sclk reference leak in error paths
From: Wentao Liang
Date: Tue Sep 15 2026 - 00:52:31 EST
atmel_st_timer_init() obtains the slow clock with of_clk_get() but never
releases the reference on error. If clk_prepare_enable() fails the
reference is leaked directly, and if the clock rate is invalid or
clocksource_register_hz() fails the error paths return without disabling
or putting the already enabled clock.
Add the missing cleanup to the three error paths: clk_put() when
prepare+enable fails, and clk_disable_unprepare() followed by clk_put()
when aborting after the clock has been enabled. The success path keeps
the slow clock enabled for the lifetime of the system timer and is left
untouched.
Fixes: adbaf5254152 ("clocksource/drivers/atmel-st: Convert init function to return error")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Wentao Liang <vulab@xxxxxxxxxxx>
---
drivers/clocksource/timer-atmel-st.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/drivers/clocksource/timer-atmel-st.c b/drivers/clocksource/timer-atmel-st.c
index 73e8aee445da..e333916f8236 100644
--- a/drivers/clocksource/timer-atmel-st.c
+++ b/drivers/clocksource/timer-atmel-st.c
@@ -222,12 +222,15 @@ static int __init atmel_st_timer_init(struct device_node *node)
ret = clk_prepare_enable(sclk);
if (ret) {
pr_err("Could not enable slow clock\n");
+ clk_put(sclk);
return ret;
}
sclk_rate = clk_get_rate(sclk);
if (!sclk_rate) {
pr_err("Invalid slow clock rate\n");
+ clk_disable_unprepare(sclk);
+ clk_put(sclk);
return -EINVAL;
}
timer_latch = (sclk_rate + HZ / 2) / HZ;
@@ -244,7 +247,14 @@ static int __init atmel_st_timer_init(struct device_node *node)
2, AT91_ST_ALMV);
/* register clocksource */
- return clocksource_register_hz(&clk32k, sclk_rate);
+ ret = clocksource_register_hz(&clk32k, sclk_rate);
+ if (ret) {
+ clk_disable_unprepare(sclk);
+ clk_put(sclk);
+ return ret;
+ }
+
+ return 0;
}
TIMER_OF_DECLARE(atmel_st_timer, "atmel,at91rm9200-st",
atmel_st_timer_init);
--
2.34.1