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("hwsleep")
0016
0017 #if (!ACPI_REDUCED_HARDWARE)
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030 acpi_status acpi_hw_legacy_sleep(u8 sleep_state)
0031 {
0032 struct acpi_bit_register_info *sleep_type_reg_info;
0033 struct acpi_bit_register_info *sleep_enable_reg_info;
0034 u32 pm1a_control;
0035 u32 pm1b_control;
0036 u32 in_value;
0037 acpi_status status;
0038
0039 ACPI_FUNCTION_TRACE(hw_legacy_sleep);
0040
0041 sleep_type_reg_info =
0042 acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_TYPE);
0043 sleep_enable_reg_info =
0044 acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_ENABLE);
0045
0046
0047
0048 status = acpi_write_bit_register(ACPI_BITREG_WAKE_STATUS,
0049 ACPI_CLEAR_STATUS);
0050 if (ACPI_FAILURE(status)) {
0051 return_ACPI_STATUS(status);
0052 }
0053
0054
0055 status = acpi_hw_disable_all_gpes();
0056 if (ACPI_FAILURE(status)) {
0057 return_ACPI_STATUS(status);
0058 }
0059 status = acpi_hw_clear_acpi_status();
0060 if (ACPI_FAILURE(status)) {
0061 return_ACPI_STATUS(status);
0062 }
0063 acpi_gbl_system_awake_and_running = FALSE;
0064
0065
0066 status = acpi_hw_enable_all_wakeup_gpes();
0067 if (ACPI_FAILURE(status)) {
0068 return_ACPI_STATUS(status);
0069 }
0070
0071
0072
0073 status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL,
0074 &pm1a_control);
0075 if (ACPI_FAILURE(status)) {
0076 return_ACPI_STATUS(status);
0077 }
0078 ACPI_DEBUG_PRINT((ACPI_DB_INIT,
0079 "Entering sleep state [S%u]\n", sleep_state));
0080
0081
0082
0083 pm1a_control &= ~(sleep_type_reg_info->access_bit_mask |
0084 sleep_enable_reg_info->access_bit_mask);
0085 pm1b_control = pm1a_control;
0086
0087
0088
0089 pm1a_control |=
0090 (acpi_gbl_sleep_type_a << sleep_type_reg_info->bit_position);
0091 pm1b_control |=
0092 (acpi_gbl_sleep_type_b << sleep_type_reg_info->bit_position);
0093
0094
0095
0096
0097
0098
0099
0100
0101 status = acpi_hw_write_pm1_control(pm1a_control, pm1b_control);
0102 if (ACPI_FAILURE(status)) {
0103 return_ACPI_STATUS(status);
0104 }
0105
0106
0107
0108 pm1a_control |= sleep_enable_reg_info->access_bit_mask;
0109 pm1b_control |= sleep_enable_reg_info->access_bit_mask;
0110
0111
0112
0113 if (sleep_state < ACPI_STATE_S4) {
0114 ACPI_FLUSH_CPU_CACHE();
0115 }
0116
0117 status = acpi_os_enter_sleep(sleep_state, pm1a_control, pm1b_control);
0118 if (status == AE_CTRL_TERMINATE) {
0119 return_ACPI_STATUS(AE_OK);
0120 }
0121 if (ACPI_FAILURE(status)) {
0122 return_ACPI_STATUS(status);
0123 }
0124
0125
0126
0127 status = acpi_hw_write_pm1_control(pm1a_control, pm1b_control);
0128 if (ACPI_FAILURE(status)) {
0129 return_ACPI_STATUS(status);
0130 }
0131
0132 if (sleep_state > ACPI_STATE_S3) {
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144 acpi_os_stall(10 * ACPI_USEC_PER_SEC);
0145
0146 status = acpi_hw_register_write(ACPI_REGISTER_PM1_CONTROL,
0147 sleep_enable_reg_info->
0148 access_bit_mask);
0149 if (ACPI_FAILURE(status)) {
0150 return_ACPI_STATUS(status);
0151 }
0152 }
0153
0154
0155
0156 do {
0157 status =
0158 acpi_read_bit_register(ACPI_BITREG_WAKE_STATUS, &in_value);
0159 if (ACPI_FAILURE(status)) {
0160 return_ACPI_STATUS(status);
0161 }
0162
0163 } while (!in_value);
0164
0165 return_ACPI_STATUS(AE_OK);
0166 }
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182 acpi_status acpi_hw_legacy_wake_prep(u8 sleep_state)
0183 {
0184 acpi_status status = AE_OK;
0185 struct acpi_bit_register_info *sleep_type_reg_info;
0186 struct acpi_bit_register_info *sleep_enable_reg_info;
0187 u32 pm1a_control;
0188 u32 pm1b_control;
0189
0190 ACPI_FUNCTION_TRACE(hw_legacy_wake_prep);
0191
0192
0193
0194
0195
0196
0197 if (acpi_gbl_sleep_type_a_s0 != ACPI_SLEEP_TYPE_INVALID) {
0198 sleep_type_reg_info =
0199 acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_TYPE);
0200 sleep_enable_reg_info =
0201 acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_ENABLE);
0202
0203
0204
0205 status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL,
0206 &pm1a_control);
0207 if (ACPI_SUCCESS(status)) {
0208
0209
0210
0211 pm1a_control &= ~(sleep_type_reg_info->access_bit_mask |
0212 sleep_enable_reg_info->
0213 access_bit_mask);
0214 pm1b_control = pm1a_control;
0215
0216
0217
0218 pm1a_control |= (acpi_gbl_sleep_type_a_s0 <<
0219 sleep_type_reg_info->bit_position);
0220 pm1b_control |= (acpi_gbl_sleep_type_b_s0 <<
0221 sleep_type_reg_info->bit_position);
0222
0223
0224
0225 (void)acpi_hw_write_pm1_control(pm1a_control,
0226 pm1b_control);
0227 }
0228 }
0229
0230 return_ACPI_STATUS(status);
0231 }
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246 acpi_status acpi_hw_legacy_wake(u8 sleep_state)
0247 {
0248 acpi_status status;
0249
0250 ACPI_FUNCTION_TRACE(hw_legacy_wake);
0251
0252
0253
0254 acpi_gbl_sleep_type_a = ACPI_SLEEP_TYPE_INVALID;
0255 acpi_hw_execute_sleep_method(METHOD_PATHNAME__SST, ACPI_SST_WAKING);
0256
0257
0258
0259
0260
0261
0262
0263
0264
0265 status = acpi_hw_disable_all_gpes();
0266 if (ACPI_FAILURE(status)) {
0267 return_ACPI_STATUS(status);
0268 }
0269
0270 status = acpi_hw_enable_all_runtime_gpes();
0271 if (ACPI_FAILURE(status)) {
0272 return_ACPI_STATUS(status);
0273 }
0274
0275
0276
0277
0278
0279 acpi_hw_execute_sleep_method(METHOD_PATHNAME__WAK, sleep_state);
0280
0281
0282
0283
0284
0285
0286 (void)acpi_write_bit_register(ACPI_BITREG_WAKE_STATUS,
0287 ACPI_CLEAR_STATUS);
0288 acpi_gbl_system_awake_and_running = TRUE;
0289
0290
0291
0292 (void)
0293 acpi_write_bit_register(acpi_gbl_fixed_event_info
0294 [ACPI_EVENT_POWER_BUTTON].
0295 enable_register_id, ACPI_ENABLE_EVENT);
0296
0297 (void)
0298 acpi_write_bit_register(acpi_gbl_fixed_event_info
0299 [ACPI_EVENT_POWER_BUTTON].
0300 status_register_id, ACPI_CLEAR_STATUS);
0301
0302
0303
0304 (void)
0305 acpi_write_bit_register(acpi_gbl_fixed_event_info
0306 [ACPI_EVENT_SLEEP_BUTTON].
0307 enable_register_id, ACPI_ENABLE_EVENT);
0308
0309 (void)
0310 acpi_write_bit_register(acpi_gbl_fixed_event_info
0311 [ACPI_EVENT_SLEEP_BUTTON].
0312 status_register_id, ACPI_CLEAR_STATUS);
0313
0314 acpi_hw_execute_sleep_method(METHOD_PATHNAME__SST, ACPI_SST_WORKING);
0315 return_ACPI_STATUS(status);
0316 }
0317
0318 #endif