1141 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * sleep.c - ACPI sleep support.4 *5 * Copyright (c) 2005 Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>6 * Copyright (c) 2004 David Shaohua Li <shaohua.li@intel.com>7 * Copyright (c) 2000-2003 Patrick Mochel8 * Copyright (c) 2003 Open Source Development Lab9 */10 11#define pr_fmt(fmt) "ACPI: PM: " fmt12 13#include <linux/delay.h>14#include <linux/irq.h>15#include <linux/dmi.h>16#include <linux/device.h>17#include <linux/interrupt.h>18#include <linux/suspend.h>19#include <linux/reboot.h>20#include <linux/acpi.h>21#include <linux/module.h>22#include <linux/syscore_ops.h>23#include <asm/io.h>24#include <trace/events/power.h>25 26#include "internal.h"27#include "sleep.h"28 29/*30 * Some HW-full platforms do not have _S5, so they may need31 * to leverage efi power off for a shutdown.32 */33bool acpi_no_s5;34static u8 sleep_states[ACPI_S_STATE_COUNT];35 36static void acpi_sleep_tts_switch(u32 acpi_state)37{38 acpi_status status;39 40 status = acpi_execute_simple_method(NULL, "\\_TTS", acpi_state);41 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {42 /*43 * OS can't evaluate the _TTS object correctly. Some warning44 * message will be printed. But it won't break anything.45 */46 pr_notice("Failure in evaluating _TTS object\n");47 }48}49 50static int tts_notify_reboot(struct notifier_block *this,51 unsigned long code, void *x)52{53 acpi_sleep_tts_switch(ACPI_STATE_S5);54 return NOTIFY_DONE;55}56 57static struct notifier_block tts_notifier = {58 .notifier_call = tts_notify_reboot,59 .next = NULL,60 .priority = 0,61};62 63#ifndef acpi_skip_set_wakeup_address64#define acpi_skip_set_wakeup_address() false65#endif66 67static int acpi_sleep_prepare(u32 acpi_state)68{69#ifdef CONFIG_ACPI_SLEEP70 unsigned long acpi_wakeup_address;71 72 /* do we have a wakeup address for S2 and S3? */73 if (acpi_state == ACPI_STATE_S3 && !acpi_skip_set_wakeup_address()) {74 acpi_wakeup_address = acpi_get_wakeup_address();75 if (!acpi_wakeup_address)76 return -EFAULT;77 acpi_set_waking_vector(acpi_wakeup_address);78 79 }80#endif81 pr_info("Preparing to enter system sleep state S%d\n", acpi_state);82 acpi_enable_wakeup_devices(acpi_state);83 acpi_enter_sleep_state_prep(acpi_state);84 return 0;85}86 87bool acpi_sleep_state_supported(u8 sleep_state)88{89 acpi_status status;90 u8 type_a, type_b;91 92 status = acpi_get_sleep_type_data(sleep_state, &type_a, &type_b);93 return ACPI_SUCCESS(status) && (!acpi_gbl_reduced_hardware94 || (acpi_gbl_FADT.sleep_control.address95 && acpi_gbl_FADT.sleep_status.address));96}97 98#ifdef CONFIG_ACPI_SLEEP99static u32 acpi_target_sleep_state = ACPI_STATE_S0;100 101u32 acpi_target_system_state(void)102{103 return acpi_target_sleep_state;104}105EXPORT_SYMBOL_GPL(acpi_target_system_state);106 107static bool pwr_btn_event_pending;108 109/*110 * The ACPI specification wants us to save NVS memory regions during hibernation111 * and to restore them during the subsequent resume. Windows does that also for112 * suspend to RAM. However, it is known that this mechanism does not work on113 * all machines, so we allow the user to disable it with the help of the114 * 'acpi_sleep=nonvs' kernel command line option.115 */116static bool nvs_nosave;117 118void __init acpi_nvs_nosave(void)119{120 nvs_nosave = true;121}122 123/*124 * The ACPI specification wants us to save NVS memory regions during hibernation125 * but says nothing about saving NVS during S3. Not all versions of Windows126 * save NVS on S3 suspend either, and it is clear that not all systems need127 * NVS to be saved at S3 time. To improve suspend/resume time, allow the128 * user to disable saving NVS on S3 if their system does not require it, but129 * continue to save/restore NVS for S4 as specified.130 */131static bool nvs_nosave_s3;132 133void __init acpi_nvs_nosave_s3(void)134{135 nvs_nosave_s3 = true;136}137 138static int __init init_nvs_save_s3(const struct dmi_system_id *d)139{140 nvs_nosave_s3 = false;141 return 0;142}143 144/*145 * ACPI 1.0 wants us to execute _PTS before suspending devices, so we allow the146 * user to request that behavior by using the 'acpi_old_suspend_ordering'147 * kernel command line option that causes the following variable to be set.148 */149static bool old_suspend_ordering;150 151void __init acpi_old_suspend_ordering(void)152{153 old_suspend_ordering = true;154}155 156static int __init init_old_suspend_ordering(const struct dmi_system_id *d)157{158 acpi_old_suspend_ordering();159 return 0;160}161 162static int __init init_nvs_nosave(const struct dmi_system_id *d)163{164 acpi_nvs_nosave();165 return 0;166}167 168bool acpi_sleep_default_s3;169 170static int __init init_default_s3(const struct dmi_system_id *d)171{172 acpi_sleep_default_s3 = true;173 return 0;174}175 176static const struct dmi_system_id acpisleep_dmi_table[] __initconst = {177 {178 .callback = init_old_suspend_ordering,179 .ident = "Abit KN9 (nForce4 variant)",180 .matches = {181 DMI_MATCH(DMI_BOARD_VENDOR, "http://www.abit.com.tw/"),182 DMI_MATCH(DMI_BOARD_NAME, "KN9 Series(NF-CK804)"),183 },184 },185 {186 .callback = init_old_suspend_ordering,187 .ident = "HP xw4600 Workstation",188 .matches = {189 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),190 DMI_MATCH(DMI_PRODUCT_NAME, "HP xw4600 Workstation"),191 },192 },193 {194 .callback = init_old_suspend_ordering,195 .ident = "Asus Pundit P1-AH2 (M2N8L motherboard)",196 .matches = {197 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTek Computer INC."),198 DMI_MATCH(DMI_BOARD_NAME, "M2N8L"),199 },200 },201 {202 .callback = init_old_suspend_ordering,203 .ident = "Panasonic CF51-2L",204 .matches = {205 DMI_MATCH(DMI_BOARD_VENDOR,206 "Matsushita Electric Industrial Co.,Ltd."),207 DMI_MATCH(DMI_BOARD_NAME, "CF51-2L"),208 },209 },210 {211 .callback = init_nvs_nosave,212 .ident = "Sony Vaio VGN-FW41E_H",213 .matches = {214 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),215 DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FW41E_H"),216 },217 },218 {219 .callback = init_nvs_nosave,220 .ident = "Sony Vaio VGN-FW21E",221 .matches = {222 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),223 DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FW21E"),224 },225 },226 {227 .callback = init_nvs_nosave,228 .ident = "Sony Vaio VGN-FW21M",229 .matches = {230 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),231 DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FW21M"),232 },233 },234 {235 .callback = init_nvs_nosave,236 .ident = "Sony Vaio VPCEB17FX",237 .matches = {238 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),239 DMI_MATCH(DMI_PRODUCT_NAME, "VPCEB17FX"),240 },241 },242 {243 .callback = init_nvs_nosave,244 .ident = "Sony Vaio VGN-SR11M",245 .matches = {246 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),247 DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SR11M"),248 },249 },250 {251 .callback = init_nvs_nosave,252 .ident = "Everex StepNote Series",253 .matches = {254 DMI_MATCH(DMI_SYS_VENDOR, "Everex Systems, Inc."),255 DMI_MATCH(DMI_PRODUCT_NAME, "Everex StepNote Series"),256 },257 },258 {259 .callback = init_nvs_nosave,260 .ident = "Sony Vaio VPCEB1Z1E",261 .matches = {262 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),263 DMI_MATCH(DMI_PRODUCT_NAME, "VPCEB1Z1E"),264 },265 },266 {267 .callback = init_nvs_nosave,268 .ident = "Sony Vaio VGN-NW130D",269 .matches = {270 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),271 DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NW130D"),272 },273 },274 {275 .callback = init_nvs_nosave,276 .ident = "Sony Vaio VPCCW29FX",277 .matches = {278 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),279 DMI_MATCH(DMI_PRODUCT_NAME, "VPCCW29FX"),280 },281 },282 {283 .callback = init_nvs_nosave,284 .ident = "Averatec AV1020-ED2",285 .matches = {286 DMI_MATCH(DMI_SYS_VENDOR, "AVERATEC"),287 DMI_MATCH(DMI_PRODUCT_NAME, "1000 Series"),288 },289 },290 {291 .callback = init_old_suspend_ordering,292 .ident = "Asus A8N-SLI DELUXE",293 .matches = {294 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),295 DMI_MATCH(DMI_BOARD_NAME, "A8N-SLI DELUXE"),296 },297 },298 {299 .callback = init_old_suspend_ordering,300 .ident = "Asus A8N-SLI Premium",301 .matches = {302 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),303 DMI_MATCH(DMI_BOARD_NAME, "A8N-SLI Premium"),304 },305 },306 {307 .callback = init_nvs_nosave,308 .ident = "Sony Vaio VGN-SR26GN_P",309 .matches = {310 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),311 DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SR26GN_P"),312 },313 },314 {315 .callback = init_nvs_nosave,316 .ident = "Sony Vaio VPCEB1S1E",317 .matches = {318 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),319 DMI_MATCH(DMI_PRODUCT_NAME, "VPCEB1S1E"),320 },321 },322 {323 .callback = init_nvs_nosave,324 .ident = "Sony Vaio VGN-FW520F",325 .matches = {326 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),327 DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FW520F"),328 },329 },330 {331 .callback = init_nvs_nosave,332 .ident = "Asus K54C",333 .matches = {334 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),335 DMI_MATCH(DMI_PRODUCT_NAME, "K54C"),336 },337 },338 {339 .callback = init_nvs_nosave,340 .ident = "Asus K54HR",341 .matches = {342 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),343 DMI_MATCH(DMI_PRODUCT_NAME, "K54HR"),344 },345 },346 {347 .callback = init_nvs_save_s3,348 .ident = "Asus 1025C",349 .matches = {350 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),351 DMI_MATCH(DMI_PRODUCT_NAME, "1025C"),352 },353 },354 /*355 * The ASUS ROG M16 from 2023 has many events which wake it from s2idle356 * resulting in excessive battery drain and risk of laptop overheating,357 * these events can be caused by the MMC or y AniMe display if installed.358 * The match is valid for all of the GU604V<x> range.359 */360 {361 .callback = init_default_s3,362 .ident = "ASUS ROG Zephyrus M16 (2023)",363 .matches = {364 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),365 DMI_MATCH(DMI_PRODUCT_NAME, "ROG Zephyrus M16 GU604V"),366 },367 },368 /*369 * https://bugzilla.kernel.org/show_bug.cgi?id=189431370 * Lenovo G50-45 is a platform later than 2012, but needs nvs memory371 * saving during S3.372 */373 {374 .callback = init_nvs_save_s3,375 .ident = "Lenovo G50-45",376 .matches = {377 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),378 DMI_MATCH(DMI_PRODUCT_NAME, "80E3"),379 },380 },381 {382 .callback = init_nvs_save_s3,383 .ident = "Lenovo G40-45",384 .matches = {385 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),386 DMI_MATCH(DMI_PRODUCT_NAME, "80E1"),387 },388 },389 /*390 * ThinkPad X1 Tablet(2016) cannot do suspend-to-idle using391 * the Low Power S0 Idle firmware interface (see392 * https://bugzilla.kernel.org/show_bug.cgi?id=199057).393 */394 {395 .callback = init_default_s3,396 .ident = "ThinkPad X1 Tablet(2016)",397 .matches = {398 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),399 DMI_MATCH(DMI_PRODUCT_NAME, "20GGA00L00"),400 },401 },402 {},403};404 405static bool ignore_blacklist;406 407void __init acpi_sleep_no_blacklist(void)408{409 ignore_blacklist = true;410}411 412static void __init acpi_sleep_dmi_check(void)413{414 if (ignore_blacklist)415 return;416 417 if (dmi_get_bios_year() >= 2012)418 acpi_nvs_nosave_s3();419 420 dmi_check_system(acpisleep_dmi_table);421}422 423/**424 * acpi_pm_freeze - Disable the GPEs and suspend EC transactions.425 */426static int acpi_pm_freeze(void)427{428 acpi_disable_all_gpes();429 acpi_os_wait_events_complete();430 acpi_ec_block_transactions();431 return 0;432}433 434/**435 * acpi_pm_pre_suspend - Enable wakeup devices, "freeze" EC and save NVS.436 */437static int acpi_pm_pre_suspend(void)438{439 acpi_pm_freeze();440 return suspend_nvs_save();441}442 443/**444 * __acpi_pm_prepare - Prepare the platform to enter the target state.445 *446 * If necessary, set the firmware waking vector and do arch-specific447 * nastiness to get the wakeup code to the waking vector.448 */449static int __acpi_pm_prepare(void)450{451 int error = acpi_sleep_prepare(acpi_target_sleep_state);452 if (error)453 acpi_target_sleep_state = ACPI_STATE_S0;454 455 return error;456}457 458/**459 * acpi_pm_prepare - Prepare the platform to enter the target sleep460 * state and disable the GPEs.461 */462static int acpi_pm_prepare(void)463{464 int error = __acpi_pm_prepare();465 if (!error)466 error = acpi_pm_pre_suspend();467 468 return error;469}470 471/**472 * acpi_pm_finish - Instruct the platform to leave a sleep state.473 *474 * This is called after we wake back up (or if entering the sleep state475 * failed).476 */477static void acpi_pm_finish(void)478{479 struct acpi_device *pwr_btn_adev;480 u32 acpi_state = acpi_target_sleep_state;481 482 acpi_ec_unblock_transactions();483 suspend_nvs_free();484 485 if (acpi_state == ACPI_STATE_S0)486 return;487 488 pr_info("Waking up from system sleep state S%d\n", acpi_state);489 acpi_disable_wakeup_devices(acpi_state);490 acpi_leave_sleep_state(acpi_state);491 492 /* reset firmware waking vector */493 acpi_set_waking_vector(0);494 495 acpi_target_sleep_state = ACPI_STATE_S0;496 497 acpi_resume_power_resources();498 499 /* If we were woken with the fixed power button, provide a small500 * hint to userspace in the form of a wakeup event on the fixed power501 * button device (if it can be found).502 *503 * We delay the event generation til now, as the PM layer requires504 * timekeeping to be running before we generate events. */505 if (!pwr_btn_event_pending)506 return;507 508 pwr_btn_event_pending = false;509 pwr_btn_adev = acpi_dev_get_first_match_dev(ACPI_BUTTON_HID_POWERF,510 NULL, -1);511 if (pwr_btn_adev) {512 pm_wakeup_event(&pwr_btn_adev->dev, 0);513 acpi_dev_put(pwr_btn_adev);514 }515}516 517/**518 * acpi_pm_start - Start system PM transition.519 * @acpi_state: The target ACPI power state to transition to.520 */521static void acpi_pm_start(u32 acpi_state)522{523 acpi_target_sleep_state = acpi_state;524 acpi_sleep_tts_switch(acpi_target_sleep_state);525 acpi_scan_lock_acquire();526}527 528/**529 * acpi_pm_end - Finish up system PM transition.530 */531static void acpi_pm_end(void)532{533 acpi_turn_off_unused_power_resources();534 acpi_scan_lock_release();535 /*536 * This is necessary in case acpi_pm_finish() is not called during a537 * failing transition to a sleep state.538 */539 acpi_target_sleep_state = ACPI_STATE_S0;540 acpi_sleep_tts_switch(acpi_target_sleep_state);541}542#else /* !CONFIG_ACPI_SLEEP */543#define sleep_no_lps0 (1)544#define acpi_target_sleep_state ACPI_STATE_S0545#define acpi_sleep_default_s3 (1)546static inline void acpi_sleep_dmi_check(void) {}547#endif /* CONFIG_ACPI_SLEEP */548 549#ifdef CONFIG_SUSPEND550static u32 acpi_suspend_states[] = {551 [PM_SUSPEND_ON] = ACPI_STATE_S0,552 [PM_SUSPEND_STANDBY] = ACPI_STATE_S1,553 [PM_SUSPEND_MEM] = ACPI_STATE_S3,554 [PM_SUSPEND_MAX] = ACPI_STATE_S5555};556 557/**558 * acpi_suspend_begin - Set the target system sleep state to the state559 * associated with given @pm_state, if supported.560 * @pm_state: The target system power management state.561 */562static int acpi_suspend_begin(suspend_state_t pm_state)563{564 u32 acpi_state = acpi_suspend_states[pm_state];565 int error;566 567 error = (nvs_nosave || nvs_nosave_s3) ? 0 : suspend_nvs_alloc();568 if (error)569 return error;570 571 if (!sleep_states[acpi_state]) {572 pr_err("ACPI does not support sleep state S%u\n", acpi_state);573 return -ENOSYS;574 }575 if (acpi_state > ACPI_STATE_S1)576 pm_set_suspend_via_firmware();577 578 acpi_pm_start(acpi_state);579 return 0;580}581 582/**583 * acpi_suspend_enter - Actually enter a sleep state.584 * @pm_state: ignored585 *586 * Flush caches and go to sleep. For STR we have to call arch-specific587 * assembly, which in turn call acpi_enter_sleep_state().588 * It's unfortunate, but it works. Please fix if you're feeling frisky.589 */590static int acpi_suspend_enter(suspend_state_t pm_state)591{592 acpi_status status = AE_OK;593 u32 acpi_state = acpi_target_sleep_state;594 int error;595 596 trace_suspend_resume(TPS("acpi_suspend"), acpi_state, true);597 switch (acpi_state) {598 case ACPI_STATE_S1:599 barrier();600 status = acpi_enter_sleep_state(acpi_state);601 break;602 603 case ACPI_STATE_S3:604 if (!acpi_suspend_lowlevel)605 return -ENOSYS;606 error = acpi_suspend_lowlevel();607 if (error)608 return error;609 pr_info("Low-level resume complete\n");610 pm_set_resume_via_firmware();611 break;612 }613 trace_suspend_resume(TPS("acpi_suspend"), acpi_state, false);614 615 /* This violates the spec but is required for bug compatibility. */616 acpi_write_bit_register(ACPI_BITREG_SCI_ENABLE, 1);617 618 /* Reprogram control registers */619 acpi_leave_sleep_state_prep(acpi_state);620 621 /* ACPI 3.0 specs (P62) says that it's the responsibility622 * of the OSPM to clear the status bit [ implying that the623 * POWER_BUTTON event should not reach userspace ]624 *625 * However, we do generate a small hint for userspace in the form of626 * a wakeup event. We flag this condition for now and generate the627 * event later, as we're currently too early in resume to be able to628 * generate wakeup events.629 */630 if (ACPI_SUCCESS(status) && (acpi_state == ACPI_STATE_S3)) {631 acpi_event_status pwr_btn_status = ACPI_EVENT_FLAG_DISABLED;632 633 acpi_get_event_status(ACPI_EVENT_POWER_BUTTON, &pwr_btn_status);634 635 if (pwr_btn_status & ACPI_EVENT_FLAG_STATUS_SET) {636 acpi_clear_event(ACPI_EVENT_POWER_BUTTON);637 /* Flag for later */638 pwr_btn_event_pending = true;639 }640 }641 642 /*643 * Disable all GPE and clear their status bits before interrupts are644 * enabled. Some GPEs (like wakeup GPEs) have no handlers and this can645 * prevent them from producing spurious interrups.646 *647 * acpi_leave_sleep_state() will reenable specific GPEs later.648 *649 * Because this code runs on one CPU with disabled interrupts (all of650 * the other CPUs are offline at this time), it need not acquire any651 * sleeping locks which may trigger an implicit preemption point even652 * if there is no contention, so avoid doing that by using a low-level653 * library routine here.654 */655 acpi_hw_disable_all_gpes();656 /* Allow EC transactions to happen. */657 acpi_ec_unblock_transactions();658 659 suspend_nvs_restore();660 661 return ACPI_SUCCESS(status) ? 0 : -EFAULT;662}663 664static int acpi_suspend_state_valid(suspend_state_t pm_state)665{666 u32 acpi_state;667 668 switch (pm_state) {669 case PM_SUSPEND_ON:670 case PM_SUSPEND_STANDBY:671 case PM_SUSPEND_MEM:672 acpi_state = acpi_suspend_states[pm_state];673 674 return sleep_states[acpi_state];675 default:676 return 0;677 }678}679 680static const struct platform_suspend_ops acpi_suspend_ops = {681 .valid = acpi_suspend_state_valid,682 .begin = acpi_suspend_begin,683 .prepare_late = acpi_pm_prepare,684 .enter = acpi_suspend_enter,685 .wake = acpi_pm_finish,686 .end = acpi_pm_end,687};688 689/**690 * acpi_suspend_begin_old - Set the target system sleep state to the691 * state associated with given @pm_state, if supported, and692 * execute the _PTS control method. This function is used if the693 * pre-ACPI 2.0 suspend ordering has been requested.694 * @pm_state: The target suspend state for the system.695 */696static int acpi_suspend_begin_old(suspend_state_t pm_state)697{698 int error = acpi_suspend_begin(pm_state);699 if (!error)700 error = __acpi_pm_prepare();701 702 return error;703}704 705/*706 * The following callbacks are used if the pre-ACPI 2.0 suspend ordering has707 * been requested.708 */709static const struct platform_suspend_ops acpi_suspend_ops_old = {710 .valid = acpi_suspend_state_valid,711 .begin = acpi_suspend_begin_old,712 .prepare_late = acpi_pm_pre_suspend,713 .enter = acpi_suspend_enter,714 .wake = acpi_pm_finish,715 .end = acpi_pm_end,716 .recover = acpi_pm_finish,717};718 719static bool s2idle_wakeup;720 721int acpi_s2idle_begin(void)722{723 acpi_scan_lock_acquire();724 return 0;725}726 727int acpi_s2idle_prepare(void)728{729 if (acpi_sci_irq_valid()) {730 int error;731 732 error = enable_irq_wake(acpi_sci_irq);733 if (error)734 pr_warn("Warning: Failed to enable wakeup from IRQ %d: %d\n",735 acpi_sci_irq, error);736 737 acpi_ec_set_gpe_wake_mask(ACPI_GPE_ENABLE);738 }739 740 acpi_enable_wakeup_devices(ACPI_STATE_S0);741 742 /* Change the configuration of GPEs to avoid spurious wakeup. */743 acpi_enable_all_wakeup_gpes();744 acpi_os_wait_events_complete();745 746 s2idle_wakeup = true;747 return 0;748}749 750bool acpi_s2idle_wake(void)751{752 if (!acpi_sci_irq_valid())753 return pm_wakeup_pending();754 755 while (pm_wakeup_pending()) {756 /*757 * If IRQD_WAKEUP_ARMED is set for the SCI at this point, the758 * SCI has not triggered while suspended, so bail out (the759 * wakeup is pending anyway and the SCI is not the source of760 * it).761 */762 if (irqd_is_wakeup_armed(irq_get_irq_data(acpi_sci_irq))) {763 pm_pr_dbg("Wakeup unrelated to ACPI SCI\n");764 return true;765 }766 767 /*768 * If the status bit of any enabled fixed event is set, the769 * wakeup is regarded as valid.770 */771 if (acpi_any_fixed_event_status_set()) {772 pm_pr_dbg("ACPI fixed event wakeup\n");773 return true;774 }775 776 /* Check wakeups from drivers sharing the SCI. */777 if (acpi_check_wakeup_handlers()) {778 pm_pr_dbg("ACPI custom handler wakeup\n");779 return true;780 }781 782 /*783 * Check non-EC GPE wakeups and if there are none, cancel the784 * SCI-related wakeup and dispatch the EC GPE.785 */786 if (acpi_ec_dispatch_gpe()) {787 pm_pr_dbg("ACPI non-EC GPE wakeup\n");788 return true;789 }790 791 acpi_os_wait_events_complete();792 793 /*794 * The SCI is in the "suspended" state now and it cannot produce795 * new wakeup events till the rearming below, so if any of them796 * are pending here, they must be resulting from the processing797 * of EC events above or coming from somewhere else.798 */799 if (pm_wakeup_pending()) {800 pm_pr_dbg("Wakeup after ACPI Notify sync\n");801 return true;802 }803 804 pm_pr_dbg("Rearming ACPI SCI for wakeup\n");805 806 pm_wakeup_clear(acpi_sci_irq);807 rearm_wake_irq(acpi_sci_irq);808 }809 810 return false;811}812 813void acpi_s2idle_restore(void)814{815 /*816 * Drain pending events before restoring the working-state configuration817 * of GPEs.818 */819 acpi_os_wait_events_complete(); /* synchronize GPE processing */820 acpi_ec_flush_work(); /* flush the EC driver's workqueues */821 acpi_os_wait_events_complete(); /* synchronize Notify handling */822 823 s2idle_wakeup = false;824 825 acpi_enable_all_runtime_gpes();826 827 acpi_disable_wakeup_devices(ACPI_STATE_S0);828 829 if (acpi_sci_irq_valid()) {830 acpi_ec_set_gpe_wake_mask(ACPI_GPE_DISABLE);831 disable_irq_wake(acpi_sci_irq);832 }833}834 835void acpi_s2idle_end(void)836{837 acpi_scan_lock_release();838}839 840static const struct platform_s2idle_ops acpi_s2idle_ops = {841 .begin = acpi_s2idle_begin,842 .prepare = acpi_s2idle_prepare,843 .wake = acpi_s2idle_wake,844 .restore = acpi_s2idle_restore,845 .end = acpi_s2idle_end,846};847 848void __weak acpi_s2idle_setup(void)849{850 if (acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0)851 pr_info("Efficient low-power S0 idle declared\n");852 853 s2idle_set_ops(&acpi_s2idle_ops);854}855 856static void __init acpi_sleep_suspend_setup(void)857{858 bool suspend_ops_needed = false;859 int i;860 861 for (i = ACPI_STATE_S1; i < ACPI_STATE_S4; i++)862 if (acpi_sleep_state_supported(i)) {863 sleep_states[i] = 1;864 suspend_ops_needed = true;865 }866 867 if (suspend_ops_needed)868 suspend_set_ops(old_suspend_ordering ?869 &acpi_suspend_ops_old : &acpi_suspend_ops);870 871 acpi_s2idle_setup();872}873 874#else /* !CONFIG_SUSPEND */875#define s2idle_wakeup (false)876static inline void acpi_sleep_suspend_setup(void) {}877#endif /* !CONFIG_SUSPEND */878 879bool acpi_s2idle_wakeup(void)880{881 return s2idle_wakeup;882}883 884#ifdef CONFIG_PM_SLEEP885static u32 saved_bm_rld;886 887static int acpi_save_bm_rld(void)888{889 acpi_read_bit_register(ACPI_BITREG_BUS_MASTER_RLD, &saved_bm_rld);890 return 0;891}892 893static void acpi_restore_bm_rld(void)894{895 u32 resumed_bm_rld = 0;896 897 acpi_read_bit_register(ACPI_BITREG_BUS_MASTER_RLD, &resumed_bm_rld);898 if (resumed_bm_rld == saved_bm_rld)899 return;900 901 acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_RLD, saved_bm_rld);902}903 904static struct syscore_ops acpi_sleep_syscore_ops = {905 .suspend = acpi_save_bm_rld,906 .resume = acpi_restore_bm_rld,907};908 909static void acpi_sleep_syscore_init(void)910{911 register_syscore_ops(&acpi_sleep_syscore_ops);912}913#else914static inline void acpi_sleep_syscore_init(void) {}915#endif /* CONFIG_PM_SLEEP */916 917#ifdef CONFIG_HIBERNATION918static unsigned long s4_hardware_signature;919static struct acpi_table_facs *facs;920int acpi_check_s4_hw_signature = -1; /* Default behaviour is just to warn */921 922static int acpi_hibernation_begin(pm_message_t stage)923{924 if (!nvs_nosave) {925 int error = suspend_nvs_alloc();926 if (error)927 return error;928 }929 930 if (stage.event == PM_EVENT_HIBERNATE)931 pm_set_suspend_via_firmware();932 933 acpi_pm_start(ACPI_STATE_S4);934 return 0;935}936 937static int acpi_hibernation_enter(void)938{939 acpi_status status = AE_OK;940 941 /* This shouldn't return. If it returns, we have a problem */942 status = acpi_enter_sleep_state(ACPI_STATE_S4);943 /* Reprogram control registers */944 acpi_leave_sleep_state_prep(ACPI_STATE_S4);945 946 return ACPI_SUCCESS(status) ? 0 : -EFAULT;947}948 949static void acpi_hibernation_leave(void)950{951 pm_set_resume_via_firmware();952 /*953 * If ACPI is not enabled by the BIOS and the boot kernel, we need to954 * enable it here.955 */956 acpi_enable();957 /* Reprogram control registers */958 acpi_leave_sleep_state_prep(ACPI_STATE_S4);959 /* Check the hardware signature */960 if (facs && s4_hardware_signature != facs->hardware_signature)961 pr_crit("Hardware changed while hibernated, success doubtful!\n");962 /* Restore the NVS memory area */963 suspend_nvs_restore();964 /* Allow EC transactions to happen. */965 acpi_ec_unblock_transactions();966}967 968static void acpi_pm_thaw(void)969{970 acpi_ec_unblock_transactions();971 acpi_enable_all_runtime_gpes();972}973 974static const struct platform_hibernation_ops acpi_hibernation_ops = {975 .begin = acpi_hibernation_begin,976 .end = acpi_pm_end,977 .pre_snapshot = acpi_pm_prepare,978 .finish = acpi_pm_finish,979 .prepare = acpi_pm_prepare,980 .enter = acpi_hibernation_enter,981 .leave = acpi_hibernation_leave,982 .pre_restore = acpi_pm_freeze,983 .restore_cleanup = acpi_pm_thaw,984};985 986/**987 * acpi_hibernation_begin_old - Set the target system sleep state to988 * ACPI_STATE_S4 and execute the _PTS control method. This989 * function is used if the pre-ACPI 2.0 suspend ordering has been990 * requested.991 * @stage: The power management event message.992 */993static int acpi_hibernation_begin_old(pm_message_t stage)994{995 int error;996 /*997 * The _TTS object should always be evaluated before the _PTS object.998 * When the old_suspended_ordering is true, the _PTS object is999 * evaluated in the acpi_sleep_prepare.1000 */1001 acpi_sleep_tts_switch(ACPI_STATE_S4);1002 1003 error = acpi_sleep_prepare(ACPI_STATE_S4);1004 if (error)1005 return error;1006 1007 if (!nvs_nosave) {1008 error = suspend_nvs_alloc();1009 if (error)1010 return error;1011 }1012 1013 if (stage.event == PM_EVENT_HIBERNATE)1014 pm_set_suspend_via_firmware();1015 1016 acpi_target_sleep_state = ACPI_STATE_S4;1017 acpi_scan_lock_acquire();1018 return 0;1019}1020 1021/*1022 * The following callbacks are used if the pre-ACPI 2.0 suspend ordering has1023 * been requested.1024 */1025static const struct platform_hibernation_ops acpi_hibernation_ops_old = {1026 .begin = acpi_hibernation_begin_old,1027 .end = acpi_pm_end,1028 .pre_snapshot = acpi_pm_pre_suspend,1029 .prepare = acpi_pm_freeze,1030 .finish = acpi_pm_finish,1031 .enter = acpi_hibernation_enter,1032 .leave = acpi_hibernation_leave,1033 .pre_restore = acpi_pm_freeze,1034 .restore_cleanup = acpi_pm_thaw,1035 .recover = acpi_pm_finish,1036};1037 1038static void acpi_sleep_hibernate_setup(void)1039{1040 if (!acpi_sleep_state_supported(ACPI_STATE_S4))1041 return;1042 1043 hibernation_set_ops(old_suspend_ordering ?1044 &acpi_hibernation_ops_old : &acpi_hibernation_ops);1045 sleep_states[ACPI_STATE_S4] = 1;1046 if (!acpi_check_s4_hw_signature)1047 return;1048 1049 acpi_get_table(ACPI_SIG_FACS, 1, (struct acpi_table_header **)&facs);1050 if (facs) {1051 /*1052 * s4_hardware_signature is the local variable which is just1053 * used to warn about mismatch after we're attempting to1054 * resume (in violation of the ACPI specification.)1055 */1056 s4_hardware_signature = facs->hardware_signature;1057 1058 if (acpi_check_s4_hw_signature > 0) {1059 /*1060 * If we're actually obeying the ACPI specification1061 * then the signature is written out as part of the1062 * swsusp header, in order to allow the boot kernel1063 * to gracefully decline to resume.1064 */1065 swsusp_hardware_signature = facs->hardware_signature;1066 }1067 }1068}1069#else /* !CONFIG_HIBERNATION */1070static inline void acpi_sleep_hibernate_setup(void) {}1071#endif /* !CONFIG_HIBERNATION */1072 1073static int acpi_power_off_prepare(struct sys_off_data *data)1074{1075 /* Prepare to power off the system */1076 acpi_sleep_prepare(ACPI_STATE_S5);1077 acpi_disable_all_gpes();1078 acpi_os_wait_events_complete();1079 return NOTIFY_DONE;1080}1081 1082static int acpi_power_off(struct sys_off_data *data)1083{1084 /* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */1085 pr_debug("%s called\n", __func__);1086 local_irq_disable();1087 acpi_enter_sleep_state(ACPI_STATE_S5);1088 return NOTIFY_DONE;1089}1090 1091int __init acpi_sleep_init(void)1092{1093 char supported[ACPI_S_STATE_COUNT * 3 + 1];1094 char *pos = supported;1095 int i;1096 1097 acpi_sleep_dmi_check();1098 1099 sleep_states[ACPI_STATE_S0] = 1;1100 1101 acpi_sleep_syscore_init();1102 acpi_sleep_suspend_setup();1103 acpi_sleep_hibernate_setup();1104 1105 if (acpi_sleep_state_supported(ACPI_STATE_S5)) {1106 sleep_states[ACPI_STATE_S5] = 1;1107 1108 register_sys_off_handler(SYS_OFF_MODE_POWER_OFF_PREPARE,1109 SYS_OFF_PRIO_FIRMWARE,1110 acpi_power_off_prepare, NULL);1111 1112 register_sys_off_handler(SYS_OFF_MODE_POWER_OFF,1113 SYS_OFF_PRIO_FIRMWARE,1114 acpi_power_off, NULL);1115 1116 /*1117 * Windows uses S5 for reboot, so some BIOSes depend on it to1118 * perform proper reboot.1119 */1120 register_sys_off_handler(SYS_OFF_MODE_RESTART_PREPARE,1121 SYS_OFF_PRIO_FIRMWARE,1122 acpi_power_off_prepare, NULL);1123 } else {1124 acpi_no_s5 = true;1125 }1126 1127 supported[0] = 0;1128 for (i = 0; i < ACPI_S_STATE_COUNT; i++) {1129 if (sleep_states[i])1130 pos += sprintf(pos, " S%d", i);1131 }1132 pr_info("(supports%s)\n", supported);1133 1134 /*1135 * Register the tts_notifier to reboot notifier list so that the _TTS1136 * object can also be evaluated when the system enters S5.1137 */1138 register_reboot_notifier(&tts_notifier);1139 return 0;1140}1141