On Sat, 9 May 2026, Daniel Gibson wrote: > Some IdeaPad Slim 3 devices and similar with AMD CPUs have a > nonfunctional keyboard and lid switch after s2idle. > It helps to delay suspend by 2.5 seconds so the EC has some time > to do whatever it needs to get done before suspend - unfortunately > at least on my 16ABR8 waking it with a timer (wakealarm) still > triggers the issue, but at least normal resume via keypress or > lid works fine. > > This issue has been reported for many different devices, this patch > has been tested with the Zen3-based IdeaPad Slim 3 16ABR8 (82XR) > and the Zen3+-based IdeaPad Slim 3 14ARP10 (83K6). > > Reported-by: Sindre Henriksen > Closes: https://bugzilla.kernel.org/show_bug.cgi?id=221383 Cc: stable@vger.kernel.org would be warranted for this. > Tested-by: Sindre Henriksen > Suggested-by: Mario Limonciello (AMD) > Reviewed-by: Mario Limonciello (AMD) > Signed-off-by: Daniel Gibson > --- > drivers/platform/x86/amd/pmc/pmc-quirks.c | 31 +++++++++++++++++++++++ > drivers/platform/x86/amd/pmc/pmc.c | 24 +++++++++++++++++- > drivers/platform/x86/amd/pmc/pmc.h | 1 + > 3 files changed, 55 insertions(+), 1 deletion(-) > > diff --git a/drivers/platform/x86/amd/pmc/pmc-quirks.c b/drivers/platform/x86/amd/pmc/pmc-quirks.c > index 24506e342943..842a8f442fb5 100644 > --- a/drivers/platform/x86/amd/pmc/pmc-quirks.c > +++ b/drivers/platform/x86/amd/pmc/pmc-quirks.c > @@ -18,6 +18,7 @@ > struct quirk_entry { > u32 s2idle_bug_mmio; > bool spurious_8042; > + bool need_suspend_delay; > }; > > static struct quirk_entry quirk_s2idle_bug = { > @@ -33,6 +34,10 @@ static struct quirk_entry quirk_s2idle_spurious_8042 = { > .spurious_8042 = true, > }; > > +static struct quirk_entry quirk_s2idle_need_suspend_delay = { > + .need_suspend_delay = true, > +}; > + > static const struct dmi_system_id fwbug_list[] = { > { > .ident = "L14 Gen2 AMD", > @@ -203,6 +208,27 @@ static const struct dmi_system_id fwbug_list[] = { > DMI_MATCH(DMI_PRODUCT_NAME, "82XQ"), > } > }, > + /* https://bugzilla.kernel.org/show_bug.cgi?id=221383 */ > + { > + .ident = "Zen3-based IdeaPad Slim and similar", > + .driver_data = &quirk_s2idle_need_suspend_delay, > + .matches = { > + DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), > + /* > + * Note: there are also some Zen2-based 82X* devices that > + * need different quirks, they're already handled above > + */ > + DMI_MATCH(DMI_PRODUCT_NAME, "82X"), > + } > + }, > + { > + .ident = "Zen3+-based IdeaPad Slim and similar", > + .driver_data = &quirk_s2idle_need_suspend_delay, > + .matches = { > + DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), > + DMI_MATCH(DMI_PRODUCT_NAME, "83K"), > + } > + }, > /* https://bugzilla.kernel.org/show_bug.cgi?id=221273 */ > { > .ident = "Thinkpad L14 Gen3", > @@ -356,6 +382,11 @@ void amd_pmc_process_restore_quirks(struct amd_pmc_dev *dev) > amd_pmc_skip_nvme_smi_handler(dev->quirks->s2idle_bug_mmio); > } > > +bool amd_pmc_quirk_need_suspend_delay(struct amd_pmc_dev *dev) > +{ > + return dev->quirks && dev->quirks->need_suspend_delay; > +} > + > void amd_pmc_quirks_init(struct amd_pmc_dev *dev) > { > const struct dmi_system_id *dmi_id; > diff --git a/drivers/platform/x86/amd/pmc/pmc.c b/drivers/platform/x86/amd/pmc/pmc.c > index 2b9e5730170a..6bafd8661d68 100644 > --- a/drivers/platform/x86/amd/pmc/pmc.c > +++ b/drivers/platform/x86/amd/pmc/pmc.c > @@ -611,6 +611,27 @@ static bool amd_pmc_intermediate_wakeup_need_delay(struct amd_pmc_dev *pdev) > return get_metrics_table(pdev, &table) == 0 && table.s0i3_last_entry_status; > } > > +static bool amd_pmc_want_suspend_delay(struct amd_pmc_dev *pdev) > +{ > + /* > + * Some Lenovo Laptops (like different IdeaPad 3 Slims) need some > + * me-time before sleeping or they get uncooperative after waking > + * up and don't send events for keyboard and lid switch anymore. > + * > + * Unfortunately this doesn't entirely fix the problem: It can still > + * happen when resuming with a timer (wakealarm), but at least the > + * more common usecases (wakeup by opening lid or pressing a key) > + * work fine with this workaround. > + * > + * See https://bugzilla.kernel.org/show_bug.cgi?id=221383 > + */ > + if (!disable_workarounds && amd_pmc_quirk_need_suspend_delay(pdev)) { > + dev_info(pdev->dev, "Delaying suspend by 2.5s to avoid platform bug\n"); > + return true; > + } > + return false; > +} > + > static void amd_pmc_s2idle_prepare(void) > { > struct amd_pmc_dev *pdev = &pmc; > @@ -647,7 +668,8 @@ static void amd_pmc_s2idle_check(void) > struct amd_pmc_dev *pdev = &pmc; > int rc; > > - if (amd_pmc_intermediate_wakeup_need_delay(pdev)) > + if (amd_pmc_intermediate_wakeup_need_delay(pdev) || > + amd_pmc_want_suspend_delay(pdev)) Thanks, this looks much cleaner. :-) Reviewed-by: Ilpo Järvinen > msleep(2500); > > /* Dump the IdleMask before we add to the STB */ > diff --git a/drivers/platform/x86/amd/pmc/pmc.h b/drivers/platform/x86/amd/pmc/pmc.h > index fe3f53eb5955..f5257e47b8c4 100644 > --- a/drivers/platform/x86/amd/pmc/pmc.h > +++ b/drivers/platform/x86/amd/pmc/pmc.h > @@ -147,6 +147,7 @@ enum amd_pmc_def { > }; > > void amd_pmc_process_restore_quirks(struct amd_pmc_dev *dev); > +bool amd_pmc_quirk_need_suspend_delay(struct amd_pmc_dev *dev); > void amd_pmc_quirks_init(struct amd_pmc_dev *dev); > void amd_mp2_stb_init(struct amd_pmc_dev *dev); > void amd_mp2_stb_deinit(struct amd_pmc_dev *dev); > -- i.