From 0efe92b47b9d5e8f31dcb34fd6aff89c7c490ea5 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Thu, 18 Aug 2022 08:51:56 +0300 Subject: [PATCH 01/17] ACPI: PM: Fix acpi_dev_state_d0() kerneldoc The documentation for acpi_dev_state_d0() referred to Documentation/firmware-guide/acpi/low-power-probe.rst that does not exist, the right file name is Documentation/firmware-guide/acpi/non-d0-probe.rst. Fix this. Reported-by: kernel test robot Signed-off-by: Sakari Ailus [ rjw: Subject edits ] Signed-off-by: Rafael J. Wysocki --- drivers/acpi/device_pm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index 9dce1245689c..0d1f911f14e9 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c @@ -1460,7 +1460,7 @@ EXPORT_SYMBOL_GPL(acpi_storage_d3); * not valid to ask for the ACPI power state of the device in that time frame. * * This function is intended to be used in a driver's probe or remove - * function. See Documentation/firmware-guide/acpi/low-power-probe.rst for + * function. See Documentation/firmware-guide/acpi/non-d0-probe.rst for * more information. */ bool acpi_dev_state_d0(struct device *dev) From 6d2b5a1cf4dd943909a927133664ad1627783d95 Mon Sep 17 00:00:00 2001 From: Heikki Krogerus Date: Tue, 16 Aug 2022 13:16:25 +0300 Subject: [PATCH 02/17] ACPI: resource: Filter out the non memory resources in is_memory() This will generalise the function so it should become useful in more places. Signed-off-by: Heikki Krogerus Signed-off-by: Rafael J. Wysocki --- drivers/acpi/resource.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c index 510cdec375c4..e644e90d1884 100644 --- a/drivers/acpi/resource.c +++ b/drivers/acpi/resource.c @@ -690,6 +690,9 @@ static int is_memory(struct acpi_resource *ares, void *not_used) memset(&win, 0, sizeof(win)); + if (acpi_dev_filter_resource_type(ares, IORESOURCE_MEM)) + return 1; + return !(acpi_dev_resource_memory(ares, res) || acpi_dev_resource_address_space(ares, &win) || acpi_dev_resource_ext_address_space(ares, &win)); From 6bb057bfd9d509755349cd2a6ca5e5e6e6071304 Mon Sep 17 00:00:00 2001 From: Heikki Krogerus Date: Tue, 16 Aug 2022 13:16:26 +0300 Subject: [PATCH 03/17] ACPI: resource: Add helper function acpi_dev_get_memory_resources() Wrapper function that finds all memory type resources by using acpi_dev_get_resources(). It removes the need for the drivers to check the resource data type separately. Signed-off-by: Heikki Krogerus Signed-off-by: Rafael J. Wysocki --- drivers/acpi/resource.c | 17 +++++++++++++++++ include/linux/acpi.h | 1 + 2 files changed, 18 insertions(+) diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c index e644e90d1884..8032d50ca944 100644 --- a/drivers/acpi/resource.c +++ b/drivers/acpi/resource.c @@ -721,6 +721,23 @@ int acpi_dev_get_dma_resources(struct acpi_device *adev, struct list_head *list) } EXPORT_SYMBOL_GPL(acpi_dev_get_dma_resources); +/** + * acpi_dev_get_memory_resources - Get current memory resources of a device. + * @adev: ACPI device node to get the resources for. + * @list: Head of the resultant list of resources (must be empty). + * + * This is a helper function that locates all memory type resources of @adev + * with acpi_dev_get_resources(). + * + * The number of resources in the output list is returned on success, an error + * code reflecting the error condition is returned otherwise. + */ +int acpi_dev_get_memory_resources(struct acpi_device *adev, struct list_head *list) +{ + return acpi_dev_get_resources(adev, list, is_memory, NULL); +} +EXPORT_SYMBOL_GPL(acpi_dev_get_memory_resources); + /** * acpi_dev_filter_resource_type - Filter ACPI resource according to resource * types diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 6f64b2f3dc54..ed4aa395cc49 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -506,6 +506,7 @@ int acpi_dev_get_resources(struct acpi_device *adev, struct list_head *list, void *preproc_data); int acpi_dev_get_dma_resources(struct acpi_device *adev, struct list_head *list); +int acpi_dev_get_memory_resources(struct acpi_device *adev, struct list_head *list); int acpi_dev_filter_resource_type(struct acpi_resource *ares, unsigned long types); From 064d42d90e412936434fae7d49204d8055e5b0e5 Mon Sep 17 00:00:00 2001 From: Heikki Krogerus Date: Tue, 16 Aug 2022 13:16:27 +0300 Subject: [PATCH 04/17] ACPI: APD: Use the helper acpi_dev_get_memory_resources() It removes the need to check the resource data type separately. Signed-off-by: Heikki Krogerus Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpi_apd.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/drivers/acpi/acpi_apd.c b/drivers/acpi/acpi_apd.c index ad245bbd965e..3bbe2276cac7 100644 --- a/drivers/acpi/acpi_apd.c +++ b/drivers/acpi/acpi_apd.c @@ -60,12 +60,6 @@ static int acpi_apd_setup(struct apd_private_data *pdata) } #ifdef CONFIG_X86_AMD_PLATFORM_DEVICE -static int misc_check_res(struct acpi_resource *ares, void *data) -{ - struct resource res; - - return !acpi_dev_resource_memory(ares, &res); -} static int fch_misc_setup(struct apd_private_data *pdata) { @@ -82,8 +76,7 @@ static int fch_misc_setup(struct apd_private_data *pdata) return -ENOMEM; INIT_LIST_HEAD(&resource_list); - ret = acpi_dev_get_resources(adev, &resource_list, misc_check_res, - NULL); + ret = acpi_dev_get_memory_resources(adev, &resource_list); if (ret < 0) return -ENOENT; From 840baca4c44130e9e1954d7b1807f3280c804bc2 Mon Sep 17 00:00:00 2001 From: Heikki Krogerus Date: Tue, 16 Aug 2022 13:16:28 +0300 Subject: [PATCH 05/17] ACPI: LPSS: Use the helper acpi_dev_get_memory_resources() It removes the need to check the resource data type separately. Signed-off-by: Heikki Krogerus Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpi_lpss.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c index c4d4d21391d7..4f6cba8fe8de 100644 --- a/drivers/acpi/acpi_lpss.c +++ b/drivers/acpi/acpi_lpss.c @@ -392,13 +392,6 @@ static const struct acpi_device_id acpi_lpss_device_ids[] = { #ifdef CONFIG_X86_INTEL_LPSS -static int is_memory(struct acpi_resource *res, void *not_used) -{ - struct resource r; - - return !acpi_dev_resource_memory(res, &r); -} - /* LPSS main clock device. */ static struct platform_device *lpss_clk_dev; @@ -659,7 +652,7 @@ static int acpi_lpss_create_device(struct acpi_device *adev, return -ENOMEM; INIT_LIST_HEAD(&resource_list); - ret = acpi_dev_get_resources(adev, &resource_list, is_memory, NULL); + ret = acpi_dev_get_memory_resources(adev, &resource_list); if (ret < 0) goto err_out; From e12dee3736731e24b1e7367f87d66ac0fcd73ce7 Mon Sep 17 00:00:00 2001 From: Tamim Khan Date: Sun, 28 Aug 2022 23:04:19 -0400 Subject: [PATCH 06/17] ACPI: resource: Skip IRQ override on Asus Vivobook K3402ZA/K3502ZA In the ACPI DSDT table for Asus VivoBook K3402ZA/K3502ZA IRQ 1 is described as ActiveLow; however, the kernel overrides it to Edge_High. This prevents the internal keyboard from working on these laptops. In order to fix this add these laptops to the skip_override_table so that the kernel does not override IRQ 1 to Edge_High. Link: https://bugzilla.kernel.org/show_bug.cgi?id=216158 Reviewed-by: Hui Wang Tested-by: Tamim Khan Tested-by: Sunand Signed-off-by: Tamim Khan Signed-off-by: Rafael J. Wysocki --- drivers/acpi/resource.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c index 8032d50ca944..e40b2153911d 100644 --- a/drivers/acpi/resource.c +++ b/drivers/acpi/resource.c @@ -399,6 +399,24 @@ static const struct dmi_system_id medion_laptop[] = { { } }; +static const struct dmi_system_id asus_laptop[] = { + { + .ident = "Asus Vivobook K3402ZA", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_BOARD_NAME, "K3402ZA"), + }, + }, + { + .ident = "Asus Vivobook K3502ZA", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_BOARD_NAME, "K3502ZA"), + }, + }, + { } +}; + struct irq_override_cmp { const struct dmi_system_id *system; unsigned char irq; @@ -409,6 +427,7 @@ struct irq_override_cmp { static const struct irq_override_cmp skip_override_table[] = { { medion_laptop, 1, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0 }, + { asus_laptop, 1, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0 }, }; static bool acpi_dev_irq_override(u32 gsi, u8 triggering, u8 polarity, From 1538dc8c1561f0de4ba57a69e2a421a1a3951618 Mon Sep 17 00:00:00 2001 From: Heikki Krogerus Date: Wed, 7 Sep 2022 13:30:07 +0300 Subject: [PATCH 07/17] usb: typec: intel_pmc_mux: Use the helper acpi_dev_get_memory_resources() It removes the need to check the resource data type separately. Signed-off-by: Heikki Krogerus Signed-off-by: Rafael J. Wysocki --- drivers/usb/typec/mux/intel_pmc_mux.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/drivers/usb/typec/mux/intel_pmc_mux.c b/drivers/usb/typec/mux/intel_pmc_mux.c index a8e273fe204a..e1f4df7238bf 100644 --- a/drivers/usb/typec/mux/intel_pmc_mux.c +++ b/drivers/usb/typec/mux/intel_pmc_mux.c @@ -569,15 +569,6 @@ static int pmc_usb_register_port(struct pmc_usb *pmc, int index, return ret; } -static int is_memory(struct acpi_resource *res, void *data) -{ - struct resource_win win = {}; - struct resource *r = &win.res; - - return !(acpi_dev_resource_memory(res, r) || - acpi_dev_resource_address_space(res, &win)); -} - /* IOM ACPI IDs and IOM_PORT_STATUS_OFFSET */ static const struct acpi_device_id iom_acpi_ids[] = { /* TigerLake */ @@ -611,7 +602,7 @@ static int pmc_usb_probe_iom(struct pmc_usb *pmc) return -ENODEV; INIT_LIST_HEAD(&resource_list); - ret = acpi_dev_get_resources(adev, &resource_list, is_memory, NULL); + ret = acpi_dev_get_memory_resources(adev, &resource_list); if (ret < 0) return ret; From 6e5cbe7c4b41824e500acbb42411da692d1435f1 Mon Sep 17 00:00:00 2001 From: Kellen Renshaw Date: Wed, 21 Sep 2022 10:24:22 -0700 Subject: [PATCH 08/17] ACPI: resource: Add ASUS model S5402ZA to quirks The Asus Vivobook S5402ZA has the same keyboard issue as Asus Vivobook K3402ZA/K3502ZA. The kernel overrides IRQ 1 to Edge_High when it should be Active_Low. This patch adds the S5402ZA model to the quirk list. Link: https://bugzilla.kernel.org/show_bug.cgi?id=216158 Tested-by: Kellen Renshaw Signed-off-by: Kellen Renshaw Signed-off-by: Rafael J. Wysocki --- drivers/acpi/resource.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c index e40b2153911d..514d89656dde 100644 --- a/drivers/acpi/resource.c +++ b/drivers/acpi/resource.c @@ -414,6 +414,13 @@ static const struct dmi_system_id asus_laptop[] = { DMI_MATCH(DMI_BOARD_NAME, "K3502ZA"), }, }, + { + .ident = "Asus Vivobook S5402ZA", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_BOARD_NAME, "S5402ZA"), + }, + }, { } }; From 100a5737938049706987d06a4ab73e82b8277085 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Wed, 21 Sep 2022 15:40:48 -0500 Subject: [PATCH 09/17] ACPI: x86: s2idle: Move _HID handling for AMD systems into structures Right now the information about which cases to use for what are in a comment, but this is error prone. Instead move all information into a dedicated structure. Tested-by: catalin@antebit.com Reviewed-by: Philipp Zabel Tested-by: Philipp Zabel # GA402RJ Signed-off-by: Mario Limonciello Signed-off-by: Rafael J. Wysocki --- drivers/acpi/x86/s2idle.c | 63 ++++++++++++++++++++++++++++----------- 1 file changed, 46 insertions(+), 17 deletions(-) diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c index f9ac12b778e6..28a3ef9a6bc1 100644 --- a/drivers/acpi/x86/s2idle.c +++ b/drivers/acpi/x86/s2idle.c @@ -363,6 +363,39 @@ static int validate_dsm(acpi_handle handle, const char *uuid, int rev, guid_t *d return ret; } +struct amd_lps0_hid_device_data { + const unsigned int rev_id; + const bool check_off_by_one; + const bool prefer_amd_guid; +}; + +static const struct amd_lps0_hid_device_data amd_picasso = { + .rev_id = 0, + .check_off_by_one = true, + .prefer_amd_guid = false, +}; + +static const struct amd_lps0_hid_device_data amd_cezanne = { + .rev_id = 0, + .check_off_by_one = false, + .prefer_amd_guid = false, +}; + +static const struct amd_lps0_hid_device_data amd_rembrandt = { + .rev_id = 2, + .check_off_by_one = false, + .prefer_amd_guid = true, +}; + +static const struct acpi_device_id amd_hid_ids[] = { + {"AMD0004", (kernel_ulong_t)&amd_picasso, }, + {"AMD0005", (kernel_ulong_t)&amd_picasso, }, + {"AMDI0005", (kernel_ulong_t)&amd_picasso, }, + {"AMDI0006", (kernel_ulong_t)&amd_cezanne, }, + {"AMDI0007", (kernel_ulong_t)&amd_rembrandt, }, + {} +}; + static int lps0_device_attach(struct acpi_device *adev, const struct acpi_device_id *not_used) { @@ -370,31 +403,27 @@ static int lps0_device_attach(struct acpi_device *adev, return 0; if (acpi_s2idle_vendor_amd()) { - /* AMD0004, AMD0005, AMDI0005: - * - Should use rev_id 0x0 - * - function mask > 0x3: Should use AMD method, but has off by one bug - * - function mask = 0x3: Should use Microsoft method - * AMDI0006: - * - should use rev_id 0x0 - * - function mask = 0x3: Should use Microsoft method - * AMDI0007: - * - Should use rev_id 0x2 - * - Should only use AMD method - */ - const char *hid = acpi_device_hid(adev); - rev_id = strcmp(hid, "AMDI0007") ? 0 : 2; + static const struct acpi_device_id *dev_id; + const struct amd_lps0_hid_device_data *data; + + for (dev_id = &amd_hid_ids[0]; dev_id->id[0]; dev_id++) + if (acpi_dev_hid_uid_match(adev, dev_id->id, NULL)) + break; + if (dev_id) + data = (const struct amd_lps0_hid_device_data *) dev_id->driver_data; + else + return 0; + rev_id = data->rev_id; lps0_dsm_func_mask = validate_dsm(adev->handle, ACPI_LPS0_DSM_UUID_AMD, rev_id, &lps0_dsm_guid); lps0_dsm_func_mask_microsoft = validate_dsm(adev->handle, ACPI_LPS0_DSM_UUID_MICROSOFT, 0, &lps0_dsm_guid_microsoft); - if (lps0_dsm_func_mask > 0x3 && (!strcmp(hid, "AMD0004") || - !strcmp(hid, "AMD0005") || - !strcmp(hid, "AMDI0005"))) { + if (lps0_dsm_func_mask > 0x3 && data->check_off_by_one) { lps0_dsm_func_mask = (lps0_dsm_func_mask << 1) | 0x1; acpi_handle_debug(adev->handle, "_DSM UUID %s: Adjusted function mask: 0x%x\n", ACPI_LPS0_DSM_UUID_AMD, lps0_dsm_func_mask); - } else if (lps0_dsm_func_mask_microsoft > 0 && + } else if (lps0_dsm_func_mask_microsoft > 0 && data->prefer_amd_guid && (!strcmp(hid, "AMDI0007") || !strcmp(hid, "AMDI0008"))) { lps0_dsm_func_mask_microsoft = -EINVAL; From fd894f05cf30956296384b0c4a81892ed21ac1d9 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Wed, 21 Sep 2022 15:40:49 -0500 Subject: [PATCH 10/17] ACPI: x86: s2idle: If a new AMD _HID is missing assume Rembrandt A mistake was made that only AMDI0007 was set to rev of "2", but it should have been also set for AMDI008. If an ID is missing from the _HID table, then assume it matches Rembrandt behavior. This implicitly means that if any other behavior changes happen in the future missing IDs must be added to that table. Tested-by: catalin@antebit.com Reviewed-by: Philipp Zabel Tested-by: Philipp Zabel # GA402RJ Signed-off-by: Mario Limonciello Signed-off-by: Rafael J. Wysocki --- drivers/acpi/x86/s2idle.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c index 28a3ef9a6bc1..2c5931d247a2 100644 --- a/drivers/acpi/x86/s2idle.c +++ b/drivers/acpi/x86/s2idle.c @@ -412,7 +412,7 @@ static int lps0_device_attach(struct acpi_device *adev, if (dev_id) data = (const struct amd_lps0_hid_device_data *) dev_id->driver_data; else - return 0; + data = &amd_rembrandt; rev_id = data->rev_id; lps0_dsm_func_mask = validate_dsm(adev->handle, ACPI_LPS0_DSM_UUID_AMD, rev_id, &lps0_dsm_guid); From a0bc002393d42ab7d895b0e82e730ce7622bdbff Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Wed, 21 Sep 2022 15:40:50 -0500 Subject: [PATCH 11/17] ACPI: x86: s2idle: Add module parameter to prefer Microsoft GUID OEMs have made some mistakes in the past for the AMD GUID support and not populated the method properly. To add an escape hatch for this problem introduce a module parameter that can force using the Microsoft GUID. This is intentionally introduced to both Intel and AMD codepaths to allow using the parameter as a debugging tactic on either. Reviewed-by: Philipp Zabel Tested-by: Philipp Zabel # GA402RJ Signed-off-by: Mario Limonciello Signed-off-by: Rafael J. Wysocki --- drivers/acpi/x86/s2idle.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c index 2c5931d247a2..725d2a6c87ed 100644 --- a/drivers/acpi/x86/s2idle.c +++ b/drivers/acpi/x86/s2idle.c @@ -27,6 +27,10 @@ static bool sleep_no_lps0 __read_mostly; module_param(sleep_no_lps0, bool, 0644); MODULE_PARM_DESC(sleep_no_lps0, "Do not use the special LPS0 device interface"); +static bool prefer_microsoft_dsm_guid __read_mostly; +module_param(prefer_microsoft_dsm_guid, bool, 0644); +MODULE_PARM_DESC(prefer_microsoft_dsm_guid, "Prefer using Microsoft GUID in LPS0 device _DSM evaluation"); + static const struct acpi_device_id lps0_device_ids[] = { {"PNP0D80", }, {"", }, @@ -402,6 +406,9 @@ static int lps0_device_attach(struct acpi_device *adev, if (lps0_device_handle) return 0; + lps0_dsm_func_mask_microsoft = validate_dsm(adev->handle, + ACPI_LPS0_DSM_UUID_MICROSOFT, 0, + &lps0_dsm_guid_microsoft); if (acpi_s2idle_vendor_amd()) { static const struct acpi_device_id *dev_id; const struct amd_lps0_hid_device_data *data; @@ -416,16 +423,12 @@ static int lps0_device_attach(struct acpi_device *adev, rev_id = data->rev_id; lps0_dsm_func_mask = validate_dsm(adev->handle, ACPI_LPS0_DSM_UUID_AMD, rev_id, &lps0_dsm_guid); - lps0_dsm_func_mask_microsoft = validate_dsm(adev->handle, - ACPI_LPS0_DSM_UUID_MICROSOFT, 0, - &lps0_dsm_guid_microsoft); if (lps0_dsm_func_mask > 0x3 && data->check_off_by_one) { lps0_dsm_func_mask = (lps0_dsm_func_mask << 1) | 0x1; acpi_handle_debug(adev->handle, "_DSM UUID %s: Adjusted function mask: 0x%x\n", ACPI_LPS0_DSM_UUID_AMD, lps0_dsm_func_mask); } else if (lps0_dsm_func_mask_microsoft > 0 && data->prefer_amd_guid && - (!strcmp(hid, "AMDI0007") || - !strcmp(hid, "AMDI0008"))) { + !prefer_microsoft_dsm_guid) { lps0_dsm_func_mask_microsoft = -EINVAL; acpi_handle_debug(adev->handle, "_DSM Using AMD method\n"); } @@ -433,7 +436,8 @@ static int lps0_device_attach(struct acpi_device *adev, rev_id = 1; lps0_dsm_func_mask = validate_dsm(adev->handle, ACPI_LPS0_DSM_UUID, rev_id, &lps0_dsm_guid); - lps0_dsm_func_mask_microsoft = -EINVAL; + if (!prefer_microsoft_dsm_guid) + lps0_dsm_func_mask_microsoft = -EINVAL; } if (lps0_dsm_func_mask < 0 && lps0_dsm_func_mask_microsoft < 0) From d0f61e89f08dd46a090da50f5d747204673f70ea Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Wed, 21 Sep 2022 15:40:51 -0500 Subject: [PATCH 12/17] ACPI: x86: s2idle: Add a quirk for ASUS TUF Gaming A17 FA707RE ASUS TUF Gaming A17 FA707RE has problems with ACPI events after s2idle resume. It's from a missing call to an ASL method in AMD the s2idle calling path. Force the system to use the Microsoft Modern Standby calling path instead. Link: https://bugzilla.kernel.org/show_bug.cgi?id=216101 Reported-and-tested-by: catalin@antebit.com Reviewed-by: Philipp Zabel Tested-by: Philipp Zabel # GA402RJ Signed-off-by: Mario Limonciello Signed-off-by: Rafael J. Wysocki --- drivers/acpi/x86/s2idle.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c index 725d2a6c87ed..99eae362de6d 100644 --- a/drivers/acpi/x86/s2idle.c +++ b/drivers/acpi/x86/s2idle.c @@ -17,6 +17,7 @@ #include #include +#include #include #include "../sleep.h" @@ -400,6 +401,28 @@ static const struct acpi_device_id amd_hid_ids[] = { {} }; +static int lps0_prefer_microsoft(const struct dmi_system_id *id) +{ + pr_debug("Preferring Microsoft GUID.\n"); + prefer_microsoft_dsm_guid = true; + return 0; +} + +static const struct dmi_system_id s2idle_dmi_table[] __initconst = { + { + /* + * ASUS TUF Gaming A17 FA707RE + * https://bugzilla.kernel.org/show_bug.cgi?id=216101 + */ + .callback = lps0_prefer_microsoft, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "ASUS TUF Gaming A17"), + }, + }, + {} +}; + static int lps0_device_attach(struct acpi_device *adev, const struct acpi_device_id *not_used) { @@ -566,8 +589,9 @@ static const struct platform_s2idle_ops acpi_s2idle_ops_lps0 = { .end = acpi_s2idle_end, }; -void acpi_s2idle_setup(void) +void __init acpi_s2idle_setup(void) { + dmi_check_system(s2idle_dmi_table); acpi_scan_add_handler(&lps0_handler); s2idle_set_ops(&acpi_s2idle_ops_lps0); } From ddeea2c3cb881adee0f979bfd61a90fb057ef3e6 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Wed, 21 Sep 2022 15:40:52 -0500 Subject: [PATCH 13/17] ACPI: x86: s2idle: Add a quirk for ASUS ROG Zephyrus G14 ASUS ROG Zephyrus G14 is affected by the same BIOS bug as ASUS TUF Gaming A17 where important ASL is not called in the AMD code path. Use the Microsoft codepath instead. Reported-and-suggested-by: Philipp Zabel Tested-by: Philipp Zabel Tested-by: Matthew Anderson Tested-by: Marko Cekrlic Signed-off-by: Mario Limonciello Signed-off-by: Rafael J. Wysocki --- drivers/acpi/x86/s2idle.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c index 99eae362de6d..2cd381f6c002 100644 --- a/drivers/acpi/x86/s2idle.c +++ b/drivers/acpi/x86/s2idle.c @@ -420,6 +420,14 @@ static const struct dmi_system_id s2idle_dmi_table[] __initconst = { DMI_MATCH(DMI_PRODUCT_NAME, "ASUS TUF Gaming A17"), }, }, + { + /* ASUS ROG Zephyrus G14 (2022) */ + .callback = lps0_prefer_microsoft, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "ROG Zephyrus G14 GA402"), + }, + }, {} }; From 888ca9c7955e3969df84f5a1bda2143be9fa365a Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Wed, 21 Sep 2022 15:40:53 -0500 Subject: [PATCH 14/17] ACPI: x86: s2idle: Add a quirk for Lenovo Slim 7 Pro 14ARH7 Lenovo Slim 7 Pro 14ARH7 has a sporadically non-functional keyboard when resuming from s2idle. This is caused by some missing calls to the EC that don't occur in the AMD codepath but only in the Microsoft codepath. Add the system to the quirk list to force Microsoft codepath. Reported-by: Travis Glenn Hansen Reported-by: Sebastian S. Link: https://bugzilla.kernel.org/show_bug.cgi?id=216473 Link: https://bugzilla.kernel.org/show_bug.cgi?id=216438 Signed-off-by: Mario Limonciello Signed-off-by: Rafael J. Wysocki --- drivers/acpi/x86/s2idle.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c index 2cd381f6c002..c811eeed42cd 100644 --- a/drivers/acpi/x86/s2idle.c +++ b/drivers/acpi/x86/s2idle.c @@ -428,6 +428,18 @@ static const struct dmi_system_id s2idle_dmi_table[] __initconst = { DMI_MATCH(DMI_PRODUCT_NAME, "ROG Zephyrus G14 GA402"), }, }, + { + /* + * Lenovo Yoga Slim 7 Pro X 14ARH7 + * https://bugzilla.kernel.org/show_bug.cgi?id=216473 : 82V2 + * https://bugzilla.kernel.org/show_bug.cgi?id=216438 : 82TL + */ + .callback = lps0_prefer_microsoft, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "82"), + }, + }, {} }; From 631b54519e8e58758e4541756c1818dcebd2dcc9 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Wed, 21 Sep 2022 15:40:54 -0500 Subject: [PATCH 15/17] ACPI: x86: s2idle: Add a quirk for ASUSTeK COMPUTER INC. ROG Flow X13 ASUSTeK COMPUTER INC. ROG Flow X13 has a problem with fans upon wakeup from s2idle. In examining the ASL, functions 3 and 4 are not called in the AMD codepath but only in the Microsoft codepath. Add the system to the quirk list to force Microsoft codepath. Link: https://gitlab.freedesktop.org/drm/amd/-/issues/2148 Tested-by: short-circuit Signed-off-by: Mario Limonciello Signed-off-by: Rafael J. Wysocki --- drivers/acpi/x86/s2idle.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c index c811eeed42cd..eedd21d8a284 100644 --- a/drivers/acpi/x86/s2idle.c +++ b/drivers/acpi/x86/s2idle.c @@ -440,6 +440,17 @@ static const struct dmi_system_id s2idle_dmi_table[] __initconst = { DMI_MATCH(DMI_PRODUCT_NAME, "82"), }, }, + { + /* + * ASUSTeK COMPUTER INC. ROG Flow X13 GV301RE_GV301RE + * https://gitlab.freedesktop.org/drm/amd/-/issues/2148 + */ + .callback = lps0_prefer_microsoft, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "ROG Flow X13 GV301"), + }, + }, {} }; From 39f81776c6807d605cfec6fa7a2439fa4786034e Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Wed, 28 Sep 2022 11:19:34 -0500 Subject: [PATCH 16/17] ACPI: x86: s2idle: Fix a NULL pointer dereference Ryzen 7000 (Raphael) introduced AMDI0008 for _HID. This ID was added in commit ed470febf837 ("ACPI: PM: s2idle: Add support for upcoming AMD uPEP HID AMDI008"), but then removed in favor of aligning all new IDs to Rembrandt support in commit fd894f05cf30 ("ACPI: x86: s2idle: If a new AMD _HID is missing assume Rembrandt"). Unfortunately there was a mistake in commit 100a57379380 ("ACPI: x86: s2idle: Move _HID handling for AMD systems into structures") that can lead to a NULL pointer dereference accessing `dev_id->driver_data` in the sentinel of `amd_hid_ids`. Fix this dereference. Reported-by: Richard Gong Fixes: 100a57379380 ("ACPI: x86: s2idle: Move _HID handling for AMD systems into structures") Signed-off-by: Mario Limonciello Signed-off-by: Rafael J. Wysocki --- drivers/acpi/x86/s2idle.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c index eedd21d8a284..3ae2ba74de92 100644 --- a/drivers/acpi/x86/s2idle.c +++ b/drivers/acpi/x86/s2idle.c @@ -470,7 +470,7 @@ static int lps0_device_attach(struct acpi_device *adev, for (dev_id = &amd_hid_ids[0]; dev_id->id[0]; dev_id++) if (acpi_dev_hid_uid_match(adev, dev_id->id, NULL)) break; - if (dev_id) + if (dev_id->id[0]) data = (const struct amd_lps0_hid_device_data *) dev_id->driver_data; else data = &amd_rembrandt; From 54bd1e548701640f2aff299aab192eec55571e01 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Wed, 28 Sep 2022 11:19:35 -0500 Subject: [PATCH 17/17] ACPI: x86: s2idle: Add another ID to s2idle_dmi_table It's reported that "ASUSTeK COMPUTER INC. ROG Flow X16 GV601RW" has non-functional fans after resume when using the AMD codepath. This issue is fixed using the Microsoft codepath. Add the 3 variants of this system to the Microsoft codepath DMI table. * GV601RW * GV601RM * GV601RE Link: https://www.reddit.com/r/linuxhardware/comments/wh50nd/compatibility_report_asus_rog_flow_x16_gv601rm/ Link: https://gitlab.freedesktop.org/drm/amd/-/issues/2148#note_1571241 Reported-by: Luke Jones Signed-off-by: Mario Limonciello Signed-off-by: Rafael J. Wysocki --- drivers/acpi/x86/s2idle.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c index 3ae2ba74de92..0155c1d2d608 100644 --- a/drivers/acpi/x86/s2idle.c +++ b/drivers/acpi/x86/s2idle.c @@ -451,6 +451,17 @@ static const struct dmi_system_id s2idle_dmi_table[] __initconst = { DMI_MATCH(DMI_PRODUCT_NAME, "ROG Flow X13 GV301"), }, }, + { + /* + * ASUSTeK COMPUTER INC. ROG Flow X16 GV601RW_GV601RW + * https://gitlab.freedesktop.org/drm/amd/-/issues/2148 + */ + .callback = lps0_prefer_microsoft, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "ROG Flow X16 GV601"), + }, + }, {} };