From: Mario Limonciello Date: Thu, 21 May 2026 04:37:14 +0000 (-0500) Subject: platform/x86: amd-pmc: Fix S0i3 wakeup with alarmtimer X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f7ecfc3fe5753d10e9c4d0d7955c160ea8cbf0ea;p=thirdparty%2Fkernel%2Fstable.git platform/x86: amd-pmc: Fix S0i3 wakeup with alarmtimer 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 Acked-by: Ilpo Järvinen Link: https://patch.msgid.link/20260521043714.1022930-3-mario.limonciello@amd.com Signed-off-by: Alexandre Belloni --- diff --git a/drivers/platform/x86/amd/pmc/pmc.c b/drivers/platform/x86/amd/pmc/pmc.c index cae3fcafd4d7b..07e51e051af33 100644 --- a/drivers/platform/x86/amd/pmc/pmc.c +++ b/drivers/platform/x86/amd/pmc/pmc.c @@ -567,9 +567,12 @@ static int amd_pmc_verify_czn_rtc(struct amd_pmc_dev *pdev, u32 *arg) 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;