root/drivers/acpi/acpica/hwxfsleep.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ACPI_MODULE_NAME
  2. acpi_set_firmware_waking_vector
  3. ACPI_EXPORT_SYMBOL
  4. ACPI_EXPORT_SYMBOL
  5. ACPI_EXPORT_SYMBOL
  6. ACPI_EXPORT_SYMBOL
  7. ACPI_EXPORT_SYMBOL

   1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
   2 /******************************************************************************
   3  *
   4  * Name: hwxfsleep.c - ACPI Hardware Sleep/Wake External Interfaces
   5  *
   6  * Copyright (C) 2000 - 2019, Intel Corp.
   7  *
   8  *****************************************************************************/
   9 
  10 #define EXPORT_ACPI_INTERFACES
  11 
  12 #include <acpi/acpi.h>
  13 #include "accommon.h"
  14 
  15 #define _COMPONENT          ACPI_HARDWARE
  16 ACPI_MODULE_NAME("hwxfsleep")
  17 
  18 /* Local prototypes */
  19 #if (!ACPI_REDUCED_HARDWARE)
  20 static acpi_status
  21 acpi_hw_set_firmware_waking_vector(struct acpi_table_facs *facs,
  22                                    acpi_physical_address physical_address,
  23                                    acpi_physical_address physical_address64);
  24 #endif
  25 
  26 /*
  27  * These functions are removed for the ACPI_REDUCED_HARDWARE case:
  28  *      acpi_set_firmware_waking_vector
  29  *      acpi_enter_sleep_state_s4bios
  30  */
  31 
  32 #if (!ACPI_REDUCED_HARDWARE)
  33 /*******************************************************************************
  34  *
  35  * FUNCTION:    acpi_hw_set_firmware_waking_vector
  36  *
  37  * PARAMETERS:  facs                - Pointer to FACS table
  38  *              physical_address    - 32-bit physical address of ACPI real mode
  39  *                                    entry point
  40  *              physical_address64  - 64-bit physical address of ACPI protected
  41  *                                    mode entry point
  42  *
  43  * RETURN:      Status
  44  *
  45  * DESCRIPTION: Sets the firmware_waking_vector fields of the FACS
  46  *
  47  ******************************************************************************/
  48 
  49 static acpi_status
  50 acpi_hw_set_firmware_waking_vector(struct acpi_table_facs *facs,
  51                                    acpi_physical_address physical_address,
  52                                    acpi_physical_address physical_address64)
  53 {
  54         ACPI_FUNCTION_TRACE(acpi_hw_set_firmware_waking_vector);
  55 
  56 
  57         /*
  58          * According to the ACPI specification 2.0c and later, the 64-bit
  59          * waking vector should be cleared and the 32-bit waking vector should
  60          * be used, unless we want the wake-up code to be called by the BIOS in
  61          * Protected Mode.  Some systems (for example HP dv5-1004nr) are known
  62          * to fail to resume if the 64-bit vector is used.
  63          */
  64 
  65         /* Set the 32-bit vector */
  66 
  67         facs->firmware_waking_vector = (u32)physical_address;
  68 
  69         if (facs->length > 32) {
  70                 if (facs->version >= 1) {
  71 
  72                         /* Set the 64-bit vector */
  73 
  74                         facs->xfirmware_waking_vector = physical_address64;
  75                 } else {
  76                         /* Clear the 64-bit vector if it exists */
  77 
  78                         facs->xfirmware_waking_vector = 0;
  79                 }
  80         }
  81 
  82         return_ACPI_STATUS(AE_OK);
  83 }
  84 
  85 /*******************************************************************************
  86  *
  87  * FUNCTION:    acpi_set_firmware_waking_vector
  88  *
  89  * PARAMETERS:  physical_address    - 32-bit physical address of ACPI real mode
  90  *                                    entry point
  91  *              physical_address64  - 64-bit physical address of ACPI protected
  92  *                                    mode entry point
  93  *
  94  * RETURN:      Status
  95  *
  96  * DESCRIPTION: Sets the firmware_waking_vector fields of the FACS
  97  *
  98  ******************************************************************************/
  99 
 100 acpi_status
 101 acpi_set_firmware_waking_vector(acpi_physical_address physical_address,
 102                                 acpi_physical_address physical_address64)
 103 {
 104 
 105         ACPI_FUNCTION_TRACE(acpi_set_firmware_waking_vector);
 106 
 107         if (acpi_gbl_FACS) {
 108                 (void)acpi_hw_set_firmware_waking_vector(acpi_gbl_FACS,
 109                                                          physical_address,
 110                                                          physical_address64);
 111         }
 112 
 113         return_ACPI_STATUS(AE_OK);
 114 }
 115 
 116 ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector)
 117 
 118 /*******************************************************************************
 119  *
 120  * FUNCTION:    acpi_enter_sleep_state_s4bios
 121  *
 122  * PARAMETERS:  None
 123  *
 124  * RETURN:      Status
 125  *
 126  * DESCRIPTION: Perform a S4 bios request.
 127  *              THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED
 128  *
 129  ******************************************************************************/
 130 acpi_status acpi_enter_sleep_state_s4bios(void)
 131 {
 132         u32 in_value;
 133         acpi_status status;
 134 
 135         ACPI_FUNCTION_TRACE(acpi_enter_sleep_state_s4bios);
 136 
 137         /* Clear the wake status bit (PM1) */
 138 
 139         status =
 140             acpi_write_bit_register(ACPI_BITREG_WAKE_STATUS, ACPI_CLEAR_STATUS);
 141         if (ACPI_FAILURE(status)) {
 142                 return_ACPI_STATUS(status);
 143         }
 144 
 145         status = acpi_hw_clear_acpi_status();
 146         if (ACPI_FAILURE(status)) {
 147                 return_ACPI_STATUS(status);
 148         }
 149 
 150         /*
 151          * 1) Disable all GPEs
 152          * 2) Enable all wakeup GPEs
 153          */
 154         status = acpi_hw_disable_all_gpes();
 155         if (ACPI_FAILURE(status)) {
 156                 return_ACPI_STATUS(status);
 157         }
 158         acpi_gbl_system_awake_and_running = FALSE;
 159 
 160         status = acpi_hw_enable_all_wakeup_gpes();
 161         if (ACPI_FAILURE(status)) {
 162                 return_ACPI_STATUS(status);
 163         }
 164 
 165         ACPI_FLUSH_CPU_CACHE();
 166 
 167         status = acpi_hw_write_port(acpi_gbl_FADT.smi_command,
 168                                     (u32)acpi_gbl_FADT.s4_bios_request, 8);
 169 
 170         do {
 171                 acpi_os_stall(ACPI_USEC_PER_MSEC);
 172                 status =
 173                     acpi_read_bit_register(ACPI_BITREG_WAKE_STATUS, &in_value);
 174                 if (ACPI_FAILURE(status)) {
 175                         return_ACPI_STATUS(status);
 176                 }
 177 
 178         } while (!in_value);
 179 
 180         return_ACPI_STATUS(AE_OK);
 181 }
 182 
 183 ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_s4bios)
 184 #endif                          /* !ACPI_REDUCED_HARDWARE */
 185 
 186 /*******************************************************************************
 187  *
 188  * FUNCTION:    acpi_enter_sleep_state_prep
 189  *
 190  * PARAMETERS:  sleep_state         - Which sleep state to enter
 191  *
 192  * RETURN:      Status
 193  *
 194  * DESCRIPTION: Prepare to enter a system sleep state.
 195  *              This function must execute with interrupts enabled.
 196  *              We break sleeping into 2 stages so that OSPM can handle
 197  *              various OS-specific tasks between the two steps.
 198  *
 199  ******************************************************************************/
 200 
 201 acpi_status acpi_enter_sleep_state_prep(u8 sleep_state)
 202 {
 203         acpi_status status;
 204         struct acpi_object_list arg_list;
 205         union acpi_object arg;
 206         u32 sst_value;
 207 
 208         ACPI_FUNCTION_TRACE(acpi_enter_sleep_state_prep);
 209 
 210         status = acpi_get_sleep_type_data(sleep_state,
 211                                           &acpi_gbl_sleep_type_a,
 212                                           &acpi_gbl_sleep_type_b);
 213         if (ACPI_FAILURE(status)) {
 214                 return_ACPI_STATUS(status);
 215         }
 216 
 217         /* Execute the _PTS method (Prepare To Sleep) */
 218 
 219         arg_list.count = 1;
 220         arg_list.pointer = &arg;
 221         arg.type = ACPI_TYPE_INTEGER;
 222         arg.integer.value = sleep_state;
 223 
 224         status =
 225             acpi_evaluate_object(NULL, METHOD_PATHNAME__PTS, &arg_list, NULL);
 226         if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
 227                 return_ACPI_STATUS(status);
 228         }
 229 
 230         /* Setup the argument to the _SST method (System STatus) */
 231 
 232         switch (sleep_state) {
 233         case ACPI_STATE_S0:
 234 
 235                 sst_value = ACPI_SST_WORKING;
 236                 break;
 237 
 238         case ACPI_STATE_S1:
 239         case ACPI_STATE_S2:
 240         case ACPI_STATE_S3:
 241 
 242                 sst_value = ACPI_SST_SLEEPING;
 243                 break;
 244 
 245         case ACPI_STATE_S4:
 246 
 247                 sst_value = ACPI_SST_SLEEP_CONTEXT;
 248                 break;
 249 
 250         default:
 251 
 252                 sst_value = ACPI_SST_INDICATOR_OFF;     /* Default is off */
 253                 break;
 254         }
 255 
 256         /*
 257          * Set the system indicators to show the desired sleep state.
 258          * _SST is an optional method (return no error if not found)
 259          */
 260         acpi_hw_execute_sleep_method(METHOD_PATHNAME__SST, sst_value);
 261         return_ACPI_STATUS(AE_OK);
 262 }
 263 
 264 ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_prep)
 265 
 266 /*******************************************************************************
 267  *
 268  * FUNCTION:    acpi_enter_sleep_state
 269  *
 270  * PARAMETERS:  sleep_state         - Which sleep state to enter
 271  *
 272  * RETURN:      Status
 273  *
 274  * DESCRIPTION: Enter a system sleep state
 275  *              THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED
 276  *
 277  ******************************************************************************/
 278 acpi_status acpi_enter_sleep_state(u8 sleep_state)
 279 {
 280         acpi_status status;
 281 
 282         ACPI_FUNCTION_TRACE(acpi_enter_sleep_state);
 283 
 284         if ((acpi_gbl_sleep_type_a > ACPI_SLEEP_TYPE_MAX) ||
 285             (acpi_gbl_sleep_type_b > ACPI_SLEEP_TYPE_MAX)) {
 286                 ACPI_ERROR((AE_INFO, "Sleep values out of range: A=0x%X B=0x%X",
 287                             acpi_gbl_sleep_type_a, acpi_gbl_sleep_type_b));
 288                 return_ACPI_STATUS(AE_AML_OPERAND_VALUE);
 289         }
 290 
 291 #if !ACPI_REDUCED_HARDWARE
 292         if (!acpi_gbl_reduced_hardware)
 293                 status = acpi_hw_legacy_sleep(sleep_state);
 294         else
 295 #endif
 296                 status = acpi_hw_extended_sleep(sleep_state);
 297         return_ACPI_STATUS(status);
 298 }
 299 
 300 ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state)
 301 
 302 /*******************************************************************************
 303  *
 304  * FUNCTION:    acpi_leave_sleep_state_prep
 305  *
 306  * PARAMETERS:  sleep_state         - Which sleep state we are exiting
 307  *
 308  * RETURN:      Status
 309  *
 310  * DESCRIPTION: Perform the first state of OS-independent ACPI cleanup after a
 311  *              sleep. Called with interrupts DISABLED.
 312  *              We break wake/resume into 2 stages so that OSPM can handle
 313  *              various OS-specific tasks between the two steps.
 314  *
 315  ******************************************************************************/
 316 acpi_status acpi_leave_sleep_state_prep(u8 sleep_state)
 317 {
 318         acpi_status status;
 319 
 320         ACPI_FUNCTION_TRACE(acpi_leave_sleep_state_prep);
 321 
 322 #if !ACPI_REDUCED_HARDWARE
 323         if (!acpi_gbl_reduced_hardware)
 324                 status = acpi_hw_legacy_wake_prep(sleep_state);
 325         else
 326 #endif
 327                 status = acpi_hw_extended_wake_prep(sleep_state);
 328         return_ACPI_STATUS(status);
 329 }
 330 
 331 ACPI_EXPORT_SYMBOL(acpi_leave_sleep_state_prep)
 332 
 333 /*******************************************************************************
 334  *
 335  * FUNCTION:    acpi_leave_sleep_state
 336  *
 337  * PARAMETERS:  sleep_state         - Which sleep state we are exiting
 338  *
 339  * RETURN:      Status
 340  *
 341  * DESCRIPTION: Perform OS-independent ACPI cleanup after a sleep
 342  *              Called with interrupts ENABLED.
 343  *
 344  ******************************************************************************/
 345 acpi_status acpi_leave_sleep_state(u8 sleep_state)
 346 {
 347         acpi_status status;
 348 
 349         ACPI_FUNCTION_TRACE(acpi_leave_sleep_state);
 350 
 351 #if !ACPI_REDUCED_HARDWARE
 352         if (!acpi_gbl_reduced_hardware)
 353                 status = acpi_hw_legacy_wake(sleep_state);
 354         else
 355 #endif
 356                 status = acpi_hw_extended_wake(sleep_state);
 357         return_ACPI_STATUS(status);
 358 }
 359 
 360 ACPI_EXPORT_SYMBOL(acpi_leave_sleep_state)

/* [<][>][^][v][top][bottom][index][help] */