[PATCH] rtc: ftrtc010: fix negative offset handling and smatch warning
From: Liu Dalin
Date: Thu Oct 08 2026 - 07:39:08 EST
A prior attempted to fix the 32-bit arithmetic overflow by turning
the implicit u32-to-timeu64_t cast into an explicit one. However,
all calculations still happen in u32, inheriting the existing
negative offset sign-extension bug, and the explicit cast triggers
smatch "cast after binop" warning.
The FTRTC010 RECORD register stores a signed 32-bit two's complement
offset exposed through readl() as a u32. Casting the whole u32
expression result to timeu64_t performs zero extension, so negative
offsets become huge positive values.
Fix it by casting offset to s32 first to correctly interpret the
two's complement sign, then promote all operands to timeu64_t so all
calculations are done in 64-bit space. days/hour/min/sec are
non-negative hardware counters, so promoting them directly to
timeu64_t is safe.
Fixes: 1d61d2592c1f ("rtc: gemini/ftrtc010: rename driver and symbols")
Signed-off-by: Liu Dalin <liudalin@xxxxxxxxxxxxxxx>
---
drivers/rtc/rtc-ftrtc010.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/rtc/rtc-ftrtc010.c b/drivers/rtc/rtc-ftrtc010.c
index b29c96be40f4..65fe1e872239 100644
--- a/drivers/rtc/rtc-ftrtc010.c
+++ b/drivers/rtc/rtc-ftrtc010.c
@@ -72,7 +72,8 @@ static int ftrtc010_rtc_read_time(struct device *dev, struct rtc_time *tm)
days = readl(rtc->rtc_base + FTRTC010_RTC_DAYS);
offset = readl(rtc->rtc_base + FTRTC010_RTC_RECORD);
- time = (timeu64_t)(offset + days * 86400 + hour * 3600 + min * 60 + sec);
+ time = (timeu64_t)(s32)offset + (timeu64_t)days * 86400 +
+ (timeu64_t)hour * 3600 + (timeu64_t)min * 60 + (timeu64_t)sec;
rtc_time64_to_tm(time, tm);
--
2.43.0