LCOV - code coverage report
Current view: top level - drivers/acpi - sleep.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 58 411 14.1 %
Date: 2022-04-01 13:59:58 Functions: 6 48 12.5 %
Branches: 20 181 11.0 %

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

Generated by: LCOV version 1.14