#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>
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)
{
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,
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");
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())
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();
/*
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);
}
bool acpi_sleep_no_ec_events(void)
{
- return !s2idle_in_progress || !lps0_device_handle;
+ return !s2idle_in_progress;
}
#ifdef CONFIG_PM_SLEEP
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;
}
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);
}
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:
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;
}
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;
}
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) {}
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
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) {}