summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Lu <alex_lu@realsil.com.cn>2019-09-04 22:36:31 -0400
committerMarcel Holtmann <marcel@holtmann.org>2019-09-05 11:32:28 -0400
commitd7ef0d1e39685b38c97b30daa6de0d50df004839 (patch)
treeefdd5eb7b540451fd025b27b9c27ab4f0ee12ef9
parentcf0d9a705d81a0f581865cefe0880f29589dd06f (diff)
Bluetooth: btusb: Use cmd_timeout to reset Realtek device
Realtek Bluetooth controller provides a BT_DIS reset pin for hardware reset of it. The cmd_timeout is helpful on Realtek bluetooth controller where the firmware gets stuck. Signed-off-by: Alex Lu <alex_lu@realsil.com.cn> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
-rw-r--r--drivers/bluetooth/btusb.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 31d3febed187..ed455de598ea 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -524,6 +524,36 @@ static void btusb_intel_cmd_timeout(struct hci_dev *hdev)
524 gpiod_set_value_cansleep(reset_gpio, 0); 524 gpiod_set_value_cansleep(reset_gpio, 0);
525} 525}
526 526
527static void btusb_rtl_cmd_timeout(struct hci_dev *hdev)
528{
529 struct btusb_data *data = hci_get_drvdata(hdev);
530 struct gpio_desc *reset_gpio = data->reset_gpio;
531
532 if (++data->cmd_timeout_cnt < 5)
533 return;
534
535 if (!reset_gpio) {
536 bt_dev_err(hdev, "No gpio to reset Realtek device, ignoring");
537 return;
538 }
539
540 /* Toggle the hard reset line. The Realtek device is going to
541 * yank itself off the USB and then replug. The cleanup is handled
542 * correctly on the way out (standard USB disconnect), and the new
543 * device is detected cleanly and bound to the driver again like
544 * it should be.
545 */
546 if (test_and_set_bit(BTUSB_HW_RESET_ACTIVE, &data->flags)) {
547 bt_dev_err(hdev, "last reset failed? Not resetting again");
548 return;
549 }
550
551 bt_dev_err(hdev, "Reset Realtek device via gpio");
552 gpiod_set_value_cansleep(reset_gpio, 0);
553 msleep(200);
554 gpiod_set_value_cansleep(reset_gpio, 1);
555}
556
527static inline void btusb_free_frags(struct btusb_data *data) 557static inline void btusb_free_frags(struct btusb_data *data)
528{ 558{
529 unsigned long flags; 559 unsigned long flags;
@@ -3783,6 +3813,7 @@ static int btusb_probe(struct usb_interface *intf,
3783 if (id->driver_info & BTUSB_REALTEK) { 3813 if (id->driver_info & BTUSB_REALTEK) {
3784 hdev->setup = btrtl_setup_realtek; 3814 hdev->setup = btrtl_setup_realtek;
3785 hdev->shutdown = btrtl_shutdown_realtek; 3815 hdev->shutdown = btrtl_shutdown_realtek;
3816 hdev->cmd_timeout = btusb_rtl_cmd_timeout;
3786 3817
3787 /* Realtek devices lose their updated firmware over global 3818 /* Realtek devices lose their updated firmware over global
3788 * suspend that means host doesn't send SET_FEATURE 3819 * suspend that means host doesn't send SET_FEATURE