blob: fce0734d4e73bbb6e01b7e8632c78efe640bf20a [file] [log] [blame]
From 65b2e041e095cbdbe9ec1e85acd07cdbeb84ba47 Mon Sep 17 00:00:00 2001
From: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
Date: Thu, 1 Sep 2022 15:03:03 -0700
Subject: [PATCH] CHROMIUM: Bluetooth: Allow reset via sysfs
Allow sysfs to trigger reset via the cmd_timeout function in hci device.
This is required to recover devices that are not responsive from
userspace.
Also remove the cmd timeout count in btusb since we only ever allow one
command in flight at a time. We should always reset after a single
command times out.
BUG=b:236709385
TEST=Manually tested on Zork
Change-Id: Ieb10dafe1d42925449c4ecb56f7fe97b7345399f
Signed-off-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/3869332
Reviewed-by: Alain Michaud <alainm@chromium.org>
Reviewed-by: Ying Hsu <yinghsu@chromium.org>
Commit-Queue: Abhishek Pandit-Subedi <abhishekpandit@google.com>
Reviewed-by: Michael Sun <michaelfsun@google.com>
Tested-by: Abhishek Pandit-Subedi <abhishekpandit@google.com>
---
drivers/bluetooth/btusb.c | 10 ----------
net/bluetooth/hci_sysfs.c | 13 +++++++++++++
2 files changed, 13 insertions(+), 10 deletions(-)
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index f73ef4972a5a1e5bd687522884be50064418a826..0247126f37c66f5cb6c96024578ed0cbf43c5ed4 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -842,7 +842,6 @@ struct btusb_data {
int (*setup_on_usb)(struct hci_dev *hdev);
int oob_wake_irq; /* irq for out-of-band wake-on-bt */
- unsigned cmd_timeout_cnt;
struct qca_dump_info qca_dump;
};
@@ -875,9 +874,6 @@ static void btusb_intel_cmd_timeout(struct hci_dev *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");
@@ -960,9 +956,6 @@ static void btusb_rtl_cmd_timeout(struct hci_dev *hdev)
btusb_rtl_alloc_devcoredump(hdev, &hdr, NULL, 0);
- if (++data->cmd_timeout_cnt < 5)
- return;
-
if (!reset_gpio) {
btusb_reset(hdev);
return;
@@ -1007,9 +1000,6 @@ static void btusb_qca_cmd_timeout(struct hci_dev *hdev)
return;
}
- if (++data->cmd_timeout_cnt < 5)
- return;
-
if (reset_gpio) {
bt_dev_err(hdev, "Reset qca device via bt_en gpio");
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
index a8bce896cb4b4a09fe72e21b56081e16bc8410a8..196e40b223702266c42f3b4383b70adf04c4a8c3 100644
--- a/net/bluetooth/hci_sysfs.c
+++ b/net/bluetooth/hci_sysfs.c
@@ -106,8 +106,21 @@ static ssize_t identity_show(struct device *dev,
}
DEVICE_ATTR_RO(identity);
+static ssize_t reset_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct hci_dev *hdev = to_hci_dev(dev);
+
+ if (hdev->cmd_timeout)
+ hdev->cmd_timeout(hdev);
+
+ return count;
+}
+DEVICE_ATTR_WO(reset);
+
static struct attribute *bt_host_attrs[] = {
&dev_attr_identity.attr,
+ &dev_attr_reset.attr,
NULL,
};
ATTRIBUTE_GROUPS(bt_host);
--
2.34.1