[PATCH 2/5] clocksource: timer-cadence-ttc: Allow deferred probing
From: Meher Thanmaiee
Date: Wed Oct 07 2026 - 06:34:06 EST
Switch from builtin_platform_driver_probe() to builtin_platform_driver()
to support deferred probing. The existing timer probe path calls
of_clk_get(), which can return -EPROBE_DEFER when the clock provider is
not yet available. builtin_platform_driver_probe() discards the probe
callback after init and cannot retry probing, so switch to
builtin_platform_driver(), which keeps it available. This requires
removing the __init annotations from ttc_timer_probe(),
ttc_setup_clocksource(), and ttc_setup_clockevent().
Move the initialized flag assignment to after clocksource and
clockevent registration succeeds so that a retried probe does not see
initialized = true and return early before the timer is configured.
Signed-off-by: Meher Thanmaiee <meherthanmaiee.vanukuri@xxxxxxx>
---
drivers/clocksource/timer-cadence-ttc.c | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/drivers/clocksource/timer-cadence-ttc.c b/drivers/clocksource/timer-cadence-ttc.c
index 8be13d344007..75bc0af1fa9e 100644
--- a/drivers/clocksource/timer-cadence-ttc.c
+++ b/drivers/clocksource/timer-cadence-ttc.c
@@ -312,8 +312,8 @@ static int ttc_rate_change_clocksource_cb(struct notifier_block *nb,
return NOTIFY_DONE;
}
-static int __init ttc_setup_clocksource(struct clk *clk, void __iomem *base,
- u32 timer_width)
+static int ttc_setup_clocksource(struct clk *clk, void __iomem *base,
+ u32 timer_width)
{
struct ttc_timer_clocksource *ttccs;
int err;
@@ -395,8 +395,8 @@ static int ttc_rate_change_clockevent_cb(struct notifier_block *nb,
}
}
-static int __init ttc_setup_clockevent(struct clk *clk,
- void __iomem *base, u32 irq)
+static int ttc_setup_clockevent(struct clk *clk,
+ void __iomem *base, u32 irq)
{
struct ttc_timer_clockevent *ttcce;
int err;
@@ -463,7 +463,7 @@ static int __init ttc_setup_clockevent(struct clk *clk,
return err;
}
-static int __init ttc_timer_probe(struct platform_device *pdev)
+static int ttc_timer_probe(struct platform_device *pdev)
{
unsigned int irq;
void __iomem *timer_baseaddr;
@@ -476,8 +476,6 @@ static int __init ttc_timer_probe(struct platform_device *pdev)
if (initialized)
return 0;
- initialized = 1;
-
/*
* Get the 1st Triple Timer Counter (TTC) block from the device tree
* and use it. Note that the event timer uses the interrupt and it's the
@@ -522,6 +520,8 @@ static int __init ttc_timer_probe(struct platform_device *pdev)
if (ret)
goto put_clk_ce;
+ initialized = 1;
+
pr_info("%pOFn #0 at %p, irq=%d\n", timer, timer_baseaddr, irq);
return 0;
@@ -541,9 +541,10 @@ static const struct of_device_id ttc_timer_of_match[] = {
MODULE_DEVICE_TABLE(of, ttc_timer_of_match);
static struct platform_driver ttc_timer_driver = {
+ .probe = ttc_timer_probe,
.driver = {
.name = "cdns_ttc_timer",
.of_match_table = ttc_timer_of_match,
},
};
-builtin_platform_driver_probe(ttc_timer_driver, ttc_timer_probe);
+builtin_platform_driver(ttc_timer_driver);
--
2.34.1