^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * sleep.c - ACPI sleep support.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 2005 Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (c) 2004 David Shaohua Li <shaohua.li@intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (c) 2000-2003 Patrick Mochel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright (c) 2003 Open Source Development Lab
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/dmi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/suspend.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/reboot.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/syscore_ops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <trace/events/power.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include "internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include "sleep.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * Some HW-full platforms do not have _S5, so they may need
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * to leverage efi power off for a shutdown.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) bool acpi_no_s5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) static u8 sleep_states[ACPI_S_STATE_COUNT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) static void acpi_sleep_tts_switch(u32 acpi_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) status = acpi_execute_simple_method(NULL, "\\_TTS", acpi_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * OS can't evaluate the _TTS object correctly. Some warning
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * message will be printed. But it won't break anything.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) printk(KERN_NOTICE "Failure in evaluating _TTS object\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) static int tts_notify_reboot(struct notifier_block *this,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) unsigned long code, void *x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) acpi_sleep_tts_switch(ACPI_STATE_S5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) return NOTIFY_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) static struct notifier_block tts_notifier = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) .notifier_call = tts_notify_reboot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) .next = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) .priority = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) static int acpi_sleep_prepare(u32 acpi_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #ifdef CONFIG_ACPI_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) unsigned long acpi_wakeup_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) /* do we have a wakeup address for S2 and S3? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) if (acpi_state == ACPI_STATE_S3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) acpi_wakeup_address = acpi_get_wakeup_address();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) if (!acpi_wakeup_address)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) acpi_set_waking_vector(acpi_wakeup_address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) ACPI_FLUSH_CPU_CACHE();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) printk(KERN_INFO PREFIX "Preparing to enter system sleep state S%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) acpi_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) acpi_enable_wakeup_devices(acpi_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) acpi_enter_sleep_state_prep(acpi_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) bool acpi_sleep_state_supported(u8 sleep_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) u8 type_a, type_b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) status = acpi_get_sleep_type_data(sleep_state, &type_a, &type_b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) return ACPI_SUCCESS(status) && (!acpi_gbl_reduced_hardware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) || (acpi_gbl_FADT.sleep_control.address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) && acpi_gbl_FADT.sleep_status.address));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #ifdef CONFIG_ACPI_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) static bool sleep_no_lps0 __read_mostly;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) module_param(sleep_no_lps0, bool, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) MODULE_PARM_DESC(sleep_no_lps0, "Do not use the special LPS0 device interface");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) static u32 acpi_target_sleep_state = ACPI_STATE_S0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) u32 acpi_target_system_state(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) return acpi_target_sleep_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) EXPORT_SYMBOL_GPL(acpi_target_system_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static bool pwr_btn_event_pending;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * The ACPI specification wants us to save NVS memory regions during hibernation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) * and to restore them during the subsequent resume. Windows does that also for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * suspend to RAM. However, it is known that this mechanism does not work on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) * all machines, so we allow the user to disable it with the help of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) * 'acpi_sleep=nonvs' kernel command line option.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) static bool nvs_nosave;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) void __init acpi_nvs_nosave(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) nvs_nosave = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) * The ACPI specification wants us to save NVS memory regions during hibernation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) * but says nothing about saving NVS during S3. Not all versions of Windows
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) * save NVS on S3 suspend either, and it is clear that not all systems need
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) * NVS to be saved at S3 time. To improve suspend/resume time, allow the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) * user to disable saving NVS on S3 if their system does not require it, but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) * continue to save/restore NVS for S4 as specified.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) static bool nvs_nosave_s3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) void __init acpi_nvs_nosave_s3(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) nvs_nosave_s3 = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) static int __init init_nvs_save_s3(const struct dmi_system_id *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) nvs_nosave_s3 = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * ACPI 1.0 wants us to execute _PTS before suspending devices, so we allow the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) * user to request that behavior by using the 'acpi_old_suspend_ordering'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) * kernel command line option that causes the following variable to be set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) static bool old_suspend_ordering;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) void __init acpi_old_suspend_ordering(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) old_suspend_ordering = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) static int __init init_old_suspend_ordering(const struct dmi_system_id *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) acpi_old_suspend_ordering();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) static int __init init_nvs_nosave(const struct dmi_system_id *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) acpi_nvs_nosave();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) static bool acpi_sleep_default_s3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) static int __init init_default_s3(const struct dmi_system_id *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) acpi_sleep_default_s3 = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) static const struct dmi_system_id acpisleep_dmi_table[] __initconst = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) .callback = init_old_suspend_ordering,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) .ident = "Abit KN9 (nForce4 variant)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) DMI_MATCH(DMI_BOARD_VENDOR, "http://www.abit.com.tw/"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) DMI_MATCH(DMI_BOARD_NAME, "KN9 Series(NF-CK804)"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) .callback = init_old_suspend_ordering,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) .ident = "HP xw4600 Workstation",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) DMI_MATCH(DMI_PRODUCT_NAME, "HP xw4600 Workstation"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) .callback = init_old_suspend_ordering,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) .ident = "Asus Pundit P1-AH2 (M2N8L motherboard)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTek Computer INC."),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) DMI_MATCH(DMI_BOARD_NAME, "M2N8L"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) .callback = init_old_suspend_ordering,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) .ident = "Panasonic CF51-2L",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) DMI_MATCH(DMI_BOARD_VENDOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) "Matsushita Electric Industrial Co.,Ltd."),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) DMI_MATCH(DMI_BOARD_NAME, "CF51-2L"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) .callback = init_nvs_nosave,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) .ident = "Sony Vaio VGN-FW41E_H",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FW41E_H"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) .callback = init_nvs_nosave,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) .ident = "Sony Vaio VGN-FW21E",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FW21E"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) .callback = init_nvs_nosave,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) .ident = "Sony Vaio VGN-FW21M",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FW21M"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) .callback = init_nvs_nosave,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) .ident = "Sony Vaio VPCEB17FX",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) DMI_MATCH(DMI_PRODUCT_NAME, "VPCEB17FX"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) .callback = init_nvs_nosave,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) .ident = "Sony Vaio VGN-SR11M",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SR11M"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) .callback = init_nvs_nosave,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) .ident = "Everex StepNote Series",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) DMI_MATCH(DMI_SYS_VENDOR, "Everex Systems, Inc."),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) DMI_MATCH(DMI_PRODUCT_NAME, "Everex StepNote Series"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) .callback = init_nvs_nosave,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) .ident = "Sony Vaio VPCEB1Z1E",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) DMI_MATCH(DMI_PRODUCT_NAME, "VPCEB1Z1E"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) .callback = init_nvs_nosave,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) .ident = "Sony Vaio VGN-NW130D",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NW130D"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) .callback = init_nvs_nosave,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) .ident = "Sony Vaio VPCCW29FX",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) DMI_MATCH(DMI_PRODUCT_NAME, "VPCCW29FX"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) .callback = init_nvs_nosave,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) .ident = "Averatec AV1020-ED2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) DMI_MATCH(DMI_SYS_VENDOR, "AVERATEC"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) DMI_MATCH(DMI_PRODUCT_NAME, "1000 Series"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) .callback = init_old_suspend_ordering,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) .ident = "Asus A8N-SLI DELUXE",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) DMI_MATCH(DMI_BOARD_NAME, "A8N-SLI DELUXE"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) .callback = init_old_suspend_ordering,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) .ident = "Asus A8N-SLI Premium",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) DMI_MATCH(DMI_BOARD_NAME, "A8N-SLI Premium"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) .callback = init_nvs_nosave,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) .ident = "Sony Vaio VGN-SR26GN_P",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SR26GN_P"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) .callback = init_nvs_nosave,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) .ident = "Sony Vaio VPCEB1S1E",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) DMI_MATCH(DMI_PRODUCT_NAME, "VPCEB1S1E"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) .callback = init_nvs_nosave,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) .ident = "Sony Vaio VGN-FW520F",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FW520F"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) .callback = init_nvs_nosave,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) .ident = "Asus K54C",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) DMI_MATCH(DMI_PRODUCT_NAME, "K54C"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) .callback = init_nvs_nosave,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) .ident = "Asus K54HR",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) DMI_MATCH(DMI_PRODUCT_NAME, "K54HR"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) .callback = init_nvs_save_s3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) .ident = "Asus 1025C",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) DMI_MATCH(DMI_PRODUCT_NAME, "1025C"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) * https://bugzilla.kernel.org/show_bug.cgi?id=189431
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) * Lenovo G50-45 is a platform later than 2012, but needs nvs memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) * saving during S3.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) .callback = init_nvs_save_s3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) .ident = "Lenovo G50-45",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) DMI_MATCH(DMI_PRODUCT_NAME, "80E3"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) * ThinkPad X1 Tablet(2016) cannot do suspend-to-idle using
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) * the Low Power S0 Idle firmware interface (see
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) * https://bugzilla.kernel.org/show_bug.cgi?id=199057).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) .callback = init_default_s3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) .ident = "ThinkPad X1 Tablet(2016)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) DMI_MATCH(DMI_PRODUCT_NAME, "20GGA00L00"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) {},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) static bool ignore_blacklist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) void __init acpi_sleep_no_blacklist(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) ignore_blacklist = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) static void __init acpi_sleep_dmi_check(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) if (ignore_blacklist)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) if (dmi_get_bios_year() >= 2012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) acpi_nvs_nosave_s3();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) dmi_check_system(acpisleep_dmi_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) * acpi_pm_freeze - Disable the GPEs and suspend EC transactions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) static int acpi_pm_freeze(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) acpi_disable_all_gpes();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) acpi_os_wait_events_complete();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) acpi_ec_block_transactions();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) * acpi_pre_suspend - Enable wakeup devices, "freeze" EC and save NVS.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) static int acpi_pm_pre_suspend(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) acpi_pm_freeze();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) return suspend_nvs_save();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) * __acpi_pm_prepare - Prepare the platform to enter the target state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) * If necessary, set the firmware waking vector and do arch-specific
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) * nastiness to get the wakeup code to the waking vector.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) static int __acpi_pm_prepare(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) int error = acpi_sleep_prepare(acpi_target_sleep_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) acpi_target_sleep_state = ACPI_STATE_S0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) * acpi_pm_prepare - Prepare the platform to enter the target sleep
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) * state and disable the GPEs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) static int acpi_pm_prepare(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) int error = __acpi_pm_prepare();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) if (!error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) error = acpi_pm_pre_suspend();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) * acpi_pm_finish - Instruct the platform to leave a sleep state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) * This is called after we wake back up (or if entering the sleep state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) * failed).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) static void acpi_pm_finish(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) struct acpi_device *pwr_btn_adev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) u32 acpi_state = acpi_target_sleep_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) acpi_ec_unblock_transactions();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) suspend_nvs_free();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) if (acpi_state == ACPI_STATE_S0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) printk(KERN_INFO PREFIX "Waking up from system sleep state S%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) acpi_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) acpi_disable_wakeup_devices(acpi_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) acpi_leave_sleep_state(acpi_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) /* reset firmware waking vector */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) acpi_set_waking_vector(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) acpi_target_sleep_state = ACPI_STATE_S0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) acpi_resume_power_resources();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) /* If we were woken with the fixed power button, provide a small
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) * hint to userspace in the form of a wakeup event on the fixed power
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) * button device (if it can be found).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) * We delay the event generation til now, as the PM layer requires
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) * timekeeping to be running before we generate events. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) if (!pwr_btn_event_pending)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) pwr_btn_event_pending = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) pwr_btn_adev = acpi_dev_get_first_match_dev(ACPI_BUTTON_HID_POWERF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) NULL, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) if (pwr_btn_adev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) pm_wakeup_event(&pwr_btn_adev->dev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) acpi_dev_put(pwr_btn_adev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) * acpi_pm_start - Start system PM transition.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) static void acpi_pm_start(u32 acpi_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) acpi_target_sleep_state = acpi_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) acpi_sleep_tts_switch(acpi_target_sleep_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) acpi_scan_lock_acquire();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) * acpi_pm_end - Finish up system PM transition.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) static void acpi_pm_end(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) acpi_turn_off_unused_power_resources();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) acpi_scan_lock_release();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) * This is necessary in case acpi_pm_finish() is not called during a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) * failing transition to a sleep state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) acpi_target_sleep_state = ACPI_STATE_S0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) acpi_sleep_tts_switch(acpi_target_sleep_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) #else /* !CONFIG_ACPI_SLEEP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) #define sleep_no_lps0 (1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) #define acpi_target_sleep_state ACPI_STATE_S0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) #define acpi_sleep_default_s3 (1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) static inline void acpi_sleep_dmi_check(void) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) #endif /* CONFIG_ACPI_SLEEP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) #ifdef CONFIG_SUSPEND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) static u32 acpi_suspend_states[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) [PM_SUSPEND_ON] = ACPI_STATE_S0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) [PM_SUSPEND_STANDBY] = ACPI_STATE_S1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) [PM_SUSPEND_MEM] = ACPI_STATE_S3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) [PM_SUSPEND_MAX] = ACPI_STATE_S5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) * acpi_suspend_begin - Set the target system sleep state to the state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) * associated with given @pm_state, if supported.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) static int acpi_suspend_begin(suspend_state_t pm_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) u32 acpi_state = acpi_suspend_states[pm_state];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) error = (nvs_nosave || nvs_nosave_s3) ? 0 : suspend_nvs_alloc();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) if (!sleep_states[acpi_state]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) pr_err("ACPI does not support sleep state S%u\n", acpi_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) return -ENOSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) if (acpi_state > ACPI_STATE_S1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) pm_set_suspend_via_firmware();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) acpi_pm_start(acpi_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) * acpi_suspend_enter - Actually enter a sleep state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) * @pm_state: ignored
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) * Flush caches and go to sleep. For STR we have to call arch-specific
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) * assembly, which in turn call acpi_enter_sleep_state().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) * It's unfortunate, but it works. Please fix if you're feeling frisky.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) static int acpi_suspend_enter(suspend_state_t pm_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) acpi_status status = AE_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) u32 acpi_state = acpi_target_sleep_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) ACPI_FLUSH_CPU_CACHE();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) trace_suspend_resume(TPS("acpi_suspend"), acpi_state, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) switch (acpi_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) case ACPI_STATE_S1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) barrier();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) status = acpi_enter_sleep_state(acpi_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) case ACPI_STATE_S3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) if (!acpi_suspend_lowlevel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) return -ENOSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) error = acpi_suspend_lowlevel();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) pr_info(PREFIX "Low-level resume complete\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) pm_set_resume_via_firmware();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) trace_suspend_resume(TPS("acpi_suspend"), acpi_state, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) /* This violates the spec but is required for bug compatibility. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) acpi_write_bit_register(ACPI_BITREG_SCI_ENABLE, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) /* Reprogram control registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) acpi_leave_sleep_state_prep(acpi_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) /* ACPI 3.0 specs (P62) says that it's the responsibility
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) * of the OSPM to clear the status bit [ implying that the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) * POWER_BUTTON event should not reach userspace ]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) * However, we do generate a small hint for userspace in the form of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) * a wakeup event. We flag this condition for now and generate the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) * event later, as we're currently too early in resume to be able to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) * generate wakeup events.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) if (ACPI_SUCCESS(status) && (acpi_state == ACPI_STATE_S3)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) acpi_event_status pwr_btn_status = ACPI_EVENT_FLAG_DISABLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) acpi_get_event_status(ACPI_EVENT_POWER_BUTTON, &pwr_btn_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) if (pwr_btn_status & ACPI_EVENT_FLAG_STATUS_SET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) acpi_clear_event(ACPI_EVENT_POWER_BUTTON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) /* Flag for later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) pwr_btn_event_pending = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) * Disable and clear GPE status before interrupt is enabled. Some GPEs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) * (like wakeup GPE) haven't handler, this can avoid such GPE misfire.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) * acpi_leave_sleep_state will reenable specific GPEs later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) acpi_disable_all_gpes();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) /* Allow EC transactions to happen. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) acpi_ec_unblock_transactions();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) suspend_nvs_restore();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) return ACPI_SUCCESS(status) ? 0 : -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) static int acpi_suspend_state_valid(suspend_state_t pm_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) u32 acpi_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) switch (pm_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) case PM_SUSPEND_ON:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) case PM_SUSPEND_STANDBY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) case PM_SUSPEND_MEM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) acpi_state = acpi_suspend_states[pm_state];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) return sleep_states[acpi_state];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) static const struct platform_suspend_ops acpi_suspend_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) .valid = acpi_suspend_state_valid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) .begin = acpi_suspend_begin,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) .prepare_late = acpi_pm_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) .enter = acpi_suspend_enter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) .wake = acpi_pm_finish,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) .end = acpi_pm_end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) * acpi_suspend_begin_old - Set the target system sleep state to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) * state associated with given @pm_state, if supported, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) * execute the _PTS control method. This function is used if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) * pre-ACPI 2.0 suspend ordering has been requested.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) static int acpi_suspend_begin_old(suspend_state_t pm_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) int error = acpi_suspend_begin(pm_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) if (!error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) error = __acpi_pm_prepare();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) * The following callbacks are used if the pre-ACPI 2.0 suspend ordering has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) * been requested.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) static const struct platform_suspend_ops acpi_suspend_ops_old = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) .valid = acpi_suspend_state_valid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) .begin = acpi_suspend_begin_old,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) .prepare_late = acpi_pm_pre_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) .enter = acpi_suspend_enter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) .wake = acpi_pm_finish,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) .end = acpi_pm_end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) .recover = acpi_pm_finish,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) static bool s2idle_wakeup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) * On platforms supporting the Low Power S0 Idle interface there is an ACPI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) * device object with the PNP0D80 compatible device ID (System Power Management
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) * Controller) and a specific _DSM method under it. That method, if present,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) * can be used to indicate to the platform that the OS is transitioning into a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) * low-power state in which certain types of activity are not desirable or that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) * it is leaving such a state, which allows the platform to adjust its operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) * mode accordingly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) static const struct acpi_device_id lps0_device_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) {"PNP0D80", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) {"", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) #define ACPI_LPS0_DSM_UUID "c4eb40a0-6cd2-11e2-bcfd-0800200c9a66"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) #define ACPI_LPS0_GET_DEVICE_CONSTRAINTS 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) #define ACPI_LPS0_SCREEN_OFF 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) #define ACPI_LPS0_SCREEN_ON 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) #define ACPI_LPS0_ENTRY 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) #define ACPI_LPS0_EXIT 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) static acpi_handle lps0_device_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) static guid_t lps0_dsm_guid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) static char lps0_dsm_func_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) /* Device constraint entry structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) struct lpi_device_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) int enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) union acpi_object *package;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) /* Constraint package structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) struct lpi_device_constraint {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) int uid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) int min_dstate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) int function_states;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) struct lpi_constraints {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) acpi_handle handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) int min_dstate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) static struct lpi_constraints *lpi_constraints_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) static int lpi_constraints_table_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) static void lpi_device_get_constraints(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) union acpi_object *out_obj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) out_obj = acpi_evaluate_dsm_typed(lps0_device_handle, &lps0_dsm_guid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) 1, ACPI_LPS0_GET_DEVICE_CONSTRAINTS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) NULL, ACPI_TYPE_PACKAGE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) acpi_handle_debug(lps0_device_handle, "_DSM function 1 eval %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) out_obj ? "successful" : "failed");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) if (!out_obj)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) lpi_constraints_table = kcalloc(out_obj->package.count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) sizeof(*lpi_constraints_table),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) if (!lpi_constraints_table)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) goto free_acpi_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) acpi_handle_debug(lps0_device_handle, "LPI: constraints list begin:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) for (i = 0; i < out_obj->package.count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) struct lpi_constraints *constraint;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) union acpi_object *package = &out_obj->package.elements[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) struct lpi_device_info info = { };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) int package_count = 0, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) if (!package)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) for (j = 0; j < package->package.count; ++j) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) union acpi_object *element =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) &(package->package.elements[j]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) switch (element->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) case ACPI_TYPE_INTEGER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) info.enabled = element->integer.value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) case ACPI_TYPE_STRING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) info.name = element->string.pointer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) case ACPI_TYPE_PACKAGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) package_count = element->package.count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) info.package = element->package.elements;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) if (!info.enabled || !info.package || !info.name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) constraint = &lpi_constraints_table[lpi_constraints_table_size];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) status = acpi_get_handle(NULL, info.name, &constraint->handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) if (ACPI_FAILURE(status))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) acpi_handle_debug(lps0_device_handle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) "index:%d Name:%s\n", i, info.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) constraint->min_dstate = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) for (j = 0; j < package_count; ++j) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) union acpi_object *info_obj = &info.package[j];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) union acpi_object *cnstr_pkg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) union acpi_object *obj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) struct lpi_device_constraint dev_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) switch (info_obj->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) case ACPI_TYPE_INTEGER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) /* version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) case ACPI_TYPE_PACKAGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) if (info_obj->package.count < 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) cnstr_pkg = info_obj->package.elements;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) obj = &cnstr_pkg[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) dev_info.uid = obj->integer.value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) obj = &cnstr_pkg[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) dev_info.min_dstate = obj->integer.value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) acpi_handle_debug(lps0_device_handle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) "uid:%d min_dstate:%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) dev_info.uid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) acpi_power_state_string(dev_info.min_dstate));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) constraint->min_dstate = dev_info.min_dstate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) if (constraint->min_dstate < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) acpi_handle_debug(lps0_device_handle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) "Incomplete constraint defined\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) lpi_constraints_table_size++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) acpi_handle_debug(lps0_device_handle, "LPI: constraints list end\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) free_acpi_buffer:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) ACPI_FREE(out_obj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) static void lpi_check_constraints(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) for (i = 0; i < lpi_constraints_table_size; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) acpi_handle handle = lpi_constraints_table[i].handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) struct acpi_device *adev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) if (!handle || acpi_bus_get_device(handle, &adev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) acpi_handle_debug(handle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) "LPI: required min power state:%s current power state:%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) acpi_power_state_string(lpi_constraints_table[i].min_dstate),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) acpi_power_state_string(adev->power.state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) if (!adev->flags.power_manageable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) acpi_handle_info(handle, "LPI: Device not power manageable\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) lpi_constraints_table[i].handle = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) if (adev->power.state < lpi_constraints_table[i].min_dstate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) acpi_handle_info(handle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) "LPI: Constraint not met; min power state:%s current power state:%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) acpi_power_state_string(lpi_constraints_table[i].min_dstate),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) acpi_power_state_string(adev->power.state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) static void acpi_sleep_run_lps0_dsm(unsigned int func)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) union acpi_object *out_obj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) if (!(lps0_dsm_func_mask & (1 << func)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) out_obj = acpi_evaluate_dsm(lps0_device_handle, &lps0_dsm_guid, 1, func, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) ACPI_FREE(out_obj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) acpi_handle_debug(lps0_device_handle, "_DSM function %u evaluation %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) func, out_obj ? "successful" : "failed");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) static int lps0_device_attach(struct acpi_device *adev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) const struct acpi_device_id *not_used)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) union acpi_object *out_obj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) if (lps0_device_handle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) if (!(acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) guid_parse(ACPI_LPS0_DSM_UUID, &lps0_dsm_guid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) /* Check if the _DSM is present and as expected. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) out_obj = acpi_evaluate_dsm(adev->handle, &lps0_dsm_guid, 1, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) if (!out_obj || out_obj->type != ACPI_TYPE_BUFFER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) acpi_handle_debug(adev->handle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) "_DSM function 0 evaluation failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) lps0_dsm_func_mask = *(char *)out_obj->buffer.pointer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) ACPI_FREE(out_obj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) acpi_handle_debug(adev->handle, "_DSM function mask: 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) lps0_dsm_func_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) lps0_device_handle = adev->handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) lpi_device_get_constraints();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) * Use suspend-to-idle by default if the default suspend mode was not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) * set from the command line.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) if (mem_sleep_default > PM_SUSPEND_MEM && !acpi_sleep_default_s3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) mem_sleep_current = PM_SUSPEND_TO_IDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) * Some LPS0 systems, like ASUS Zenbook UX430UNR/i7-8550U, require the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) * EC GPE to be enabled while suspended for certain wakeup devices to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) * work, so mark it as wakeup-capable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) acpi_ec_mark_gpe_for_wake();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) static struct acpi_scan_handler lps0_handler = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) .ids = lps0_device_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) .attach = lps0_device_attach,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) static int acpi_s2idle_begin(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) acpi_scan_lock_acquire();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) static int acpi_s2idle_prepare(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) if (acpi_sci_irq_valid()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) enable_irq_wake(acpi_sci_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) acpi_ec_set_gpe_wake_mask(ACPI_GPE_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) acpi_enable_wakeup_devices(ACPI_STATE_S0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) /* Change the configuration of GPEs to avoid spurious wakeup. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) acpi_enable_all_wakeup_gpes();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) acpi_os_wait_events_complete();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) s2idle_wakeup = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) static int acpi_s2idle_prepare_late(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) if (!lps0_device_handle || sleep_no_lps0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) if (pm_debug_messages_on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) lpi_check_constraints();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) acpi_sleep_run_lps0_dsm(ACPI_LPS0_SCREEN_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) acpi_sleep_run_lps0_dsm(ACPI_LPS0_ENTRY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) static bool acpi_s2idle_wake(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) if (!acpi_sci_irq_valid())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) return pm_wakeup_pending();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) while (pm_wakeup_pending()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) * If IRQD_WAKEUP_ARMED is set for the SCI at this point, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) * SCI has not triggered while suspended, so bail out (the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) * wakeup is pending anyway and the SCI is not the source of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) * it).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) if (irqd_is_wakeup_armed(irq_get_irq_data(acpi_sci_irq))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) pm_pr_dbg("Wakeup unrelated to ACPI SCI\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) * If the status bit of any enabled fixed event is set, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) * wakeup is regarded as valid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) if (acpi_any_fixed_event_status_set()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) pm_pr_dbg("ACPI fixed event wakeup\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) /* Check wakeups from drivers sharing the SCI. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) if (acpi_check_wakeup_handlers()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) pm_pr_dbg("ACPI custom handler wakeup\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) /* Check non-EC GPE wakeups and dispatch the EC GPE. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) if (acpi_ec_dispatch_gpe()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) pm_pr_dbg("ACPI non-EC GPE wakeup\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) * Cancel the SCI wakeup and process all pending events in case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) * there are any wakeup ones in there.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) * Note that if any non-EC GPEs are active at this point, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) * SCI will retrigger after the rearming below, so no events
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) * should be missed by canceling the wakeup here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) pm_system_cancel_wakeup();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) acpi_os_wait_events_complete();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) * The SCI is in the "suspended" state now and it cannot produce
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) * new wakeup events till the rearming below, so if any of them
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) * are pending here, they must be resulting from the processing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) * of EC events above or coming from somewhere else.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) if (pm_wakeup_pending()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) pm_pr_dbg("Wakeup after ACPI Notify sync\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) pm_wakeup_clear(acpi_sci_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) rearm_wake_irq(acpi_sci_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) static void acpi_s2idle_restore_early(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) if (!lps0_device_handle || sleep_no_lps0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) acpi_sleep_run_lps0_dsm(ACPI_LPS0_EXIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) acpi_sleep_run_lps0_dsm(ACPI_LPS0_SCREEN_ON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) static void acpi_s2idle_restore(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) * Drain pending events before restoring the working-state configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) * of GPEs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) acpi_os_wait_events_complete(); /* synchronize GPE processing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) acpi_ec_flush_work(); /* flush the EC driver's workqueues */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) acpi_os_wait_events_complete(); /* synchronize Notify handling */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) s2idle_wakeup = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) acpi_enable_all_runtime_gpes();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) acpi_disable_wakeup_devices(ACPI_STATE_S0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) if (acpi_sci_irq_valid()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) acpi_ec_set_gpe_wake_mask(ACPI_GPE_DISABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) disable_irq_wake(acpi_sci_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) static void acpi_s2idle_end(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) acpi_scan_lock_release();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) static const struct platform_s2idle_ops acpi_s2idle_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) .begin = acpi_s2idle_begin,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) .prepare = acpi_s2idle_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) .prepare_late = acpi_s2idle_prepare_late,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) .wake = acpi_s2idle_wake,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) .restore_early = acpi_s2idle_restore_early,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) .restore = acpi_s2idle_restore,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) .end = acpi_s2idle_end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) static void acpi_sleep_suspend_setup(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) for (i = ACPI_STATE_S1; i < ACPI_STATE_S4; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) if (acpi_sleep_state_supported(i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) sleep_states[i] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) suspend_set_ops(old_suspend_ordering ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) &acpi_suspend_ops_old : &acpi_suspend_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) acpi_scan_add_handler(&lps0_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) s2idle_set_ops(&acpi_s2idle_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) #else /* !CONFIG_SUSPEND */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) #define s2idle_wakeup (false)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) #define lps0_device_handle (NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) static inline void acpi_sleep_suspend_setup(void) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) #endif /* !CONFIG_SUSPEND */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) bool acpi_s2idle_wakeup(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) return s2idle_wakeup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) static u32 saved_bm_rld;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) static int acpi_save_bm_rld(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) acpi_read_bit_register(ACPI_BITREG_BUS_MASTER_RLD, &saved_bm_rld);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) static void acpi_restore_bm_rld(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) u32 resumed_bm_rld = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) acpi_read_bit_register(ACPI_BITREG_BUS_MASTER_RLD, &resumed_bm_rld);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) if (resumed_bm_rld == saved_bm_rld)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_RLD, saved_bm_rld);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) static struct syscore_ops acpi_sleep_syscore_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) .suspend = acpi_save_bm_rld,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) .resume = acpi_restore_bm_rld,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) static void acpi_sleep_syscore_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) register_syscore_ops(&acpi_sleep_syscore_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) static inline void acpi_sleep_syscore_init(void) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) #endif /* CONFIG_PM_SLEEP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) #ifdef CONFIG_HIBERNATION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) static unsigned long s4_hardware_signature;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) static struct acpi_table_facs *facs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) static bool nosigcheck;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) void __init acpi_no_s4_hw_signature(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) nosigcheck = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) static int acpi_hibernation_begin(pm_message_t stage)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) if (!nvs_nosave) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) int error = suspend_nvs_alloc();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) if (stage.event == PM_EVENT_HIBERNATE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) pm_set_suspend_via_firmware();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) acpi_pm_start(ACPI_STATE_S4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) static int acpi_hibernation_enter(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) acpi_status status = AE_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) ACPI_FLUSH_CPU_CACHE();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) /* This shouldn't return. If it returns, we have a problem */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) status = acpi_enter_sleep_state(ACPI_STATE_S4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) /* Reprogram control registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) acpi_leave_sleep_state_prep(ACPI_STATE_S4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) return ACPI_SUCCESS(status) ? 0 : -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) static void acpi_hibernation_leave(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) pm_set_resume_via_firmware();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) * If ACPI is not enabled by the BIOS and the boot kernel, we need to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) * enable it here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) acpi_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) /* Reprogram control registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) acpi_leave_sleep_state_prep(ACPI_STATE_S4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) /* Check the hardware signature */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) if (facs && s4_hardware_signature != facs->hardware_signature)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) pr_crit("ACPI: Hardware changed while hibernated, success doubtful!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) /* Restore the NVS memory area */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) suspend_nvs_restore();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) /* Allow EC transactions to happen. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) acpi_ec_unblock_transactions();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) static void acpi_pm_thaw(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) acpi_ec_unblock_transactions();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) acpi_enable_all_runtime_gpes();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) static const struct platform_hibernation_ops acpi_hibernation_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) .begin = acpi_hibernation_begin,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) .end = acpi_pm_end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) .pre_snapshot = acpi_pm_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) .finish = acpi_pm_finish,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) .prepare = acpi_pm_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) .enter = acpi_hibernation_enter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) .leave = acpi_hibernation_leave,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) .pre_restore = acpi_pm_freeze,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) .restore_cleanup = acpi_pm_thaw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) * acpi_hibernation_begin_old - Set the target system sleep state to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) * ACPI_STATE_S4 and execute the _PTS control method. This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) * function is used if the pre-ACPI 2.0 suspend ordering has been
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) * requested.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) static int acpi_hibernation_begin_old(pm_message_t stage)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) * The _TTS object should always be evaluated before the _PTS object.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) * When the old_suspended_ordering is true, the _PTS object is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) * evaluated in the acpi_sleep_prepare.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) acpi_sleep_tts_switch(ACPI_STATE_S4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) error = acpi_sleep_prepare(ACPI_STATE_S4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) if (!nvs_nosave) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) error = suspend_nvs_alloc();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) if (stage.event == PM_EVENT_HIBERNATE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) pm_set_suspend_via_firmware();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) acpi_target_sleep_state = ACPI_STATE_S4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) acpi_scan_lock_acquire();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) * The following callbacks are used if the pre-ACPI 2.0 suspend ordering has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) * been requested.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) static const struct platform_hibernation_ops acpi_hibernation_ops_old = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) .begin = acpi_hibernation_begin_old,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) .end = acpi_pm_end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) .pre_snapshot = acpi_pm_pre_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) .prepare = acpi_pm_freeze,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) .finish = acpi_pm_finish,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) .enter = acpi_hibernation_enter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) .leave = acpi_hibernation_leave,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) .pre_restore = acpi_pm_freeze,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) .restore_cleanup = acpi_pm_thaw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) .recover = acpi_pm_finish,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) static void acpi_sleep_hibernate_setup(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) if (!acpi_sleep_state_supported(ACPI_STATE_S4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) hibernation_set_ops(old_suspend_ordering ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) &acpi_hibernation_ops_old : &acpi_hibernation_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) sleep_states[ACPI_STATE_S4] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) if (nosigcheck)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) acpi_get_table(ACPI_SIG_FACS, 1, (struct acpi_table_header **)&facs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) if (facs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) s4_hardware_signature = facs->hardware_signature;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) #else /* !CONFIG_HIBERNATION */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) static inline void acpi_sleep_hibernate_setup(void) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) #endif /* !CONFIG_HIBERNATION */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) static void acpi_power_off_prepare(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) /* Prepare to power off the system */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) acpi_sleep_prepare(ACPI_STATE_S5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) acpi_disable_all_gpes();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) acpi_os_wait_events_complete();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) static void acpi_power_off(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) /* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) printk(KERN_DEBUG "%s called\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) local_irq_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) acpi_enter_sleep_state(ACPI_STATE_S5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) int __init acpi_sleep_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) char supported[ACPI_S_STATE_COUNT * 3 + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) char *pos = supported;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) acpi_sleep_dmi_check();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) sleep_states[ACPI_STATE_S0] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) acpi_sleep_syscore_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) acpi_sleep_suspend_setup();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) acpi_sleep_hibernate_setup();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) if (acpi_sleep_state_supported(ACPI_STATE_S5)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) sleep_states[ACPI_STATE_S5] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) pm_power_off_prepare = acpi_power_off_prepare;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) pm_power_off = acpi_power_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) acpi_no_s5 = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) supported[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) for (i = 0; i < ACPI_S_STATE_COUNT; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) if (sleep_states[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) pos += sprintf(pos, " S%d", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) pr_info(PREFIX "(supports%s)\n", supported);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) * Register the tts_notifier to reboot notifier list so that the _TTS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) * object can also be evaluated when the system enters S5.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) register_reboot_notifier(&tts_notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) }