blob: 2b871d1f47a097d7ddb44fe318b1a3c19774fdef [file] [log] [blame]
From 671ae89f888843abf343f66b2490a7dc04bfd221 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 59dc93e5823590b112055cc6654b266079dd67c7..8b946c04e4f88dee8921089a5b16b4e5f38c3a44 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -789,7 +789,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;
};
static void btusb_reset(struct hci_dev *hdev)
@@ -819,9 +818,6 @@ 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;
- if (++data->cmd_timeout_cnt < 5)
- return;
-
if (!reset_gpio) {
btusb_reset(hdev);
return;
@@ -850,9 +846,6 @@ static void btusb_rtl_cmd_timeout(struct hci_dev *hdev)
struct btusb_data *data = hci_get_drvdata(hdev);
struct gpio_desc *reset_gpio = data->reset_gpio;
- if (++data->cmd_timeout_cnt < 5)
- return;
-
if (!reset_gpio) {
btusb_reset(hdev);
return;
@@ -880,9 +873,6 @@ static void btusb_qca_cmd_timeout(struct hci_dev *hdev)
struct btusb_data *data = hci_get_drvdata(hdev);
struct gpio_desc *reset_gpio = data->reset_gpio;
- 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 0d7250a534ba289cd85f6d85e287fd56db3806e8..5e7d77979f26d622e530aa6e20c366f8a7084910 100644
--- a/net/bluetooth/hci_sysfs.c
+++ b/net/bluetooth/hci_sysfs.c
@@ -104,8 +104,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.39.0.314.g84b9a713c41-goog