mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 09:36:22 +02:00
rtc: interface: Add rtc_read_next_alarm() to read next expiring timer
Add a new function rtc_read_next_alarm() that reads the next expiring alarm from the RTC timerqueue. This is different from rtc_read_alarm(), which only reads the aie_timer. The wakealarm sysfs file programs the rtc->aie_timer, whereas the alarmtimer suspend routine programs its own timer into the RTC timerqueue. Both timers end up in the RTC's timerqueue, and the first expiring timer is what gets armed in the hardware. This new function allows code to query which alarm will actually fire next, regardless of which subsystem programmed it. This is needed by platform code that needs to program secondary timers based on the actual next wakeup time. Link: https://lore.kernel.org/all/87ed50z0le.ffs@tglx Suggested-by: Thomas Gleixner <tglx@linutronix.de> Assisted-by: Claude:claude-opus-4-6 Signed-off-by: Mario Limonciello <mario.limonciello@amd.com> Link: https://patch.msgid.link/20260521043714.1022930-2-mario.limonciello@amd.com Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
This commit is contained in:
parent
1afe4f19d6
commit
947d7ea6f6
|
|
@ -384,6 +384,46 @@ int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
|
|||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* rtc_read_next_alarm - read the next expiring alarm
|
||||
* @rtc: RTC device
|
||||
* @alarm: storage for the alarm information
|
||||
*
|
||||
* Read the next expiring alarm from the RTC timerqueue. This returns
|
||||
* the alarm that will actually fire next, which may be different from
|
||||
* rtc_read_alarm() if multiple timers are queued (e.g., alarmtimer
|
||||
* and wakealarm sysfs both active).
|
||||
*
|
||||
* Returns: 0 on success, -ENOENT if no alarm is pending, or other error.
|
||||
*/
|
||||
int rtc_read_next_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
|
||||
{
|
||||
struct timerqueue_node *next;
|
||||
int err;
|
||||
|
||||
if (!rtc || !alarm)
|
||||
return -EINVAL;
|
||||
|
||||
err = mutex_lock_interruptible(&rtc->ops_lock);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
next = timerqueue_getnext(&rtc->timerqueue);
|
||||
if (!next) {
|
||||
err = -ENOENT;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
memset(alarm, 0, sizeof(struct rtc_wkalrm));
|
||||
alarm->time = rtc_ktime_to_tm(next->expires);
|
||||
alarm->enabled = 1;
|
||||
|
||||
unlock:
|
||||
mutex_unlock(&rtc->ops_lock);
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rtc_read_next_alarm);
|
||||
|
||||
int rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
|
||||
{
|
||||
int err;
|
||||
|
|
|
|||
|
|
@ -190,6 +190,8 @@ extern int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm);
|
|||
int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm);
|
||||
extern int rtc_read_alarm(struct rtc_device *rtc,
|
||||
struct rtc_wkalrm *alrm);
|
||||
extern int rtc_read_next_alarm(struct rtc_device *rtc,
|
||||
struct rtc_wkalrm *alrm);
|
||||
extern int rtc_set_alarm(struct rtc_device *rtc,
|
||||
struct rtc_wkalrm *alrm);
|
||||
extern int rtc_initialize_alarm(struct rtc_device *rtc,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user