From b758a6c48d418a89f8d2bc08c5daa778b162b5b3 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 7 Jun 2021 11:55:57 +0200 Subject: [PATCH] ACPI: Only run _OSC without the query flag on machines with native USB4 support Commit 719e1f561afb ("ACPI: Execute platform _OSC also with query bit clear") makes acpi_bus_osc_negotiate_platform_control() not only query the platforms capabilities but it also commits the result back to the firmware to report which capabilities are supported by the OS back to the firmware. This reporting back of the OS supported capabilities is necessary for USB4 support, but it is causing problems on some other devices, causing some SSDTs to no longer load on these devices. Make the reporting back of the capabilities (the _OSC call with the query flag cleared) conditional on the queried capabilities including native USB4 support, skipping it when there is no native USB4 support to fix the regressions caused by doing this on some machines without native USB4 support. BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=213023 BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1963717 Fixes: 719e1f561afb ("ACPI: Execute platform _OSC also with query bit clear") Cc: Mario Limonciello Signed-off-by: Hans de Goede --- drivers/acpi/bus.c | 41 +++++++++++++++++++---------------------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index be7da23fad76..9a56a6f653cc 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -286,7 +286,7 @@ EXPORT_SYMBOL_GPL(osc_sb_native_usb4_support_confirmed); static u8 sb_uuid_str[] = "0811B06E-4A27-44F9-8D60-3CBBC22E7B48"; static void acpi_bus_osc_negotiate_platform_control(void) { - u32 capbuf[2], *capbuf_ret; + u32 capbuf[2], caps = 0; struct acpi_osc_context context = { .uuid_str = sb_uuid_str, .rev = 1, @@ -330,34 +330,31 @@ static void acpi_bus_osc_negotiate_platform_control(void) if (ACPI_FAILURE(acpi_run_osc(handle, &context))) return; - capbuf_ret = context.ret.pointer; - if (context.ret.length <= OSC_SUPPORT_DWORD) { - kfree(context.ret.pointer); - return; + if (context.ret.length > OSC_SUPPORT_DWORD) { + u32 *capbuf_ret = context.ret.pointer; + + caps = capbuf_ret[OSC_SUPPORT_DWORD]; } + kfree(context.ret.pointer); + + osc_sb_apei_support_acked = caps & OSC_SB_APEI_SUPPORT; + osc_pc_lpi_support_confirmed = caps & OSC_SB_PCLPI_SUPPORT; + osc_sb_native_usb4_support_confirmed = caps & OSC_SB_NATIVE_USB4_SUPPORT; /* - * Now run _OSC again with query flag clear and with the caps - * supported by both the OS and the platform. + * On machines with native USB4 support, run _OSC again with the query + * flag cleared and with the caps supported by both the OS and the + * platform to let the firmware know we support native USB4. */ - capbuf[OSC_QUERY_DWORD] = 0; - capbuf[OSC_SUPPORT_DWORD] = capbuf_ret[OSC_SUPPORT_DWORD]; - kfree(context.ret.pointer); + if (osc_sb_native_usb4_support_confirmed) { + capbuf[OSC_QUERY_DWORD] = 0; + capbuf[OSC_SUPPORT_DWORD] = caps; - if (ACPI_FAILURE(acpi_run_osc(handle, &context))) - return; + if (ACPI_FAILURE(acpi_run_osc(handle, &context))) + return; - capbuf_ret = context.ret.pointer; - if (context.ret.length > OSC_SUPPORT_DWORD) { - osc_sb_apei_support_acked = - capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_APEI_SUPPORT; - osc_pc_lpi_support_confirmed = - capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_PCLPI_SUPPORT; - osc_sb_native_usb4_support_confirmed = - capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_NATIVE_USB4_SUPPORT; + kfree(context.ret.pointer); } - - kfree(context.ret.pointer); } /* -- 2.31.1