It was reported that suspend-then-hibernate stopped working with modern
systemd versions on AMD Cezanne systems. The reason for this breakage
was because systemd switched to using alarmtimer instead of the wakealarm
sysfs file.
On AMD Cezanne systems, amd_pmc_verify_czn_rtc() programs a secondary
timer with the alarm time. This was introduced by
commit
59348401ebed ("platform/x86: amd-pmc: Add special handling for
timer based S0i3 wakeup"). However, this function uses rtc_read_alarm(),
which only reads the aie_timer, not the next expiring timer from the
timerqueue.
When both alarmtimer and wakealarm are active, the first expiring timer
might be the alarmtimer, but amd_pmc_verify_czn_rtc() would only see
the aie_timer, potentially missing the earlier alarm.
Switch to rtc_read_next_alarm() to read whichever timer will fire next.
Also handle -ENOENT (no alarm pending) explicitly as a non-error case.
Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/3591
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
Acked-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Link: https://patch.msgid.link/20260521043714.1022930-3-mario.limonciello@amd.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
rtc_device = rtc_class_open("rtc0");
if (!rtc_device)
return 0;
- rc = rtc_read_alarm(rtc_device, &alarm);
- if (rc)
- return rc;
+ rc = rtc_read_next_alarm(rtc_device, &alarm);
+ if (rc) {
+ if (rc == -ENOENT)
+ dev_dbg(pdev->dev, "no alarm pending\n");
+ return rc == -ENOENT ? 0 : rc;
+ }
if (!alarm.enabled) {
dev_dbg(pdev->dev, "alarm not enabled\n");
return 0;