diff --git a/drivers/platform/x86/amd/pmc/pmc.c b/drivers/platform/x86/amd/pmc/pmc.c index d5b543f74a22..b09512368877 100644 --- a/drivers/platform/x86/amd/pmc/pmc.c +++ b/drivers/platform/x86/amd/pmc/pmc.c @@ -811,6 +811,20 @@ static bool amd_pmc_intermediate_wakeup_need_delay(struct amd_pmc_dev *pdev) static bool amd_pmc_want_suspend_delay(struct amd_pmc_dev *pdev) { + /* + * intermediate_wakeup implies that the machine didn't get to deepest sleep + * state before - otherwise this function isn't called in amd_pmc_s2idle_check() + * because amd_pmc_intermediate_wakeup_need_delay() returns true first. + * On some IdeaPads that happens when charging, because the EC seems + * to send lots of messages then that wake the machine. + * + * But even in that case, the sleep here is necessary (on those IdeaPads), + * otherwise they wake up completely (resume) after a few seconds. + * So this variable is only used to avoid spamming dmesg on each + * intermediate wakeup. + */ + bool intermediate_wakeup = !pdev->is_first_check_after_suspend; + /* * Some Lenovo Laptops (like different IdeaPad 3 Slims) need some * me-time before sleeping or they get uncooperative after waking @@ -829,17 +843,20 @@ static bool amd_pmc_want_suspend_delay(struct amd_pmc_dev *pdev) * disabled with disable_workarounds or delay_suspend=0 */ if (delay_suspend == 1 || (delay_suspend == -1 && !disable_workarounds)) { - dev_info(pdev->dev, "Delaying suspend by 2.5s to avoid platform bug\n"); + if (!intermediate_wakeup) + dev_info(pdev->dev, "Delaying suspend by 2.5s to avoid platform bug\n"); return true; } - dev_info(pdev->dev, "Not delaying suspend because of module parameter, even though your device is assumed to need it!\n"); + if (!intermediate_wakeup) + dev_info(pdev->dev, "Not delaying suspend because of module parameter, even though your device is assumed to need it!\n"); } else if (delay_suspend == 1) { - dev_info(pdev->dev, "Delaying suspend by 2.5s because delay_suspend=1. If this solves problems on your machine, please report this whole line to: platform-driver-x86@vger.kernel.org so it can be automatically detected as affected in the future. System Vendor: \"%s\" Product Name: \"%s\" Product Family: \"%s\" Board Vendor: \"%s\" Board Name: \"%s\"\n", - dmi_get_system_info(DMI_SYS_VENDOR), - dmi_get_system_info(DMI_PRODUCT_NAME), - dmi_get_system_info(DMI_PRODUCT_FAMILY), - dmi_get_system_info(DMI_BOARD_VENDOR), - dmi_get_system_info(DMI_BOARD_NAME)); + if (!intermediate_wakeup) + dev_info(pdev->dev, "Delaying suspend by 2.5s because delay_suspend=1. If this solves problems on your machine, please report this whole line to: platform-driver-x86@vger.kernel.org so it can be automatically detected as affected in the future. System Vendor: \"%s\" Product Name: \"%s\" Product Family: \"%s\" Board Vendor: \"%s\" Board Name: \"%s\"\n", + dmi_get_system_info(DMI_SYS_VENDOR), + dmi_get_system_info(DMI_PRODUCT_NAME), + dmi_get_system_info(DMI_PRODUCT_FAMILY), + dmi_get_system_info(DMI_BOARD_VENDOR), + dmi_get_system_info(DMI_BOARD_NAME)); return true; } return false; @@ -852,6 +869,9 @@ static void amd_pmc_s2idle_prepare(void) u8 msg; u32 arg = 1; + /* Reset this variable because this is a fresh suspend */ + pdev->is_first_check_after_suspend = true; + /* Reset and Start SMU logging - to monitor the s0i3 stats */ amd_pmc_setup_smu_logging(pdev); @@ -891,6 +911,9 @@ static void amd_pmc_s2idle_check(void) rc = amd_pmc_write_stb(pdev, AMD_PMC_STB_S2IDLE_CHECK); if (rc) dev_err(pdev->dev, "error writing to STB: %d\n", rc); + + /* remember that first check after suspend is done (until next prepare) */ + pdev->is_first_check_after_suspend = false; } static int amd_pmc_dump_data(struct amd_pmc_dev *pdev) diff --git a/drivers/platform/x86/amd/pmc/pmc.h b/drivers/platform/x86/amd/pmc/pmc.h index 5e7b8d5dc5d6..bea65810de5a 100644 --- a/drivers/platform/x86/amd/pmc/pmc.h +++ b/drivers/platform/x86/amd/pmc/pmc.h @@ -37,6 +37,7 @@ struct amd_pmc_dev { struct dentry *dbgfs_dir; struct quirk_entry *quirks; bool disable_8042_wakeup; + bool is_first_check_after_suspend; }; void amd_pmc_process_restore_quirks(struct amd_pmc_dev *dev);