mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] rtc: Don't lose a minute-resolution alarm that rounds down into the past
@ 2026-11-10  7:13 Arun Iyengar via B4 Relay
  2026-11-10  7:48 ` Alexandre Belloni
  0 siblings, 1 reply; 2+ messages in thread
From: Arun Iyengar via B4 Relay @ 2026-11-10  7:13 UTC (permalink / raw)
  To: Alexandre Belloni; +Cc: linux-rtc, linux-kernel, stable

From: Arun Iyengar <aiyengar1990@gmail.com>

For an RTC with RTC_FEATURE_ALARM_RES_MINUTE, rtc_set_alarm() rounds the
alarm down to the start of its minute, so that it never fires late. When
the alarm is less than a minute away and in the same minute as the
current time, the rounded time is already in the past.
rtc_timer_enqueue() then gets -ETIME from __rtc_set_alarm() and expires
the timer from the irq work right away, and the hardware alarm is never
armed.

That loses every short wake alarm. With a HYM8563, which has minute
resolution, "rtcwake -m freeze -s 15" sets an alarm that expires in
software before the system suspends, so nothing wakes it: with the
alarm set at 17:55:00 for 17:55:17, /proc/driver/rtc reads back
"alrm_time: 17:55:00, alarm_IRQ: no", and the system stays in
suspend-to-idle until something else wakes it.

Round the alarm up to the next minute when rounding down would put an
alarm that is still in the future into the past. It then fires at most
59 seconds late instead of never. Alarms that are already in the past,
or that round down to a time still in the future, are handled as before.

Fixes: d87f741dddab ("rtc: handle alarms with a minute resolution")
Cc: stable@vger.kernel.org
Signed-off-by: Arun Iyengar <aiyengar1990@gmail.com>
---
Tested on an Orange Pi 5 (RK3588S) with a HYM8563: "rtcwake -m no -s 15"
now reads back the alarm at the next full minute with "alarm_IRQ: yes",
and 47 consecutive "rtcwake -m freeze -s 15" cycles all woke from the
RTC interrupt. Before the fix the alarm was lost whenever the 15 s
stayed inside the current minute, and the system never woke.

This patch was developed with Claude (Anthropic) as a coding assistant:
it wrote the code and the commit message, and I reviewed and tested it
as described above.
---
 drivers/rtc/interface.c | 33 +++++++++++++++++++++++++++------
 1 file changed, 27 insertions(+), 6 deletions(-)

diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c
index 96626f8068f9..004819c9a846 100644
--- a/drivers/rtc/interface.c
+++ b/drivers/rtc/interface.c
@@ -535,18 +535,39 @@ int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
 		rtc_timer_remove(rtc, &rtc->aie_timer);
 
 	alarm_time = rtc_tm_to_ktime(alarm->time);
-	/*
-	 * Round down so we never miss a deadline, checking for past deadline is
-	 * done in __rtc_set_alarm
-	 */
-	if (test_bit(RTC_FEATURE_ALARM_RES_MINUTE, rtc->features))
-		alarm_time = ktime_sub_ns(alarm_time, (u64)alarm->time.tm_sec * NSEC_PER_SEC);
+	if (test_bit(RTC_FEATURE_ALARM_RES_MINUTE, rtc->features) &&
+	    alarm->time.tm_sec) {
+		ktime_t down = ktime_sub_ns(alarm_time,
+					    (u64)alarm->time.tm_sec * NSEC_PER_SEC);
+		struct rtc_time tm;
+		ktime_t now;
+
+		err = __rtc_read_time(rtc, &tm);
+		if (err)
+			goto unlock;
+		now = rtc_tm_to_ktime(tm);
+
+		/*
+		 * Round down so we never miss a deadline. If that puts an alarm
+		 * that is still in the future into the past, the timer would
+		 * expire right away and the hardware alarm would never be
+		 * armed: whoever relies on it, e.g. to wake the system from
+		 * suspend, would wait forever. Round up to the next minute
+		 * instead. An alarm already in the past is left alone, it is
+		 * handled by __rtc_set_alarm.
+		 */
+		if (ktime_after(down, now) || !ktime_after(alarm_time, now))
+			alarm_time = down;
+		else
+			alarm_time = ktime_add_ns(down, 60 * NSEC_PER_SEC);
+	}
 
 	rtc->aie_timer.node.expires = alarm_time;
 	rtc->aie_timer.period = 0;
 	if (alarm->enabled)
 		err = rtc_timer_enqueue(rtc, &rtc->aie_timer);
 
+unlock:
 	mutex_unlock(&rtc->ops_lock);
 
 	return err;

---
base-commit: 7485659ecb81d5fce3a3edf2cae9fcb29c17b1cd
change-id: 20261110-rtc-minute-alarm-1d8af9689d23

Best regards,
--  
Arun Iyengar <aiyengar1990@gmail.com>



^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] rtc: Don't lose a minute-resolution alarm that rounds down into the past
  2026-11-10  7:13 [PATCH] rtc: Don't lose a minute-resolution alarm that rounds down into the past Arun Iyengar via B4 Relay
@ 2026-11-10  7:48 ` Alexandre Belloni
  0 siblings, 0 replies; 2+ messages in thread
From: Alexandre Belloni @ 2026-11-10  7:48 UTC (permalink / raw)
  To: aiyengar1990; +Cc: linux-rtc, linux-kernel, stable

On 10/11/2026 07:13:47+0000, Arun Iyengar via B4 Relay wrote:
> From: Arun Iyengar <aiyengar1990@gmail.com>
> 
> For an RTC with RTC_FEATURE_ALARM_RES_MINUTE, rtc_set_alarm() rounds the
> alarm down to the start of its minute, so that it never fires late. When
> the alarm is less than a minute away and in the same minute as the
> current time, the rounded time is already in the past.
> rtc_timer_enqueue() then gets -ETIME from __rtc_set_alarm() and expires
> the timer from the irq work right away, and the hardware alarm is never
> armed.

This is the expected behaviour, userspace has to handle the error
properly: the alarm can't be set, set it for a later time or stop there
and don't suspend.

> 
> That loses every short wake alarm. With a HYM8563, which has minute
> resolution, "rtcwake -m freeze -s 15" sets an alarm that expires in
> software before the system suspends, so nothing wakes it: with the
> alarm set at 17:55:00 for 17:55:17, /proc/driver/rtc reads back
> "alrm_time: 17:55:00, alarm_IRQ: no", and the system stays in
> suspend-to-idle until something else wakes it.
> 
> Round the alarm up to the next minute when rounding down would put an
> alarm that is still in the future into the past. It then fires at most
> 59 seconds late instead of never. Alarms that are already in the past,
> or that round down to a time still in the future, are handled as before.

Never round up, you are going to miss deadlines.


-- 
Alexandre Belloni, co-owner and COO, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-11-10  7:48 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-10  7:13 [PATCH] rtc: Don't lose a minute-resolution alarm that rounds down into the past Arun Iyengar via B4 Relay
2026-11-10  7:48 ` Alexandre Belloni

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®