0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #define EXPORT_ACPI_INTERFACES
0011
0012 #include <acpi/acpi.h>
0013 #include "accommon.h"
0014
0015 #define _COMPONENT ACPI_HARDWARE
0016 ACPI_MODULE_NAME("hwxfsleep")
0017
0018
0019 #if (!ACPI_REDUCED_HARDWARE)
0020 static acpi_status
0021 acpi_hw_set_firmware_waking_vector(struct acpi_table_facs *facs,
0022 acpi_physical_address physical_address,
0023 acpi_physical_address physical_address64);
0024 #endif
0025
0026
0027
0028
0029
0030
0031
0032 #if (!ACPI_REDUCED_HARDWARE)
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049 static acpi_status
0050 acpi_hw_set_firmware_waking_vector(struct acpi_table_facs *facs,
0051 acpi_physical_address physical_address,
0052 acpi_physical_address physical_address64)
0053 {
0054 ACPI_FUNCTION_TRACE(acpi_hw_set_firmware_waking_vector);
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067 facs->firmware_waking_vector = (u32)physical_address;
0068
0069 if (facs->length > 32) {
0070 if (facs->version >= 1) {
0071
0072
0073
0074 facs->xfirmware_waking_vector = physical_address64;
0075 } else {
0076
0077
0078 facs->xfirmware_waking_vector = 0;
0079 }
0080 }
0081
0082 return_ACPI_STATUS(AE_OK);
0083 }
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100 acpi_status
0101 acpi_set_firmware_waking_vector(acpi_physical_address physical_address,
0102 acpi_physical_address physical_address64)
0103 {
0104
0105 ACPI_FUNCTION_TRACE(acpi_set_firmware_waking_vector);
0106
0107 if (acpi_gbl_FACS) {
0108 (void)acpi_hw_set_firmware_waking_vector(acpi_gbl_FACS,
0109 physical_address,
0110 physical_address64);
0111 }
0112
0113 return_ACPI_STATUS(AE_OK);
0114 }
0115
0116 ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector)
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130 acpi_status acpi_enter_sleep_state_s4bios(void)
0131 {
0132 u32 in_value;
0133 acpi_status status;
0134
0135 ACPI_FUNCTION_TRACE(acpi_enter_sleep_state_s4bios);
0136
0137
0138
0139 status =
0140 acpi_write_bit_register(ACPI_BITREG_WAKE_STATUS, ACPI_CLEAR_STATUS);
0141 if (ACPI_FAILURE(status)) {
0142 return_ACPI_STATUS(status);
0143 }
0144
0145 status = acpi_hw_clear_acpi_status();
0146 if (ACPI_FAILURE(status)) {
0147 return_ACPI_STATUS(status);
0148 }
0149
0150
0151
0152
0153
0154 status = acpi_hw_disable_all_gpes();
0155 if (ACPI_FAILURE(status)) {
0156 return_ACPI_STATUS(status);
0157 }
0158 acpi_gbl_system_awake_and_running = FALSE;
0159
0160 status = acpi_hw_enable_all_wakeup_gpes();
0161 if (ACPI_FAILURE(status)) {
0162 return_ACPI_STATUS(status);
0163 }
0164
0165 status = acpi_hw_write_port(acpi_gbl_FADT.smi_command,
0166 (u32)acpi_gbl_FADT.s4_bios_request, 8);
0167 if (ACPI_FAILURE(status)) {
0168 return_ACPI_STATUS(status);
0169 }
0170
0171 do {
0172 acpi_os_stall(ACPI_USEC_PER_MSEC);
0173 status =
0174 acpi_read_bit_register(ACPI_BITREG_WAKE_STATUS, &in_value);
0175 if (ACPI_FAILURE(status)) {
0176 return_ACPI_STATUS(status);
0177 }
0178
0179 } while (!in_value);
0180
0181 return_ACPI_STATUS(AE_OK);
0182 }
0183
0184 ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_s4bios)
0185 #endif
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202 acpi_status acpi_enter_sleep_state_prep(u8 sleep_state)
0203 {
0204 acpi_status status;
0205 struct acpi_object_list arg_list;
0206 union acpi_object arg;
0207 u32 sst_value;
0208
0209 ACPI_FUNCTION_TRACE(acpi_enter_sleep_state_prep);
0210
0211 status = acpi_get_sleep_type_data(sleep_state,
0212 &acpi_gbl_sleep_type_a,
0213 &acpi_gbl_sleep_type_b);
0214 if (ACPI_FAILURE(status)) {
0215 return_ACPI_STATUS(status);
0216 }
0217
0218 status = acpi_get_sleep_type_data(ACPI_STATE_S0,
0219 &acpi_gbl_sleep_type_a_s0,
0220 &acpi_gbl_sleep_type_b_s0);
0221 if (ACPI_FAILURE(status)) {
0222 acpi_gbl_sleep_type_a_s0 = ACPI_SLEEP_TYPE_INVALID;
0223 }
0224
0225
0226
0227 arg_list.count = 1;
0228 arg_list.pointer = &arg;
0229 arg.type = ACPI_TYPE_INTEGER;
0230 arg.integer.value = sleep_state;
0231
0232 status =
0233 acpi_evaluate_object(NULL, METHOD_PATHNAME__PTS, &arg_list, NULL);
0234 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
0235 return_ACPI_STATUS(status);
0236 }
0237
0238
0239
0240 switch (sleep_state) {
0241 case ACPI_STATE_S0:
0242
0243 sst_value = ACPI_SST_WORKING;
0244 break;
0245
0246 case ACPI_STATE_S1:
0247 case ACPI_STATE_S2:
0248 case ACPI_STATE_S3:
0249
0250 sst_value = ACPI_SST_SLEEPING;
0251 break;
0252
0253 case ACPI_STATE_S4:
0254
0255 sst_value = ACPI_SST_SLEEP_CONTEXT;
0256 break;
0257
0258 default:
0259
0260 sst_value = ACPI_SST_INDICATOR_OFF;
0261 break;
0262 }
0263
0264
0265
0266
0267
0268 acpi_hw_execute_sleep_method(METHOD_PATHNAME__SST, sst_value);
0269 return_ACPI_STATUS(AE_OK);
0270 }
0271
0272 ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_prep)
0273
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284
0285
0286 acpi_status acpi_enter_sleep_state(u8 sleep_state)
0287 {
0288 acpi_status status;
0289
0290 ACPI_FUNCTION_TRACE(acpi_enter_sleep_state);
0291
0292 if ((acpi_gbl_sleep_type_a > ACPI_SLEEP_TYPE_MAX) ||
0293 (acpi_gbl_sleep_type_b > ACPI_SLEEP_TYPE_MAX)) {
0294 ACPI_ERROR((AE_INFO, "Sleep values out of range: A=0x%X B=0x%X",
0295 acpi_gbl_sleep_type_a, acpi_gbl_sleep_type_b));
0296 return_ACPI_STATUS(AE_AML_OPERAND_VALUE);
0297 }
0298
0299 #if !ACPI_REDUCED_HARDWARE
0300 if (!acpi_gbl_reduced_hardware)
0301 status = acpi_hw_legacy_sleep(sleep_state);
0302 else
0303 #endif
0304 status = acpi_hw_extended_sleep(sleep_state);
0305 return_ACPI_STATUS(status);
0306 }
0307
0308 ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state)
0309
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323
0324 acpi_status acpi_leave_sleep_state_prep(u8 sleep_state)
0325 {
0326 acpi_status status;
0327
0328 ACPI_FUNCTION_TRACE(acpi_leave_sleep_state_prep);
0329
0330 #if !ACPI_REDUCED_HARDWARE
0331 if (!acpi_gbl_reduced_hardware)
0332 status = acpi_hw_legacy_wake_prep(sleep_state);
0333 else
0334 #endif
0335 status = acpi_hw_extended_wake_prep(sleep_state);
0336 return_ACPI_STATUS(status);
0337 }
0338
0339 ACPI_EXPORT_SYMBOL(acpi_leave_sleep_state_prep)
0340
0341
0342
0343
0344
0345
0346
0347
0348
0349
0350
0351
0352
0353 acpi_status acpi_leave_sleep_state(u8 sleep_state)
0354 {
0355 acpi_status status;
0356
0357 ACPI_FUNCTION_TRACE(acpi_leave_sleep_state);
0358
0359 #if !ACPI_REDUCED_HARDWARE
0360 if (!acpi_gbl_reduced_hardware)
0361 status = acpi_hw_legacy_wake(sleep_state);
0362 else
0363 #endif
0364 status = acpi_hw_extended_wake(sleep_state);
0365 return_ACPI_STATUS(status);
0366 }
0367
0368 ACPI_EXPORT_SYMBOL(acpi_leave_sleep_state)