From 69242d5bb10e014c6c80bfb489e9574cab0db931 Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Thu, 26 Feb 2026 12:37:55 -0600 Subject: [PATCH] drivers/usb/acpi: Add DSM function 3 support for Intel Bluetooth The Linux btintel driver requires DSM function 3 (DSM_SET_RESET_METHOD) to be supported before it will use the ACPI _PRR/_RST reset path. Without it, the driver falls back to GPIO or USB reset. Add set_reset_method callback that returns success. coreboot only supports WDISABLE2 (GPIO); the _RST method already implements the toggle. Update the capability buffer (0x03 -> 0x0b) to advertise function 3 support. Change RDLY default from 105 to 160 ms to match the Linux driver. Change-Id: I6a7c9289dcffbbbd769ab3fb4e59765d2fef7598 Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/91445 Reviewed-by: Sean Rhodes Tested-by: build bot (Jenkins) --- src/drivers/usb/acpi/intel_bluetooth.c | 32 ++++++++++++++++++++------ 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/src/drivers/usb/acpi/intel_bluetooth.c b/src/drivers/usb/acpi/intel_bluetooth.c index 2ccb13bfe8..151f2bb18c 100644 --- a/src/drivers/usb/acpi/intel_bluetooth.c +++ b/src/drivers/usb/acpi/intel_bluetooth.c @@ -14,16 +14,20 @@ * * Arg2 == 1: Set the reset delay based on Arg3 * - * Arg2 == 3: Set the reset method based on Arg3 (Not supported by this driver) - * WDISABLE2 (BT_RF_KILL_N) - * VSEC (PCI Config Space) + * Arg2 == 2: Reserved + * + * Arg2 == 3: Set the reset method based on Arg3 (required by Linux driver) + * Arg3 is a 4-byte buffer: [0x01, 0x00, type, 0x00] + * type 0 = WDISABLE2 (BT_RF_KILL_N) - supported by this driver + * type 1 = VSEC (PCI Config Space) - not supported */ static void check_reset_delay(void *arg) { acpigen_write_if_lequal_op_int(ARG1_OP, 0); { - acpigen_write_return_singleton_buffer(0x03); + /* Bits 0, 1, 3: other funcs, reset timing, set reset method (Linux) */ + acpigen_write_return_singleton_buffer(0x0b); } acpigen_write_else(); { @@ -37,12 +41,26 @@ static void set_reset_delay(void *arg) acpigen_write_store_op_to_namestr(ARG3_OP, "RDLY"); } +static void set_reset_method(void *arg) +{ + /* + * coreboot only supports WDISABLE2 (GPIO). Linux sends type in Arg3[2]. + * Accept and return success - _RST already implements GPIO toggle. + */ + acpigen_write_return_singleton_buffer(0x01); +} + static void not_supported(void *arg) { acpigen_write_return_singleton_buffer(0x00); } -void (*reset_supported[])(void *) = { check_reset_delay, set_reset_delay }; +void (*reset_supported[])(void *) = { + check_reset_delay, /* 0: capability query */ + set_reset_delay, /* 1: set delay */ + not_supported, /* 2: reserved */ + set_reset_method, /* 3: set reset method (required by Linux) */ +}; void (*reset_unsupported[])(void *) = { not_supported }; void acpi_device_intel_bt(const struct acpi_gpio *enable_gpio, @@ -55,9 +73,9 @@ void acpi_device_intel_bt(const struct acpi_gpio *enable_gpio, acpigen_write_name_integer("_S0W", ACPI_DEVICE_SLEEP_D2); /* - * Name (RDLY, 0x69) + * Name (RDLY, 160) // ms, matches Linux driver default */ - acpigen_write_name_integer("RDLY", 0x69); + acpigen_write_name_integer("RDLY", 160); /* * Method (_DSM, 4, Serialized)