Merge tag 'platform-drivers-x86-v5.18-1' of git://git.kernel.org/pub/scm/linux/kernel...
[linux-2.6-microblaze.git] / drivers / acpi / x86 / s2idle.c
index abc06e7..2963229 100644 (file)
@@ -86,6 +86,8 @@ struct lpi_device_constraint_amd {
        int min_dstate;
 };
 
+static LIST_HEAD(lps0_s2idle_devops_head);
+
 static struct lpi_constraints *lpi_constraints_table;
 static int lpi_constraints_table_size;
 static int rev_id;
@@ -424,15 +426,11 @@ static int lps0_device_attach(struct acpi_device *adev,
                mem_sleep_current = PM_SUSPEND_TO_IDLE;
 
        /*
-        * Some Intel based LPS0 systems, like ASUS Zenbook UX430UNR/i7-8550U don't
-        * use intel-hid or intel-vbtn but require the EC GPE to be enabled while
-        * suspended for certain wakeup devices to work, so mark it as wakeup-capable.
-        *
-        * Only enable on !AMD as enabling this universally causes problems for a number
-        * of AMD based systems.
+        * Some LPS0 systems, like ASUS Zenbook UX430UNR/i7-8550U, require the
+        * EC GPE to be enabled while suspended for certain wakeup devices to
+        * work, so mark it as wakeup-capable.
         */
-       if (!acpi_s2idle_vendor_amd())
-               acpi_ec_mark_gpe_for_wake();
+       acpi_ec_mark_gpe_for_wake();
 
        return 0;
 }
@@ -444,6 +442,8 @@ static struct acpi_scan_handler lps0_handler = {
 
 int acpi_s2idle_prepare_late(void)
 {
+       struct acpi_s2idle_dev_ops *handler;
+
        if (!lps0_device_handle || sleep_no_lps0)
                return 0;
 
@@ -474,14 +474,26 @@ int acpi_s2idle_prepare_late(void)
                acpi_sleep_run_lps0_dsm(ACPI_LPS0_MS_ENTRY,
                                lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft);
        }
+
+       list_for_each_entry(handler, &lps0_s2idle_devops_head, list_node) {
+               if (handler->prepare)
+                       handler->prepare();
+       }
+
        return 0;
 }
 
 void acpi_s2idle_restore_early(void)
 {
+       struct acpi_s2idle_dev_ops *handler;
+
        if (!lps0_device_handle || sleep_no_lps0)
                return;
 
+       list_for_each_entry(handler, &lps0_s2idle_devops_head, list_node)
+               if (handler->restore)
+                       handler->restore();
+
        /* Modern standby exit */
        if (lps0_dsm_func_mask_microsoft > 0)
                acpi_sleep_run_lps0_dsm(ACPI_LPS0_MS_EXIT,
@@ -524,4 +536,28 @@ void acpi_s2idle_setup(void)
        s2idle_set_ops(&acpi_s2idle_ops_lps0);
 }
 
+int acpi_register_lps0_dev(struct acpi_s2idle_dev_ops *arg)
+{
+       if (!lps0_device_handle || sleep_no_lps0)
+               return -ENODEV;
+
+       lock_system_sleep();
+       list_add(&arg->list_node, &lps0_s2idle_devops_head);
+       unlock_system_sleep();
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(acpi_register_lps0_dev);
+
+void acpi_unregister_lps0_dev(struct acpi_s2idle_dev_ops *arg)
+{
+       if (!lps0_device_handle || sleep_no_lps0)
+               return;
+
+       lock_system_sleep();
+       list_del(&arg->list_node);
+       unlock_system_sleep();
+}
+EXPORT_SYMBOL_GPL(acpi_unregister_lps0_dev);
+
 #endif /* CONFIG_SUSPEND */