]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ACPI: TAD: RTC: Refine timer value computations and checks
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>
Wed, 22 Apr 2026 15:26:49 +0000 (17:26 +0200)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Mon, 27 Apr 2026 19:57:09 +0000 (21:57 +0200)
Since rtc_tm_to_ktime() may overflow for large RTC time values and
full second granularity is sufficient in timer value computations
in acpi_tad_rtc_set_alarm() and acpi_tad_rtc_read_alarm(), use
rtc_tm_to_time64() instead of that function, which also allows the
computations to be simplified.

Moreover, U32_MAX is a special "timer disabled" value, so make
acpi_tad_rtc_set_alarm() reject it when attempting to program the
alarm timers.

Fixes: 7572dcabe38d ("ACPI: TAD: Add alarm support to the RTC class device interface")
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Reviewed-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Link: https://patch.msgid.link/3414608.aeNJFYEL58@rafael.j.wysocki
drivers/acpi/acpi_tad.c

index 2aaef50a2d0fac87046c9db7168b1eb524246018..bdf8695c00f35dfe469d71c14984d60d9d251663 100644 (file)
@@ -680,9 +680,8 @@ static int acpi_tad_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *t)
 
                acpi_tad_rt_to_tm(&rt, &tm_now);
 
-               value = ktime_divns(ktime_sub(rtc_tm_to_ktime(t->time),
-                                             rtc_tm_to_ktime(tm_now)), NSEC_PER_SEC);
-               if (value <= 0 || value > U32_MAX)
+               value = rtc_tm_to_time64(&t->time) - rtc_tm_to_time64(&tm_now);
+               if (value <= 0 || value >= U32_MAX)
                        return -EINVAL;
        }
 
@@ -745,8 +744,7 @@ static int acpi_tad_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *t)
 
        if (retval != ACPI_TAD_WAKE_DISABLED) {
                t->enabled = 1;
-               t->time = rtc_ktime_to_tm(ktime_add_ns(rtc_tm_to_ktime(tm_now),
-                                                      (u64)retval * NSEC_PER_SEC));
+               rtc_time64_to_tm(rtc_tm_to_time64(&tm_now) + retval, &t->time);
        } else {
                t->enabled = 0;
                t->time = tm_now;