0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <acpi/acpi.h>
0012 #include "accommon.h"
0013
0014 #define _COMPONENT ACPI_HARDWARE
0015 ACPI_MODULE_NAME("hwesleep")
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030 void acpi_hw_execute_sleep_method(char *method_pathname, u32 integer_argument)
0031 {
0032 struct acpi_object_list arg_list;
0033 union acpi_object arg;
0034 acpi_status status;
0035
0036 ACPI_FUNCTION_TRACE(hw_execute_sleep_method);
0037
0038
0039
0040 arg_list.count = 1;
0041 arg_list.pointer = &arg;
0042 arg.type = ACPI_TYPE_INTEGER;
0043 arg.integer.value = (u64)integer_argument;
0044
0045 status = acpi_evaluate_object(NULL, method_pathname, &arg_list, NULL);
0046 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
0047 ACPI_EXCEPTION((AE_INFO, status, "While executing method %s",
0048 method_pathname));
0049 }
0050
0051 return_VOID;
0052 }
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068 acpi_status acpi_hw_extended_sleep(u8 sleep_state)
0069 {
0070 acpi_status status;
0071 u8 sleep_control;
0072 u64 sleep_status;
0073
0074 ACPI_FUNCTION_TRACE(hw_extended_sleep);
0075
0076
0077
0078 if (!acpi_gbl_FADT.sleep_control.address ||
0079 !acpi_gbl_FADT.sleep_status.address) {
0080 return_ACPI_STATUS(AE_NOT_EXIST);
0081 }
0082
0083
0084
0085 status = acpi_write((u64)ACPI_X_WAKE_STATUS,
0086 &acpi_gbl_FADT.sleep_status);
0087 if (ACPI_FAILURE(status)) {
0088 return_ACPI_STATUS(status);
0089 }
0090
0091 acpi_gbl_system_awake_and_running = FALSE;
0092
0093
0094
0095
0096
0097
0098
0099 ACPI_DEBUG_PRINT((ACPI_DB_INIT,
0100 "Entering sleep state [S%u]\n", sleep_state));
0101
0102 sleep_control = ((acpi_gbl_sleep_type_a << ACPI_X_SLEEP_TYPE_POSITION) &
0103 ACPI_X_SLEEP_TYPE_MASK) | ACPI_X_SLEEP_ENABLE;
0104
0105
0106
0107 if (sleep_state < ACPI_STATE_S4) {
0108 ACPI_FLUSH_CPU_CACHE();
0109 }
0110
0111 status = acpi_os_enter_sleep(sleep_state, sleep_control, 0);
0112 if (status == AE_CTRL_TERMINATE) {
0113 return_ACPI_STATUS(AE_OK);
0114 }
0115 if (ACPI_FAILURE(status)) {
0116 return_ACPI_STATUS(status);
0117 }
0118
0119 status = acpi_write((u64)sleep_control, &acpi_gbl_FADT.sleep_control);
0120 if (ACPI_FAILURE(status)) {
0121 return_ACPI_STATUS(status);
0122 }
0123
0124
0125
0126 do {
0127 status = acpi_read(&sleep_status, &acpi_gbl_FADT.sleep_status);
0128 if (ACPI_FAILURE(status)) {
0129 return_ACPI_STATUS(status);
0130 }
0131
0132 } while (!(((u8)sleep_status) & ACPI_X_WAKE_STATUS));
0133
0134 return_ACPI_STATUS(AE_OK);
0135 }
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150 acpi_status acpi_hw_extended_wake_prep(u8 sleep_state)
0151 {
0152 u8 sleep_type_value;
0153
0154 ACPI_FUNCTION_TRACE(hw_extended_wake_prep);
0155
0156 if (acpi_gbl_sleep_type_a_s0 != ACPI_SLEEP_TYPE_INVALID) {
0157 sleep_type_value =
0158 ((acpi_gbl_sleep_type_a_s0 << ACPI_X_SLEEP_TYPE_POSITION) &
0159 ACPI_X_SLEEP_TYPE_MASK);
0160
0161 (void)acpi_write((u64)(sleep_type_value | ACPI_X_SLEEP_ENABLE),
0162 &acpi_gbl_FADT.sleep_control);
0163 }
0164
0165 return_ACPI_STATUS(AE_OK);
0166 }
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181 acpi_status acpi_hw_extended_wake(u8 sleep_state)
0182 {
0183 ACPI_FUNCTION_TRACE(hw_extended_wake);
0184
0185
0186
0187 acpi_gbl_sleep_type_a = ACPI_SLEEP_TYPE_INVALID;
0188
0189
0190
0191 acpi_hw_execute_sleep_method(METHOD_PATHNAME__SST, ACPI_SST_WAKING);
0192 acpi_hw_execute_sleep_method(METHOD_PATHNAME__WAK, sleep_state);
0193
0194
0195
0196
0197
0198
0199 (void)acpi_write((u64)ACPI_X_WAKE_STATUS, &acpi_gbl_FADT.sleep_status);
0200 acpi_gbl_system_awake_and_running = TRUE;
0201
0202 acpi_hw_execute_sleep_method(METHOD_PATHNAME__SST, ACPI_SST_WORKING);
0203 return_ACPI_STATUS(AE_OK);
0204 }