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.c76
1 files changed, 68 insertions, 8 deletions
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
index ca191ff97844..1d661b5c3287 100644
--- a/drivers/acpi/sleep.c
+++ b/drivers/acpi/sleep.c
@@ -17,6 +17,8 @@
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#include <linux/acpi.h>
20#include <linux/module.h>
21#include <linux/pm_runtime.h>
20 22
21#include <asm/io.h> 23#include <asm/io.h>
22 24
@@ -26,6 +28,24 @@
26#include "internal.h" 28#include "internal.h"
27#include "sleep.h" 29#include "sleep.h"
28 30
31static unsigned int gts, bfs;
32module_param(gts, uint, 0644);
33module_param(bfs, uint, 0644);
34MODULE_PARM_DESC(gts, "Enable evaluation of _GTS on suspend.");
35MODULE_PARM_DESC(bfs, "Enable evaluation of _BFS on resume".);
36
37static u8 wake_sleep_flags(void)
38{
39 u8 flags = ACPI_NO_OPTIONAL_METHODS;
40
41 if (gts)
42 flags |= ACPI_EXECUTE_GTS;
43 if (bfs)
44 flags |= ACPI_EXECUTE_BFS;
45
46 return flags;
47}
48
29static u8 sleep_states[ACPI_S_STATE_COUNT]; 49static u8 sleep_states[ACPI_S_STATE_COUNT];
30 50
31static void acpi_sleep_tts_switch(u32 acpi_state) 51static void acpi_sleep_tts_switch(u32 acpi_state)
@@ -243,6 +263,7 @@ static int acpi_suspend_enter(suspend_state_t pm_state)
243{ 263{
244 acpi_status status = AE_OK; 264 acpi_status status = AE_OK;
245 u32 acpi_state = acpi_target_sleep_state; 265 u32 acpi_state = acpi_target_sleep_state;
266 u8 flags = wake_sleep_flags();
246 int error; 267 int error;
247 268
248 ACPI_FLUSH_CPU_CACHE(); 269 ACPI_FLUSH_CPU_CACHE();
@@ -250,7 +271,7 @@ static int acpi_suspend_enter(suspend_state_t pm_state)
250 switch (acpi_state) { 271 switch (acpi_state) {
251 case ACPI_STATE_S1: 272 case ACPI_STATE_S1:
252 barrier(); 273 barrier();
253 status = acpi_enter_sleep_state(acpi_state); 274 status = acpi_enter_sleep_state(acpi_state, flags);
254 break; 275 break;
255 276
256 case ACPI_STATE_S3: 277 case ACPI_STATE_S3:
@@ -265,7 +286,7 @@ static int acpi_suspend_enter(suspend_state_t pm_state)
265 acpi_write_bit_register(ACPI_BITREG_SCI_ENABLE, 1); 286 acpi_write_bit_register(ACPI_BITREG_SCI_ENABLE, 1);
266 287
267 /* Reprogram control registers and execute _BFS */ 288 /* Reprogram control registers and execute _BFS */
268 acpi_leave_sleep_state_prep(acpi_state); 289 acpi_leave_sleep_state_prep(acpi_state, flags);
269 290
270 /* ACPI 3.0 specs (P62) says that it's the responsibility 291 /* ACPI 3.0 specs (P62) says that it's the responsibility
271 * of the OSPM to clear the status bit [ implying that the 292 * of the OSPM to clear the status bit [ implying that the
@@ -529,27 +550,30 @@ static int acpi_hibernation_begin(void)
529 550
530static int acpi_hibernation_enter(void) 551static int acpi_hibernation_enter(void)
531{ 552{
553 u8 flags = wake_sleep_flags();
532 acpi_status status = AE_OK; 554 acpi_status status = AE_OK;
533 555
534 ACPI_FLUSH_CPU_CACHE(); 556 ACPI_FLUSH_CPU_CACHE();
535 557
536 /* This shouldn't return. If it returns, we have a problem */ 558 /* This shouldn't return. If it returns, we have a problem */
537 status = acpi_enter_sleep_state(ACPI_STATE_S4); 559 status = acpi_enter_sleep_state(ACPI_STATE_S4, flags);
538 /* Reprogram control registers and execute _BFS */ 560 /* Reprogram control registers and execute _BFS */
539 acpi_leave_sleep_state_prep(ACPI_STATE_S4); 561 acpi_leave_sleep_state_prep(ACPI_STATE_S4, flags);
540 562
541 return ACPI_SUCCESS(status) ? 0 : -EFAULT; 563 return ACPI_SUCCESS(status) ? 0 : -EFAULT;
542} 564}
543 565
544static void acpi_hibernation_leave(void) 566static void acpi_hibernation_leave(void)
545{ 567{
568 u8 flags = wake_sleep_flags();
569
546 /* 570 /*
547 * If ACPI is not enabled by the BIOS and the boot kernel, we need to 571 * If ACPI is not enabled by the BIOS and the boot kernel, we need to
548 * enable it here. 572 * enable it here.
549 */ 573 */
550 acpi_enable(); 574 acpi_enable();
551 /* Reprogram control registers and execute _BFS */ 575 /* Reprogram control registers and execute _BFS */
552 acpi_leave_sleep_state_prep(ACPI_STATE_S4); 576 acpi_leave_sleep_state_prep(ACPI_STATE_S4, flags);
553 /* Check the hardware signature */ 577 /* Check the hardware signature */
554 if (facs && s4_hardware_signature != facs->hardware_signature) { 578 if (facs && s4_hardware_signature != facs->hardware_signature) {
555 printk(KERN_EMERG "ACPI: Hardware changed while hibernated, " 579 printk(KERN_EMERG "ACPI: Hardware changed while hibernated, "
@@ -730,6 +754,40 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p)
730 754
731#ifdef CONFIG_PM_SLEEP 755#ifdef CONFIG_PM_SLEEP
732/** 756/**
757 * acpi_pm_device_run_wake - Enable/disable wake-up for given device.
758 * @phys_dev: Device to enable/disable the platform to wake-up the system for.
759 * @enable: Whether enable or disable the wake-up functionality.
760 *
761 * Find the ACPI device object corresponding to @pci_dev and try to
762 * enable/disable the GPE associated with it.
763 */
764int acpi_pm_device_run_wake(struct device *phys_dev, bool enable)
765{
766 struct acpi_device *dev;
767 acpi_handle handle;
768
769 if (!device_run_wake(phys_dev))
770 return -EINVAL;
771
772 handle = DEVICE_ACPI_HANDLE(phys_dev);
773 if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &dev))) {
774 dev_dbg(phys_dev, "ACPI handle has no context in %s!\n",
775 __func__);
776 return -ENODEV;
777 }
778
779 if (enable) {
780 acpi_enable_wakeup_device_power(dev, ACPI_STATE_S0);
781 acpi_enable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number);
782 } else {
783 acpi_disable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number);
784 acpi_disable_wakeup_device_power(dev);
785 }
786
787 return 0;
788}
789
790/**
733 * acpi_pm_device_sleep_wake - enable or disable the system wake-up 791 * acpi_pm_device_sleep_wake - enable or disable the system wake-up
734 * capability of given device 792 * capability of given device
735 * @dev: device to handle 793 * @dev: device to handle
@@ -770,10 +828,12 @@ static void acpi_power_off_prepare(void)
770 828
771static void acpi_power_off(void) 829static void acpi_power_off(void)
772{ 830{
831 u8 flags = wake_sleep_flags();
832
773 /* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */ 833 /* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */
774 printk(KERN_DEBUG "%s called\n", __func__); 834 printk(KERN_DEBUG "%s called\n", __func__);
775 local_irq_disable(); 835 local_irq_disable();
776 acpi_enter_sleep_state(ACPI_STATE_S5); 836 acpi_enter_sleep_state(ACPI_STATE_S5, flags);
777} 837}
778 838
779/* 839/*
@@ -788,13 +848,13 @@ static void __init acpi_gts_bfs_check(void)
788{ 848{
789 acpi_handle dummy; 849 acpi_handle dummy;
790 850
791 if (ACPI_SUCCESS(acpi_get_handle(ACPI_ROOT_OBJECT, METHOD_NAME__GTS, &dummy))) 851 if (ACPI_SUCCESS(acpi_get_handle(ACPI_ROOT_OBJECT, METHOD_PATHNAME__GTS, &dummy)))
792 { 852 {
793 printk(KERN_NOTICE PREFIX "BIOS offers _GTS\n"); 853 printk(KERN_NOTICE PREFIX "BIOS offers _GTS\n");
794 printk(KERN_NOTICE PREFIX "If \"acpi.gts=1\" improves suspend, " 854 printk(KERN_NOTICE PREFIX "If \"acpi.gts=1\" improves suspend, "
795 "please notify linux-acpi@vger.kernel.org\n"); 855 "please notify linux-acpi@vger.kernel.org\n");
796 } 856 }
797 if (ACPI_SUCCESS(acpi_get_handle(ACPI_ROOT_OBJECT, METHOD_NAME__BFS, &dummy))) 857 if (ACPI_SUCCESS(acpi_get_handle(ACPI_ROOT_OBJECT, METHOD_PATHNAME__BFS, &dummy)))
798 { 858 {
799 printk(KERN_NOTICE PREFIX "BIOS offers _BFS\n"); 859 printk(KERN_NOTICE PREFIX "BIOS offers _BFS\n");
800 printk(KERN_NOTICE PREFIX "If \"acpi.bfs=1\" improves resume, " 860 printk(KERN_NOTICE PREFIX "If \"acpi.bfs=1\" improves resume, "