#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) {}