aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/sleep.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/sleep.c')
-rw-r--r--drivers/acpi/sleep.c84
1 files changed, 47 insertions, 37 deletions
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
index 4754ff6e70e6..6c949602cbd1 100644
--- a/drivers/acpi/sleep.c
+++ b/drivers/acpi/sleep.c
@@ -16,6 +16,7 @@
16#include <linux/device.h> 16#include <linux/device.h>
17#include <linux/suspend.h> 17#include <linux/suspend.h>
18#include <linux/reboot.h> 18#include <linux/reboot.h>
19#include <linux/acpi.h>
19 20
20#include <asm/io.h> 21#include <asm/io.h>
21 22
@@ -25,7 +26,7 @@
25#include "internal.h" 26#include "internal.h"
26#include "sleep.h" 27#include "sleep.h"
27 28
28u8 sleep_states[ACPI_S_STATE_COUNT]; 29static u8 sleep_states[ACPI_S_STATE_COUNT];
29 30
30static void acpi_sleep_tts_switch(u32 acpi_state) 31static void acpi_sleep_tts_switch(u32 acpi_state)
31{ 32{
@@ -124,8 +125,7 @@ static int acpi_pm_freeze(void)
124static int acpi_pm_pre_suspend(void) 125static int acpi_pm_pre_suspend(void)
125{ 126{
126 acpi_pm_freeze(); 127 acpi_pm_freeze();
127 suspend_nvs_save(); 128 return suspend_nvs_save();
128 return 0;
129} 129}
130 130
131/** 131/**
@@ -151,7 +151,7 @@ static int acpi_pm_prepare(void)
151{ 151{
152 int error = __acpi_pm_prepare(); 152 int error = __acpi_pm_prepare();
153 if (!error) 153 if (!error)
154 acpi_pm_pre_suspend(); 154 error = acpi_pm_pre_suspend();
155 155
156 return error; 156 return error;
157} 157}
@@ -167,6 +167,7 @@ static void acpi_pm_finish(void)
167 u32 acpi_state = acpi_target_sleep_state; 167 u32 acpi_state = acpi_target_sleep_state;
168 168
169 acpi_ec_unblock_transactions(); 169 acpi_ec_unblock_transactions();
170 suspend_nvs_free();
170 171
171 if (acpi_state == ACPI_STATE_S0) 172 if (acpi_state == ACPI_STATE_S0)
172 return; 173 return;
@@ -187,7 +188,6 @@ static void acpi_pm_finish(void)
187 */ 188 */
188static void acpi_pm_end(void) 189static void acpi_pm_end(void)
189{ 190{
190 suspend_nvs_free();
191 /* 191 /*
192 * This is necessary in case acpi_pm_finish() is not called during a 192 * This is necessary in case acpi_pm_finish() is not called during a
193 * failing transition to a sleep state. 193 * failing transition to a sleep state.
@@ -200,8 +200,6 @@ static void acpi_pm_end(void)
200#endif /* CONFIG_ACPI_SLEEP */ 200#endif /* CONFIG_ACPI_SLEEP */
201 201
202#ifdef CONFIG_SUSPEND 202#ifdef CONFIG_SUSPEND
203extern void do_suspend_lowlevel(void);
204
205static u32 acpi_suspend_states[] = { 203static u32 acpi_suspend_states[] = {
206 [PM_SUSPEND_ON] = ACPI_STATE_S0, 204 [PM_SUSPEND_ON] = ACPI_STATE_S0,
207 [PM_SUSPEND_STANDBY] = ACPI_STATE_S1, 205 [PM_SUSPEND_STANDBY] = ACPI_STATE_S1,
@@ -244,20 +242,11 @@ static int acpi_suspend_begin(suspend_state_t pm_state)
244static int acpi_suspend_enter(suspend_state_t pm_state) 242static int acpi_suspend_enter(suspend_state_t pm_state)
245{ 243{
246 acpi_status status = AE_OK; 244 acpi_status status = AE_OK;
247 unsigned long flags = 0;
248 u32 acpi_state = acpi_target_sleep_state; 245 u32 acpi_state = acpi_target_sleep_state;
246 int error;
249 247
250 ACPI_FLUSH_CPU_CACHE(); 248 ACPI_FLUSH_CPU_CACHE();
251 249
252 /* Do arch specific saving of state. */
253 if (acpi_state == ACPI_STATE_S3) {
254 int error = acpi_save_state_mem();
255
256 if (error)
257 return error;
258 }
259
260 local_irq_save(flags);
261 switch (acpi_state) { 250 switch (acpi_state) {
262 case ACPI_STATE_S1: 251 case ACPI_STATE_S1:
263 barrier(); 252 barrier();
@@ -265,7 +254,10 @@ static int acpi_suspend_enter(suspend_state_t pm_state)
265 break; 254 break;
266 255
267 case ACPI_STATE_S3: 256 case ACPI_STATE_S3:
268 do_suspend_lowlevel(); 257 error = acpi_suspend_lowlevel();
258 if (error)
259 return error;
260 pr_info(PREFIX "Low-level resume complete\n");
269 break; 261 break;
270 } 262 }
271 263
@@ -291,13 +283,6 @@ static int acpi_suspend_enter(suspend_state_t pm_state)
291 /* Allow EC transactions to happen. */ 283 /* Allow EC transactions to happen. */
292 acpi_ec_unblock_transactions_early(); 284 acpi_ec_unblock_transactions_early();
293 285
294 local_irq_restore(flags);
295 printk(KERN_DEBUG "Back to C!\n");
296
297 /* restore processor state */
298 if (acpi_state == ACPI_STATE_S3)
299 acpi_restore_state_mem();
300
301 suspend_nvs_restore(); 286 suspend_nvs_restore();
302 287
303 return ACPI_SUCCESS(status) ? 0 : -EFAULT; 288 return ACPI_SUCCESS(status) ? 0 : -EFAULT;
@@ -319,7 +304,7 @@ static int acpi_suspend_state_valid(suspend_state_t pm_state)
319 } 304 }
320} 305}
321 306
322static struct platform_suspend_ops acpi_suspend_ops = { 307static const struct platform_suspend_ops acpi_suspend_ops = {
323 .valid = acpi_suspend_state_valid, 308 .valid = acpi_suspend_state_valid,
324 .begin = acpi_suspend_begin, 309 .begin = acpi_suspend_begin,
325 .prepare_late = acpi_pm_prepare, 310 .prepare_late = acpi_pm_prepare,
@@ -347,7 +332,7 @@ static int acpi_suspend_begin_old(suspend_state_t pm_state)
347 * The following callbacks are used if the pre-ACPI 2.0 suspend ordering has 332 * The following callbacks are used if the pre-ACPI 2.0 suspend ordering has
348 * been requested. 333 * been requested.
349 */ 334 */
350static struct platform_suspend_ops acpi_suspend_ops_old = { 335static const struct platform_suspend_ops acpi_suspend_ops_old = {
351 .valid = acpi_suspend_state_valid, 336 .valid = acpi_suspend_state_valid,
352 .begin = acpi_suspend_begin_old, 337 .begin = acpi_suspend_begin_old,
353 .prepare_late = acpi_pm_pre_suspend, 338 .prepare_late = acpi_pm_pre_suspend,
@@ -419,6 +404,30 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
419 DMI_MATCH(DMI_PRODUCT_NAME, "Everex StepNote Series"), 404 DMI_MATCH(DMI_PRODUCT_NAME, "Everex StepNote Series"),
420 }, 405 },
421 }, 406 },
407 {
408 .callback = init_nvs_nosave,
409 .ident = "Sony Vaio VPCEB1Z1E",
410 .matches = {
411 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
412 DMI_MATCH(DMI_PRODUCT_NAME, "VPCEB1Z1E"),
413 },
414 },
415 {
416 .callback = init_nvs_nosave,
417 .ident = "Sony Vaio VGN-NW130D",
418 .matches = {
419 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
420 DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NW130D"),
421 },
422 },
423 {
424 .callback = init_nvs_nosave,
425 .ident = "Averatec AV1020-ED2",
426 .matches = {
427 DMI_MATCH(DMI_SYS_VENDOR, "AVERATEC"),
428 DMI_MATCH(DMI_PRODUCT_NAME, "1000 Series"),
429 },
430 },
422 {}, 431 {},
423}; 432};
424#endif /* CONFIG_SUSPEND */ 433#endif /* CONFIG_SUSPEND */
@@ -449,16 +458,13 @@ static int acpi_hibernation_begin(void)
449static int acpi_hibernation_enter(void) 458static int acpi_hibernation_enter(void)
450{ 459{
451 acpi_status status = AE_OK; 460 acpi_status status = AE_OK;
452 unsigned long flags = 0;
453 461
454 ACPI_FLUSH_CPU_CACHE(); 462 ACPI_FLUSH_CPU_CACHE();
455 463
456 local_irq_save(flags);
457 /* This shouldn't return. If it returns, we have a problem */ 464 /* This shouldn't return. If it returns, we have a problem */
458 status = acpi_enter_sleep_state(ACPI_STATE_S4); 465 status = acpi_enter_sleep_state(ACPI_STATE_S4);
459 /* Reprogram control registers and execute _BFS */ 466 /* Reprogram control registers and execute _BFS */
460 acpi_leave_sleep_state_prep(ACPI_STATE_S4); 467 acpi_leave_sleep_state_prep(ACPI_STATE_S4);
461 local_irq_restore(flags);
462 468
463 return ACPI_SUCCESS(status) ? 0 : -EFAULT; 469 return ACPI_SUCCESS(status) ? 0 : -EFAULT;
464} 470}
@@ -490,7 +496,7 @@ static void acpi_pm_thaw(void)
490 acpi_enable_all_runtime_gpes(); 496 acpi_enable_all_runtime_gpes();
491} 497}
492 498
493static struct platform_hibernation_ops acpi_hibernation_ops = { 499static const struct platform_hibernation_ops acpi_hibernation_ops = {
494 .begin = acpi_hibernation_begin, 500 .begin = acpi_hibernation_begin,
495 .end = acpi_pm_end, 501 .end = acpi_pm_end,
496 .pre_snapshot = acpi_pm_prepare, 502 .pre_snapshot = acpi_pm_prepare,
@@ -533,7 +539,7 @@ static int acpi_hibernation_begin_old(void)
533 * The following callbacks are used if the pre-ACPI 2.0 suspend ordering has 539 * The following callbacks are used if the pre-ACPI 2.0 suspend ordering has
534 * been requested. 540 * been requested.
535 */ 541 */
536static struct platform_hibernation_ops acpi_hibernation_ops_old = { 542static const struct platform_hibernation_ops acpi_hibernation_ops_old = {
537 .begin = acpi_hibernation_begin_old, 543 .begin = acpi_hibernation_begin_old,
538 .end = acpi_pm_end, 544 .end = acpi_pm_end,
539 .pre_snapshot = acpi_pm_pre_suspend, 545 .pre_snapshot = acpi_pm_pre_suspend,
@@ -562,7 +568,7 @@ int acpi_suspend(u32 acpi_state)
562 return -EINVAL; 568 return -EINVAL;
563} 569}
564 570
565#ifdef CONFIG_PM_SLEEP 571#ifdef CONFIG_PM
566/** 572/**
567 * acpi_pm_device_sleep_state - return preferred power state of ACPI device 573 * acpi_pm_device_sleep_state - return preferred power state of ACPI device
568 * in the system sleep state given by %acpi_target_sleep_state 574 * in the system sleep state given by %acpi_target_sleep_state
@@ -624,7 +630,7 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p)
624 * can wake the system. _S0W may be valid, too. 630 * can wake the system. _S0W may be valid, too.
625 */ 631 */
626 if (acpi_target_sleep_state == ACPI_STATE_S0 || 632 if (acpi_target_sleep_state == ACPI_STATE_S0 ||
627 (device_may_wakeup(dev) && adev->wakeup.state.enabled && 633 (device_may_wakeup(dev) &&
628 adev->wakeup.sleep_state <= acpi_target_sleep_state)) { 634 adev->wakeup.sleep_state <= acpi_target_sleep_state)) {
629 acpi_status status; 635 acpi_status status;
630 636
@@ -632,7 +638,9 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p)
632 status = acpi_evaluate_integer(handle, acpi_method, NULL, 638 status = acpi_evaluate_integer(handle, acpi_method, NULL,
633 &d_max); 639 &d_max);
634 if (ACPI_FAILURE(status)) { 640 if (ACPI_FAILURE(status)) {
635 d_max = d_min; 641 if (acpi_target_sleep_state != ACPI_STATE_S0 ||
642 status != AE_NOT_FOUND)
643 d_max = d_min;
636 } else if (d_max < d_min) { 644 } else if (d_max < d_min) {
637 /* Warn the user of the broken DSDT */ 645 /* Warn the user of the broken DSDT */
638 printk(KERN_WARNING "ACPI: Wrong value from %s\n", 646 printk(KERN_WARNING "ACPI: Wrong value from %s\n",
@@ -646,7 +654,9 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p)
646 *d_min_p = d_min; 654 *d_min_p = d_min;
647 return d_max; 655 return d_max;
648} 656}
657#endif /* CONFIG_PM */
649 658
659#ifdef CONFIG_PM_SLEEP
650/** 660/**
651 * acpi_pm_device_sleep_wake - enable or disable the system wake-up 661 * acpi_pm_device_sleep_wake - enable or disable the system wake-up
652 * capability of given device 662 * capability of given device
@@ -677,7 +687,7 @@ int acpi_pm_device_sleep_wake(struct device *dev, bool enable)
677 687
678 return error; 688 return error;
679} 689}
680#endif 690#endif /* CONFIG_PM_SLEEP */
681 691
682static void acpi_power_off_prepare(void) 692static void acpi_power_off_prepare(void)
683{ 693{
@@ -702,7 +712,7 @@ static void acpi_power_off(void)
702 * paths through the BIOS, so disable _GTS and _BFS by default, 712 * paths through the BIOS, so disable _GTS and _BFS by default,
703 * but do speak up and offer the option to enable them. 713 * but do speak up and offer the option to enable them.
704 */ 714 */
705void __init acpi_gts_bfs_check(void) 715static void __init acpi_gts_bfs_check(void)
706{ 716{
707 acpi_handle dummy; 717 acpi_handle dummy;
708 718