summaryrefslogtreecommitdiff
path: root/drivers/bluetooth/btusb.c
diff options
context:
space:
mode:
authorKiran K <kiran.k@intel.com>2023-06-11 09:43:42 +0300
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>2023-08-11 21:39:19 +0300
commit8f0a3786f56d9fa4b308bdbd54757a51145dbb7a (patch)
tree721c3ea549865436ba6ef19bff3e445a709ffa8f /drivers/bluetooth/btusb.c
parent06d3fdfcdf5cefb06f2024b9d3dad356779399cf (diff)
downloadlinux-8f0a3786f56d9fa4b308bdbd54757a51145dbb7a.tar.xz
Bluetooth: btintel: Add support to reset bluetooth via ACPI DSM
New Intel platforms supports reset of Bluetooth device via ACPI DSM methods. The legacy reset mechanism via GPIO will be deprecated in future. This patch checks the platform support for reset methods and if supported uses the same instead of legacy GPIO toggling method. ACPI firmware supports two types of reset method based on NIC card. (Discrete or Integrated). 1. VSEC Type - Vendor Specific Extended Capability. Here BT_EN and BT_IF_SELECT lines are driven by a register in PCH cluster. This interface is supported on discrete BT solution. 2. WDISABLE2 - In this soluton, W_DISABLE2 pin in M.2 is connected to physical GPIO from PCH. The DSM interface shall toggle this to recover from error. Signed-off-by: Kiran K <kiran.k@intel.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Diffstat (limited to 'drivers/bluetooth/btusb.c')
-rw-r--r--drivers/bluetooth/btusb.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 711beaa0ac56..f99ce34abb9f 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -860,10 +860,26 @@ static void btusb_intel_cmd_timeout(struct hci_dev *hdev)
{
struct btusb_data *data = hci_get_drvdata(hdev);
struct gpio_desc *reset_gpio = data->reset_gpio;
+ struct btintel_data *intel_data = hci_get_priv(hdev);
if (++data->cmd_timeout_cnt < 5)
return;
+ if (intel_data->acpi_reset_method) {
+ if (test_and_set_bit(INTEL_ACPI_RESET_ACTIVE, intel_data->flags)) {
+ bt_dev_err(hdev, "acpi: last reset failed ? Not resetting again");
+ return;
+ }
+
+ bt_dev_err(hdev, "Initiating acpi reset method");
+ /* If ACPI reset method fails, lets try with legacy GPIO
+ * toggling
+ */
+ if (!intel_data->acpi_reset_method(hdev)) {
+ return;
+ }
+ }
+
if (!reset_gpio) {
btusb_reset(hdev);
return;