summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/acpi/ec.c7
-rw-r--r--drivers/acpi/internal.h2
-rw-r--r--drivers/acpi/sleep.c13
-rw-r--r--drivers/platform/x86/intel-hid.c20
-rw-r--r--drivers/platform/x86/intel-vbtn.c20
-rw-r--r--include/linux/acpi.h4
-rw-r--r--include/linux/suspend.h1
7 files changed, 45 insertions, 22 deletions
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 58c7ad402d8d..b996ca5f253f 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -25,6 +25,7 @@
#include <linux/list.h>
#include <linux/spinlock.h>
#include <linux/slab.h>
+#include <linux/suspend.h>
#include <linux/acpi.h>
#include <linux/dmi.h>
#include <asm/io.h>
@@ -1048,17 +1049,21 @@ void acpi_ec_unblock_transactions(void)
acpi_ec_start(first_ec, true);
}
+#ifdef CONFIG_PM_SLEEP
void acpi_ec_mark_gpe_for_wake(void)
{
if (first_ec && !ec_no_wakeup)
acpi_mark_gpe_for_wake(NULL, first_ec->gpe);
}
+EXPORT_SYMBOL_GPL(acpi_ec_mark_gpe_for_wake);
void acpi_ec_set_gpe_wake_mask(u8 action)
{
- if (first_ec && !ec_no_wakeup)
+ if (pm_suspend_no_platform() && first_ec && !ec_no_wakeup)
acpi_set_gpe_wake_mask(NULL, first_ec->gpe, action);
}
+EXPORT_SYMBOL_GPL(acpi_ec_set_gpe_wake_mask);
+#endif
bool acpi_ec_dispatch_gpe(void)
{
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index 1b5f9ac06ea8..bcc080511197 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -194,8 +194,6 @@ void acpi_ec_ecdt_probe(void);
void acpi_ec_dsdt_probe(void);
void acpi_ec_block_transactions(void);
void acpi_ec_unblock_transactions(void);
-void acpi_ec_mark_gpe_for_wake(void);
-void acpi_ec_set_gpe_wake_mask(u8 action);
bool acpi_ec_dispatch_gpe(void);
int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit,
acpi_handle handle, acpi_ec_query_func func,
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
index 970ae7c7a3f7..9cb0532f7471 100644
--- a/drivers/acpi/sleep.c
+++ b/drivers/acpi/sleep.c
@@ -930,8 +930,6 @@ static int lps0_device_attach(struct acpi_device *adev,
acpi_handle_debug(adev->handle, "_DSM function mask: 0x%x\n",
bitmask);
-
- acpi_ec_mark_gpe_for_wake();
} else {
acpi_handle_debug(adev->handle,
"_DSM function 0 evaluation failed\n");
@@ -960,8 +958,6 @@ static int acpi_s2idle_prepare(void)
if (lps0_device_handle) {
acpi_sleep_run_lps0_dsm(ACPI_LPS0_SCREEN_OFF);
acpi_sleep_run_lps0_dsm(ACPI_LPS0_ENTRY);
-
- acpi_ec_set_gpe_wake_mask(ACPI_GPE_ENABLE);
}
if (acpi_sci_irq_valid())
@@ -979,10 +975,7 @@ static int acpi_s2idle_prepare(void)
static void acpi_s2idle_wake(void)
{
- if (!lps0_device_handle)
- return;
-
- if (pm_debug_messages_on)
+ if (lps0_device_handle && pm_debug_messages_on)
lpi_check_constraints();
/*
@@ -1031,8 +1024,6 @@ static void acpi_s2idle_restore(void)
disable_irq_wake(acpi_sci_irq);
if (lps0_device_handle) {
- acpi_ec_set_gpe_wake_mask(ACPI_GPE_DISABLE);
-
acpi_sleep_run_lps0_dsm(ACPI_LPS0_EXIT);
acpi_sleep_run_lps0_dsm(ACPI_LPS0_SCREEN_ON);
}
@@ -1081,7 +1072,7 @@ bool acpi_s2idle_wakeup(void)
bool acpi_sleep_no_ec_events(void)
{
- return !s2idle_in_progress || !lps0_device_handle;
+ return !s2idle_in_progress;
}
#ifdef CONFIG_PM_SLEEP
diff --git a/drivers/platform/x86/intel-hid.c b/drivers/platform/x86/intel-hid.c
index bc0d55a59015..e51c72b92cbd 100644
--- a/drivers/platform/x86/intel-hid.c
+++ b/drivers/platform/x86/intel-hid.c
@@ -253,9 +253,12 @@ static void intel_button_array_enable(struct device *device, bool enable)
static int intel_hid_pm_prepare(struct device *device)
{
- struct intel_hid_priv *priv = dev_get_drvdata(device);
+ if (device_may_wakeup(device)) {
+ struct intel_hid_priv *priv = dev_get_drvdata(device);
- priv->wakeup_mode = true;
+ priv->wakeup_mode = true;
+ acpi_ec_set_gpe_wake_mask(ACPI_GPE_ENABLE);
+ }
return 0;
}
@@ -270,9 +273,12 @@ static int intel_hid_pl_suspend_handler(struct device *device)
static int intel_hid_pl_resume_handler(struct device *device)
{
- struct intel_hid_priv *priv = dev_get_drvdata(device);
+ if (device_may_wakeup(device)) {
+ struct intel_hid_priv *priv = dev_get_drvdata(device);
- priv->wakeup_mode = false;
+ acpi_ec_set_gpe_wake_mask(ACPI_GPE_DISABLE);
+ priv->wakeup_mode = false;
+ }
if (pm_resume_via_firmware()) {
intel_hid_set_enable(device, true);
intel_button_array_enable(device, true);
@@ -491,6 +497,12 @@ static int intel_hid_probe(struct platform_device *device)
}
device_init_wakeup(&device->dev, true);
+ /*
+ * In order for system wakeup to work, the EC GPE has to be marked as
+ * a wakeup one, so do that here (this setting will persist, but it has
+ * no effect until the wakeup mask is set for the EC GPE).
+ */
+ acpi_ec_mark_gpe_for_wake();
return 0;
err_remove_notify:
diff --git a/drivers/platform/x86/intel-vbtn.c b/drivers/platform/x86/intel-vbtn.c
index a0d0cecff55f..ab84e1bbdedd 100644
--- a/drivers/platform/x86/intel-vbtn.c
+++ b/drivers/platform/x86/intel-vbtn.c
@@ -176,6 +176,12 @@ static int intel_vbtn_probe(struct platform_device *device)
return -EBUSY;
device_init_wakeup(&device->dev, true);
+ /*
+ * In order for system wakeup to work, the EC GPE has to be marked as
+ * a wakeup one, so do that here (this setting will persist, but it has
+ * no effect until the wakeup mask is set for the EC GPE).
+ */
+ acpi_ec_mark_gpe_for_wake();
return 0;
}
@@ -195,17 +201,23 @@ static int intel_vbtn_remove(struct platform_device *device)
static int intel_vbtn_pm_prepare(struct device *dev)
{
- struct intel_vbtn_priv *priv = dev_get_drvdata(dev);
+ if (device_may_wakeup(dev)) {
+ struct intel_vbtn_priv *priv = dev_get_drvdata(dev);
- priv->wakeup_mode = true;
+ priv->wakeup_mode = true;
+ acpi_ec_set_gpe_wake_mask(ACPI_GPE_ENABLE);
+ }
return 0;
}
static int intel_vbtn_pm_resume(struct device *dev)
{
- struct intel_vbtn_priv *priv = dev_get_drvdata(dev);
+ if (device_may_wakeup(dev)) {
+ struct intel_vbtn_priv *priv = dev_get_drvdata(dev);
- priv->wakeup_mode = false;
+ acpi_ec_set_gpe_wake_mask(ACPI_GPE_DISABLE);
+ priv->wakeup_mode = false;
+ }
return 0;
}
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 9426b9aaed86..e65a4c5bbeae 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -931,6 +931,8 @@ int acpi_subsys_suspend_noirq(struct device *dev);
int acpi_subsys_suspend(struct device *dev);
int acpi_subsys_freeze(struct device *dev);
int acpi_subsys_poweroff(struct device *dev);
+void acpi_ec_mark_gpe_for_wake(void);
+void acpi_ec_set_gpe_wake_mask(u8 action);
#else
static inline int acpi_subsys_prepare(struct device *dev) { return 0; }
static inline void acpi_subsys_complete(struct device *dev) {}
@@ -939,6 +941,8 @@ static inline int acpi_subsys_suspend_noirq(struct device *dev) { return 0; }
static inline int acpi_subsys_suspend(struct device *dev) { return 0; }
static inline int acpi_subsys_freeze(struct device *dev) { return 0; }
static inline int acpi_subsys_poweroff(struct device *dev) { return 0; }
+static inline void acpi_ec_mark_gpe_for_wake(void) {}
+static inline void acpi_ec_set_gpe_wake_mask(u8 action) {}
#endif
#ifdef CONFIG_ACPI
diff --git a/include/linux/suspend.h b/include/linux/suspend.h
index 66ce3871ed61..f0c4a8445140 100644
--- a/include/linux/suspend.h
+++ b/include/linux/suspend.h
@@ -335,6 +335,7 @@ static inline void pm_set_suspend_via_firmware(void) {}
static inline void pm_set_resume_via_firmware(void) {}
static inline bool pm_suspend_via_firmware(void) { return false; }
static inline bool pm_resume_via_firmware(void) { return false; }
+static inline bool pm_suspend_no_platform(void) { return false; }
static inline bool pm_suspend_default_s2idle(void) { return false; }
static inline void suspend_set_ops(const struct platform_suspend_ops *ops) {}