[PATCH v3 03/12] rtc: rzn1: fix weekday underflow when alarm crosses month boundary
From: Prabhakar
Date: Mon Jul 06 2026 - 15:22:59 EST
From: Lad Prabhakar <prabhakar.mahadev-lad.rj@xxxxxxxxxxxxxx>
In rzn1_rtc_set_alarm(), the driver attempts to calculate the weekday
for an alarm by computing the day delta between the alarm time and the
current time:
days_ahead = tm->tm_mday - tm_now.tm_mday;
wday = (tm_now.tm_wday + days_ahead) % 7;
However, if an alarm is scheduled for the beginning of the next month
while the current time is at the end of the month (e.g., current day is
31, alarm day is 1), `tm->tm_mday - tm_now.tm_mday` results in a negative
value (-30). Since `days_ahead` is an unsigned int, this underflows to a
large positive number, leading to an incorrect `wday` being written to
the RZN1_RTC_ALW register. As a result, the alarm fails to fire.
Fix this by utilizing the already computed `alarm` time64_t timestamp.
Convert it back into an rtc_time struct via rtc_time64_to_tm(), which
automatically handles month boundaries and correctly populates the
`tm_wday` field.
Fixes: b5ad1bf00d2c4 ("rtc: rzn1: Add alarm support")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@xxxxxxxxxxxxxx>
---
v2->v3:
- New patch to fix weekday underflow when alarm crosses month boundary.
---
drivers/rtc/rtc-rzn1.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/rtc/rtc-rzn1.c b/drivers/rtc/rtc-rzn1.c
index aa27ad7f5941..3c83f95c18c4 100644
--- a/drivers/rtc/rtc-rzn1.c
+++ b/drivers/rtc/rtc-rzn1.c
@@ -260,7 +260,8 @@ static int rzn1_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
struct rzn1_rtc *rtc = dev_get_drvdata(dev);
struct rtc_time *tm = &alrm->time, tm_now;
unsigned long alarm, farest;
- unsigned int days_ahead, wday;
+ struct rtc_time alarm_tm;
+ unsigned int wday;
int ret;
ret = rzn1_rtc_read_time(dev, &tm_now);
@@ -274,8 +275,8 @@ static int rzn1_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
return -ERANGE;
/* Convert alarm day into week day */
- days_ahead = tm->tm_mday - tm_now.tm_mday;
- wday = (tm_now.tm_wday + days_ahead) % 7;
+ rtc_time64_to_tm(alarm, &alarm_tm);
+ wday = alarm_tm.tm_wday;
writel(bin2bcd(tm->tm_min), rtc->base + RZN1_RTC_ALM);
writel(bin2bcd(tm->tm_hour), rtc->base + RZN1_RTC_ALH);
--
2.54.0