|
@@ -151,6 +151,10 @@ static bool ec_freeze_events __read_mostly = false;
|
|
|
module_param(ec_freeze_events, bool, 0644);
|
|
|
MODULE_PARM_DESC(ec_freeze_events, "Disabling event handling during suspend/resume");
|
|
|
|
|
|
+static bool ec_no_wakeup __read_mostly;
|
|
|
+module_param(ec_no_wakeup, bool, 0644);
|
|
|
+MODULE_PARM_DESC(ec_no_wakeup, "Do not wake up from suspend-to-idle");
|
|
|
+
|
|
|
struct acpi_ec_query_handler {
|
|
|
struct list_head node;
|
|
|
acpi_ec_query_func func;
|
|
@@ -535,6 +539,14 @@ static void acpi_ec_disable_event(struct acpi_ec *ec)
|
|
|
spin_unlock_irqrestore(&ec->lock, flags);
|
|
|
__acpi_ec_flush_event(ec);
|
|
|
}
|
|
|
+
|
|
|
+void acpi_ec_flush_work(void)
|
|
|
+{
|
|
|
+ if (first_ec)
|
|
|
+ __acpi_ec_flush_event(first_ec);
|
|
|
+
|
|
|
+ flush_scheduled_work();
|
|
|
+}
|
|
|
#endif /* CONFIG_PM_SLEEP */
|
|
|
|
|
|
static bool acpi_ec_guard_event(struct acpi_ec *ec)
|
|
@@ -1880,6 +1892,32 @@ static int acpi_ec_suspend(struct device *dev)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static int acpi_ec_suspend_noirq(struct device *dev)
|
|
|
+{
|
|
|
+ struct acpi_ec *ec = acpi_driver_data(to_acpi_device(dev));
|
|
|
+
|
|
|
+ /*
|
|
|
+ * The SCI handler doesn't run at this point, so the GPE can be
|
|
|
+ * masked at the low level without side effects.
|
|
|
+ */
|
|
|
+ if (ec_no_wakeup && test_bit(EC_FLAGS_STARTED, &ec->flags) &&
|
|
|
+ ec->reference_count >= 1)
|
|
|
+ acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_DISABLE);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static int acpi_ec_resume_noirq(struct device *dev)
|
|
|
+{
|
|
|
+ struct acpi_ec *ec = acpi_driver_data(to_acpi_device(dev));
|
|
|
+
|
|
|
+ if (ec_no_wakeup && test_bit(EC_FLAGS_STARTED, &ec->flags) &&
|
|
|
+ ec->reference_count >= 1)
|
|
|
+ acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_ENABLE);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
static int acpi_ec_resume(struct device *dev)
|
|
|
{
|
|
|
struct acpi_ec *ec =
|
|
@@ -1891,6 +1929,7 @@ static int acpi_ec_resume(struct device *dev)
|
|
|
#endif
|
|
|
|
|
|
static const struct dev_pm_ops acpi_ec_pm = {
|
|
|
+ SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(acpi_ec_suspend_noirq, acpi_ec_resume_noirq)
|
|
|
SET_SYSTEM_SLEEP_PM_OPS(acpi_ec_suspend, acpi_ec_resume)
|
|
|
};
|
|
|
|