diff options
Diffstat (limited to 'drivers/acpi/sleep/main.c')
| -rw-r--r-- | drivers/acpi/sleep/main.c | 328 |
1 files changed, 186 insertions, 142 deletions
diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c index 495c63a3e0af..0489a7d1d42c 100644 --- a/drivers/acpi/sleep/main.c +++ b/drivers/acpi/sleep/main.c | |||
| @@ -24,10 +24,6 @@ | |||
| 24 | 24 | ||
| 25 | u8 sleep_states[ACPI_S_STATE_COUNT]; | 25 | u8 sleep_states[ACPI_S_STATE_COUNT]; |
| 26 | 26 | ||
| 27 | #ifdef CONFIG_PM_SLEEP | ||
| 28 | static u32 acpi_target_sleep_state = ACPI_STATE_S0; | ||
| 29 | #endif | ||
| 30 | |||
| 31 | static int acpi_sleep_prepare(u32 acpi_state) | 27 | static int acpi_sleep_prepare(u32 acpi_state) |
| 32 | { | 28 | { |
| 33 | #ifdef CONFIG_ACPI_SLEEP | 29 | #ifdef CONFIG_ACPI_SLEEP |
| @@ -49,9 +45,96 @@ static int acpi_sleep_prepare(u32 acpi_state) | |||
| 49 | return 0; | 45 | return 0; |
| 50 | } | 46 | } |
| 51 | 47 | ||
| 52 | #ifdef CONFIG_SUSPEND | 48 | #ifdef CONFIG_PM_SLEEP |
| 53 | static struct platform_suspend_ops acpi_suspend_ops; | 49 | static u32 acpi_target_sleep_state = ACPI_STATE_S0; |
| 50 | |||
| 51 | /* | ||
| 52 | * ACPI 1.0 wants us to execute _PTS before suspending devices, so we allow the | ||
| 53 | * user to request that behavior by using the 'acpi_old_suspend_ordering' | ||
| 54 | * kernel command line option that causes the following variable to be set. | ||
| 55 | */ | ||
| 56 | static bool old_suspend_ordering; | ||
| 54 | 57 | ||
| 58 | void __init acpi_old_suspend_ordering(void) | ||
| 59 | { | ||
| 60 | old_suspend_ordering = true; | ||
| 61 | } | ||
| 62 | |||
| 63 | /** | ||
| 64 | * acpi_pm_disable_gpes - Disable the GPEs. | ||
| 65 | */ | ||
| 66 | static int acpi_pm_disable_gpes(void) | ||
| 67 | { | ||
| 68 | acpi_hw_disable_all_gpes(); | ||
| 69 | return 0; | ||
| 70 | } | ||
| 71 | |||
| 72 | /** | ||
| 73 | * __acpi_pm_prepare - Prepare the platform to enter the target state. | ||
| 74 | * | ||
| 75 | * If necessary, set the firmware waking vector and do arch-specific | ||
| 76 | * nastiness to get the wakeup code to the waking vector. | ||
| 77 | */ | ||
| 78 | static int __acpi_pm_prepare(void) | ||
| 79 | { | ||
| 80 | int error = acpi_sleep_prepare(acpi_target_sleep_state); | ||
| 81 | |||
| 82 | if (error) | ||
| 83 | acpi_target_sleep_state = ACPI_STATE_S0; | ||
| 84 | return error; | ||
| 85 | } | ||
| 86 | |||
| 87 | /** | ||
| 88 | * acpi_pm_prepare - Prepare the platform to enter the target sleep | ||
| 89 | * state and disable the GPEs. | ||
| 90 | */ | ||
| 91 | static int acpi_pm_prepare(void) | ||
| 92 | { | ||
| 93 | int error = __acpi_pm_prepare(); | ||
| 94 | |||
| 95 | if (!error) | ||
| 96 | acpi_hw_disable_all_gpes(); | ||
| 97 | return error; | ||
| 98 | } | ||
| 99 | |||
| 100 | /** | ||
| 101 | * acpi_pm_finish - Instruct the platform to leave a sleep state. | ||
| 102 | * | ||
| 103 | * This is called after we wake back up (or if entering the sleep state | ||
| 104 | * failed). | ||
| 105 | */ | ||
| 106 | static void acpi_pm_finish(void) | ||
| 107 | { | ||
| 108 | u32 acpi_state = acpi_target_sleep_state; | ||
| 109 | |||
| 110 | if (acpi_state == ACPI_STATE_S0) | ||
| 111 | return; | ||
| 112 | |||
| 113 | printk(KERN_INFO PREFIX "Waking up from system sleep state S%d\n", | ||
| 114 | acpi_state); | ||
| 115 | acpi_disable_wakeup_device(acpi_state); | ||
| 116 | acpi_leave_sleep_state(acpi_state); | ||
| 117 | |||
| 118 | /* reset firmware waking vector */ | ||
| 119 | acpi_set_firmware_waking_vector((acpi_physical_address) 0); | ||
| 120 | |||
| 121 | acpi_target_sleep_state = ACPI_STATE_S0; | ||
| 122 | } | ||
| 123 | |||
| 124 | /** | ||
| 125 | * acpi_pm_end - Finish up suspend sequence. | ||
| 126 | */ | ||
| 127 | static void acpi_pm_end(void) | ||
| 128 | { | ||
| 129 | /* | ||
| 130 | * This is necessary in case acpi_pm_finish() is not called during a | ||
| 131 | * failing transition to a sleep state. | ||
| 132 | */ | ||
| 133 | acpi_target_sleep_state = ACPI_STATE_S0; | ||
| 134 | } | ||
| 135 | #endif /* CONFIG_PM_SLEEP */ | ||
| 136 | |||
| 137 | #ifdef CONFIG_SUSPEND | ||
| 55 | extern void do_suspend_lowlevel(void); | 138 | extern void do_suspend_lowlevel(void); |
| 56 | 139 | ||
| 57 | static u32 acpi_suspend_states[] = { | 140 | static u32 acpi_suspend_states[] = { |
| @@ -61,13 +144,10 @@ static u32 acpi_suspend_states[] = { | |||
| 61 | [PM_SUSPEND_MAX] = ACPI_STATE_S5 | 144 | [PM_SUSPEND_MAX] = ACPI_STATE_S5 |
| 62 | }; | 145 | }; |
| 63 | 146 | ||
| 64 | static int init_8259A_after_S1; | ||
| 65 | |||
| 66 | /** | 147 | /** |
| 67 | * acpi_suspend_begin - Set the target system sleep state to the state | 148 | * acpi_suspend_begin - Set the target system sleep state to the state |
| 68 | * associated with given @pm_state, if supported. | 149 | * associated with given @pm_state, if supported. |
| 69 | */ | 150 | */ |
| 70 | |||
| 71 | static int acpi_suspend_begin(suspend_state_t pm_state) | 151 | static int acpi_suspend_begin(suspend_state_t pm_state) |
| 72 | { | 152 | { |
| 73 | u32 acpi_state = acpi_suspend_states[pm_state]; | 153 | u32 acpi_state = acpi_suspend_states[pm_state]; |
| @@ -84,25 +164,6 @@ static int acpi_suspend_begin(suspend_state_t pm_state) | |||
| 84 | } | 164 | } |
| 85 | 165 | ||
| 86 | /** | 166 | /** |
| 87 | * acpi_suspend_prepare - Do preliminary suspend work. | ||
| 88 | * | ||
| 89 | * If necessary, set the firmware waking vector and do arch-specific | ||
| 90 | * nastiness to get the wakeup code to the waking vector. | ||
| 91 | */ | ||
| 92 | |||
| 93 | static int acpi_suspend_prepare(void) | ||
| 94 | { | ||
| 95 | int error = acpi_sleep_prepare(acpi_target_sleep_state); | ||
| 96 | |||
| 97 | if (error) { | ||
| 98 | acpi_target_sleep_state = ACPI_STATE_S0; | ||
| 99 | return error; | ||
| 100 | } | ||
| 101 | |||
| 102 | return ACPI_SUCCESS(acpi_hw_disable_all_gpes()) ? 0 : -EFAULT; | ||
| 103 | } | ||
| 104 | |||
| 105 | /** | ||
| 106 | * acpi_suspend_enter - Actually enter a sleep state. | 167 | * acpi_suspend_enter - Actually enter a sleep state. |
| 107 | * @pm_state: ignored | 168 | * @pm_state: ignored |
| 108 | * | 169 | * |
| @@ -110,7 +171,6 @@ static int acpi_suspend_prepare(void) | |||
| 110 | * assembly, which in turn call acpi_enter_sleep_state(). | 171 | * assembly, which in turn call acpi_enter_sleep_state(). |
| 111 | * It's unfortunate, but it works. Please fix if you're feeling frisky. | 172 | * It's unfortunate, but it works. Please fix if you're feeling frisky. |
| 112 | */ | 173 | */ |
| 113 | |||
| 114 | static int acpi_suspend_enter(suspend_state_t pm_state) | 174 | static int acpi_suspend_enter(suspend_state_t pm_state) |
| 115 | { | 175 | { |
| 116 | acpi_status status = AE_OK; | 176 | acpi_status status = AE_OK; |
| @@ -167,46 +227,6 @@ static int acpi_suspend_enter(suspend_state_t pm_state) | |||
| 167 | return ACPI_SUCCESS(status) ? 0 : -EFAULT; | 227 | return ACPI_SUCCESS(status) ? 0 : -EFAULT; |
| 168 | } | 228 | } |
| 169 | 229 | ||
| 170 | /** | ||
| 171 | * acpi_suspend_finish - Instruct the platform to leave a sleep state. | ||
| 172 | * | ||
| 173 | * This is called after we wake back up (or if entering the sleep state | ||
| 174 | * failed). | ||
| 175 | */ | ||
| 176 | |||
| 177 | static void acpi_suspend_finish(void) | ||
| 178 | { | ||
| 179 | u32 acpi_state = acpi_target_sleep_state; | ||
| 180 | |||
| 181 | acpi_disable_wakeup_device(acpi_state); | ||
| 182 | acpi_leave_sleep_state(acpi_state); | ||
| 183 | |||
| 184 | /* reset firmware waking vector */ | ||
| 185 | acpi_set_firmware_waking_vector((acpi_physical_address) 0); | ||
| 186 | |||
| 187 | acpi_target_sleep_state = ACPI_STATE_S0; | ||
| 188 | |||
| 189 | #ifdef CONFIG_X86 | ||
| 190 | if (init_8259A_after_S1) { | ||
| 191 | printk("Broken toshiba laptop -> kicking interrupts\n"); | ||
| 192 | init_8259A(0); | ||
| 193 | } | ||
| 194 | #endif | ||
| 195 | } | ||
| 196 | |||
| 197 | /** | ||
| 198 | * acpi_suspend_end - Finish up suspend sequence. | ||
| 199 | */ | ||
| 200 | |||
| 201 | static void acpi_suspend_end(void) | ||
| 202 | { | ||
| 203 | /* | ||
| 204 | * This is necessary in case acpi_suspend_finish() is not called during a | ||
| 205 | * failing transition to a sleep state. | ||
| 206 | */ | ||
| 207 | acpi_target_sleep_state = ACPI_STATE_S0; | ||
| 208 | } | ||
| 209 | |||
| 210 | static int acpi_suspend_state_valid(suspend_state_t pm_state) | 230 | static int acpi_suspend_state_valid(suspend_state_t pm_state) |
| 211 | { | 231 | { |
| 212 | u32 acpi_state; | 232 | u32 acpi_state; |
| @@ -226,30 +246,39 @@ static int acpi_suspend_state_valid(suspend_state_t pm_state) | |||
| 226 | static struct platform_suspend_ops acpi_suspend_ops = { | 246 | static struct platform_suspend_ops acpi_suspend_ops = { |
| 227 | .valid = acpi_suspend_state_valid, | 247 | .valid = acpi_suspend_state_valid, |
| 228 | .begin = acpi_suspend_begin, | 248 | .begin = acpi_suspend_begin, |
| 229 | .prepare = acpi_suspend_prepare, | 249 | .prepare = acpi_pm_prepare, |
| 230 | .enter = acpi_suspend_enter, | 250 | .enter = acpi_suspend_enter, |
| 231 | .finish = acpi_suspend_finish, | 251 | .finish = acpi_pm_finish, |
| 232 | .end = acpi_suspend_end, | 252 | .end = acpi_pm_end, |
| 233 | }; | 253 | }; |
| 234 | 254 | ||
| 235 | /* | 255 | /** |
| 236 | * Toshiba fails to preserve interrupts over S1, reinitialization | 256 | * acpi_suspend_begin_old - Set the target system sleep state to the |
| 237 | * of 8259 is needed after S1 resume. | 257 | * state associated with given @pm_state, if supported, and |
| 258 | * execute the _PTS control method. This function is used if the | ||
| 259 | * pre-ACPI 2.0 suspend ordering has been requested. | ||
| 238 | */ | 260 | */ |
| 239 | static int __init init_ints_after_s1(const struct dmi_system_id *d) | 261 | static int acpi_suspend_begin_old(suspend_state_t pm_state) |
| 240 | { | 262 | { |
| 241 | printk(KERN_WARNING "%s with broken S1 detected.\n", d->ident); | 263 | int error = acpi_suspend_begin(pm_state); |
| 242 | init_8259A_after_S1 = 1; | 264 | |
| 243 | return 0; | 265 | if (!error) |
| 266 | error = __acpi_pm_prepare(); | ||
| 267 | return error; | ||
| 244 | } | 268 | } |
| 245 | 269 | ||
| 246 | static struct dmi_system_id __initdata acpisleep_dmi_table[] = { | 270 | /* |
| 247 | { | 271 | * The following callbacks are used if the pre-ACPI 2.0 suspend ordering has |
| 248 | .callback = init_ints_after_s1, | 272 | * been requested. |
| 249 | .ident = "Toshiba Satellite 4030cdt", | 273 | */ |
| 250 | .matches = {DMI_MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),}, | 274 | static struct platform_suspend_ops acpi_suspend_ops_old = { |
| 251 | }, | 275 | .valid = acpi_suspend_state_valid, |
| 252 | {}, | 276 | .begin = acpi_suspend_begin_old, |
| 277 | .prepare = acpi_pm_disable_gpes, | ||
| 278 | .enter = acpi_suspend_enter, | ||
| 279 | .finish = acpi_pm_finish, | ||
| 280 | .end = acpi_pm_end, | ||
| 281 | .recover = acpi_pm_finish, | ||
| 253 | }; | 282 | }; |
| 254 | #endif /* CONFIG_SUSPEND */ | 283 | #endif /* CONFIG_SUSPEND */ |
| 255 | 284 | ||
| @@ -257,22 +286,9 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = { | |||
| 257 | static int acpi_hibernation_begin(void) | 286 | static int acpi_hibernation_begin(void) |
| 258 | { | 287 | { |
| 259 | acpi_target_sleep_state = ACPI_STATE_S4; | 288 | acpi_target_sleep_state = ACPI_STATE_S4; |
| 260 | |||
| 261 | return 0; | 289 | return 0; |
| 262 | } | 290 | } |
| 263 | 291 | ||
| 264 | static int acpi_hibernation_prepare(void) | ||
| 265 | { | ||
| 266 | int error = acpi_sleep_prepare(ACPI_STATE_S4); | ||
| 267 | |||
| 268 | if (error) { | ||
| 269 | acpi_target_sleep_state = ACPI_STATE_S0; | ||
| 270 | return error; | ||
| 271 | } | ||
| 272 | |||
| 273 | return ACPI_SUCCESS(acpi_hw_disable_all_gpes()) ? 0 : -EFAULT; | ||
| 274 | } | ||
| 275 | |||
| 276 | static int acpi_hibernation_enter(void) | 292 | static int acpi_hibernation_enter(void) |
| 277 | { | 293 | { |
| 278 | acpi_status status = AE_OK; | 294 | acpi_status status = AE_OK; |
| @@ -302,52 +318,55 @@ static void acpi_hibernation_leave(void) | |||
| 302 | acpi_leave_sleep_state_prep(ACPI_STATE_S4); | 318 | acpi_leave_sleep_state_prep(ACPI_STATE_S4); |
| 303 | } | 319 | } |
| 304 | 320 | ||
| 305 | static void acpi_hibernation_finish(void) | 321 | static void acpi_pm_enable_gpes(void) |
| 306 | { | 322 | { |
| 307 | acpi_disable_wakeup_device(ACPI_STATE_S4); | 323 | acpi_hw_enable_all_runtime_gpes(); |
| 308 | acpi_leave_sleep_state(ACPI_STATE_S4); | ||
| 309 | |||
| 310 | /* reset firmware waking vector */ | ||
| 311 | acpi_set_firmware_waking_vector((acpi_physical_address) 0); | ||
| 312 | |||
| 313 | acpi_target_sleep_state = ACPI_STATE_S0; | ||
| 314 | } | 324 | } |
| 315 | 325 | ||
| 316 | static void acpi_hibernation_end(void) | 326 | static struct platform_hibernation_ops acpi_hibernation_ops = { |
| 317 | { | 327 | .begin = acpi_hibernation_begin, |
| 318 | /* | 328 | .end = acpi_pm_end, |
| 319 | * This is necessary in case acpi_hibernation_finish() is not called | 329 | .pre_snapshot = acpi_pm_prepare, |
| 320 | * during a failing transition to the sleep state. | 330 | .finish = acpi_pm_finish, |
| 321 | */ | 331 | .prepare = acpi_pm_prepare, |
| 322 | acpi_target_sleep_state = ACPI_STATE_S0; | 332 | .enter = acpi_hibernation_enter, |
| 323 | } | 333 | .leave = acpi_hibernation_leave, |
| 334 | .pre_restore = acpi_pm_disable_gpes, | ||
| 335 | .restore_cleanup = acpi_pm_enable_gpes, | ||
| 336 | }; | ||
| 324 | 337 | ||
| 325 | static int acpi_hibernation_pre_restore(void) | 338 | /** |
| 339 | * acpi_hibernation_begin_old - Set the target system sleep state to | ||
| 340 | * ACPI_STATE_S4 and execute the _PTS control method. This | ||
| 341 | * function is used if the pre-ACPI 2.0 suspend ordering has been | ||
| 342 | * requested. | ||
| 343 | */ | ||
| 344 | static int acpi_hibernation_begin_old(void) | ||
| 326 | { | 345 | { |
| 327 | acpi_status status; | 346 | int error = acpi_sleep_prepare(ACPI_STATE_S4); |
| 328 | |||
| 329 | status = acpi_hw_disable_all_gpes(); | ||
| 330 | |||
| 331 | return ACPI_SUCCESS(status) ? 0 : -EFAULT; | ||
| 332 | } | ||
| 333 | 347 | ||
| 334 | static void acpi_hibernation_restore_cleanup(void) | 348 | if (!error) |
| 335 | { | 349 | acpi_target_sleep_state = ACPI_STATE_S4; |
| 336 | acpi_hw_enable_all_runtime_gpes(); | 350 | return error; |
| 337 | } | 351 | } |
| 338 | 352 | ||
| 339 | static struct platform_hibernation_ops acpi_hibernation_ops = { | 353 | /* |
| 340 | .begin = acpi_hibernation_begin, | 354 | * The following callbacks are used if the pre-ACPI 2.0 suspend ordering has |
| 341 | .end = acpi_hibernation_end, | 355 | * been requested. |
| 342 | .pre_snapshot = acpi_hibernation_prepare, | 356 | */ |
| 343 | .finish = acpi_hibernation_finish, | 357 | static struct platform_hibernation_ops acpi_hibernation_ops_old = { |
| 344 | .prepare = acpi_hibernation_prepare, | 358 | .begin = acpi_hibernation_begin_old, |
| 359 | .end = acpi_pm_end, | ||
| 360 | .pre_snapshot = acpi_pm_disable_gpes, | ||
| 361 | .finish = acpi_pm_finish, | ||
| 362 | .prepare = acpi_pm_disable_gpes, | ||
| 345 | .enter = acpi_hibernation_enter, | 363 | .enter = acpi_hibernation_enter, |
| 346 | .leave = acpi_hibernation_leave, | 364 | .leave = acpi_hibernation_leave, |
| 347 | .pre_restore = acpi_hibernation_pre_restore, | 365 | .pre_restore = acpi_pm_disable_gpes, |
| 348 | .restore_cleanup = acpi_hibernation_restore_cleanup, | 366 | .restore_cleanup = acpi_pm_enable_gpes, |
| 367 | .recover = acpi_pm_finish, | ||
| 349 | }; | 368 | }; |
| 350 | #endif /* CONFIG_HIBERNATION */ | 369 | #endif /* CONFIG_HIBERNATION */ |
| 351 | 370 | ||
| 352 | int acpi_suspend(u32 acpi_state) | 371 | int acpi_suspend(u32 acpi_state) |
| 353 | { | 372 | { |
| @@ -368,8 +387,8 @@ int acpi_suspend(u32 acpi_state) | |||
| 368 | /** | 387 | /** |
| 369 | * acpi_pm_device_sleep_state - return preferred power state of ACPI device | 388 | * acpi_pm_device_sleep_state - return preferred power state of ACPI device |
| 370 | * in the system sleep state given by %acpi_target_sleep_state | 389 | * in the system sleep state given by %acpi_target_sleep_state |
| 371 | * @dev: device to examine | 390 | * @dev: device to examine; its driver model wakeup flags control |
| 372 | * @wake: if set, the device should be able to wake up the system | 391 | * whether it should be able to wake up the system |
| 373 | * @d_min_p: used to store the upper limit of allowed states range | 392 | * @d_min_p: used to store the upper limit of allowed states range |
| 374 | * Return value: preferred power state of the device on success, -ENODEV on | 393 | * Return value: preferred power state of the device on success, -ENODEV on |
| 375 | * failure (ie. if there's no 'struct acpi_device' for @dev) | 394 | * failure (ie. if there's no 'struct acpi_device' for @dev) |
| @@ -387,7 +406,7 @@ int acpi_suspend(u32 acpi_state) | |||
| 387 | * via @wake. | 406 | * via @wake. |
| 388 | */ | 407 | */ |
| 389 | 408 | ||
| 390 | int acpi_pm_device_sleep_state(struct device *dev, int wake, int *d_min_p) | 409 | int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p) |
| 391 | { | 410 | { |
| 392 | acpi_handle handle = DEVICE_ACPI_HANDLE(dev); | 411 | acpi_handle handle = DEVICE_ACPI_HANDLE(dev); |
| 393 | struct acpi_device *adev; | 412 | struct acpi_device *adev; |
| @@ -426,7 +445,7 @@ int acpi_pm_device_sleep_state(struct device *dev, int wake, int *d_min_p) | |||
| 426 | * can wake the system. _S0W may be valid, too. | 445 | * can wake the system. _S0W may be valid, too. |
| 427 | */ | 446 | */ |
| 428 | if (acpi_target_sleep_state == ACPI_STATE_S0 || | 447 | if (acpi_target_sleep_state == ACPI_STATE_S0 || |
| 429 | (wake && adev->wakeup.state.enabled && | 448 | (device_may_wakeup(dev) && adev->wakeup.state.enabled && |
| 430 | adev->wakeup.sleep_state <= acpi_target_sleep_state)) { | 449 | adev->wakeup.sleep_state <= acpi_target_sleep_state)) { |
| 431 | acpi_status status; | 450 | acpi_status status; |
| 432 | 451 | ||
| @@ -448,6 +467,31 @@ int acpi_pm_device_sleep_state(struct device *dev, int wake, int *d_min_p) | |||
| 448 | *d_min_p = d_min; | 467 | *d_min_p = d_min; |
| 449 | return d_max; | 468 | return d_max; |
| 450 | } | 469 | } |
| 470 | |||
| 471 | /** | ||
| 472 | * acpi_pm_device_sleep_wake - enable or disable the system wake-up | ||
| 473 | * capability of given device | ||
| 474 | * @dev: device to handle | ||
| 475 | * @enable: 'true' - enable, 'false' - disable the wake-up capability | ||
| 476 | */ | ||
| 477 | int acpi_pm_device_sleep_wake(struct device *dev, bool enable) | ||
| 478 | { | ||
| 479 | acpi_handle handle; | ||
| 480 | struct acpi_device *adev; | ||
| 481 | |||
| 482 | if (!device_may_wakeup(dev)) | ||
| 483 | return -EINVAL; | ||
| 484 | |||
| 485 | handle = DEVICE_ACPI_HANDLE(dev); | ||
| 486 | if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &adev))) { | ||
| 487 | printk(KERN_DEBUG "ACPI handle has no context!\n"); | ||
| 488 | return -ENODEV; | ||
| 489 | } | ||
| 490 | |||
| 491 | return enable ? | ||
| 492 | acpi_enable_wakeup_device_power(adev, acpi_target_sleep_state) : | ||
| 493 | acpi_disable_wakeup_device_power(adev); | ||
| 494 | } | ||
| 451 | #endif | 495 | #endif |
| 452 | 496 | ||
| 453 | static void acpi_power_off_prepare(void) | 497 | static void acpi_power_off_prepare(void) |
| @@ -472,8 +516,6 @@ int __init acpi_sleep_init(void) | |||
| 472 | u8 type_a, type_b; | 516 | u8 type_a, type_b; |
| 473 | #ifdef CONFIG_SUSPEND | 517 | #ifdef CONFIG_SUSPEND |
| 474 | int i = 0; | 518 | int i = 0; |
| 475 | |||
| 476 | dmi_check_system(acpisleep_dmi_table); | ||
| 477 | #endif | 519 | #endif |
| 478 | 520 | ||
| 479 | if (acpi_disabled) | 521 | if (acpi_disabled) |
| @@ -491,13 +533,15 @@ int __init acpi_sleep_init(void) | |||
| 491 | } | 533 | } |
| 492 | } | 534 | } |
| 493 | 535 | ||
| 494 | suspend_set_ops(&acpi_suspend_ops); | 536 | suspend_set_ops(old_suspend_ordering ? |
| 537 | &acpi_suspend_ops_old : &acpi_suspend_ops); | ||
| 495 | #endif | 538 | #endif |
| 496 | 539 | ||
| 497 | #ifdef CONFIG_HIBERNATION | 540 | #ifdef CONFIG_HIBERNATION |
| 498 | status = acpi_get_sleep_type_data(ACPI_STATE_S4, &type_a, &type_b); | 541 | status = acpi_get_sleep_type_data(ACPI_STATE_S4, &type_a, &type_b); |
| 499 | if (ACPI_SUCCESS(status)) { | 542 | if (ACPI_SUCCESS(status)) { |
| 500 | hibernation_set_ops(&acpi_hibernation_ops); | 543 | hibernation_set_ops(old_suspend_ordering ? |
| 544 | &acpi_hibernation_ops_old : &acpi_hibernation_ops); | ||
| 501 | sleep_states[ACPI_STATE_S4] = 1; | 545 | sleep_states[ACPI_STATE_S4] = 1; |
| 502 | printk(" S4"); | 546 | printk(" S4"); |
| 503 | } | 547 | } |
