aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/bluetooth/btusb.c
diff options
context:
space:
mode:
authorRaghuram Hegde <raghuram.hegde@intel.com>2019-01-29 17:54:48 +0530
committerMarcel Holtmann <marcel@holtmann.org>2019-01-29 16:15:29 +0100
commit017a01ccfbc5a35aed83acbf2ee2735f8c3efe8a (patch)
treeb0cb2687e69abede6b7570a757bc6762e17bd5af /drivers/bluetooth/btusb.c
parentBluetooth: btusb: btusb_intel_cmd_timeout: use sleeping functions (diff)
downloadlinux-dev-017a01ccfbc5a35aed83acbf2ee2735f8c3efe8a.tar.xz
linux-dev-017a01ccfbc5a35aed83acbf2ee2735f8c3efe8a.zip
Bluetooth: btusb: Add shutdown routine for BTUSB_INTEL_NEW devices
If BT operations (BREDR inquiry/LE scan) were triggered through the stack, followed by BT turn off through 'hciconfig hci0 down', the controller would still be active and consume power. Also, there is a possibility that a race condition/ synchronization issue might arise on the subsequent BT turn on, as the controller might try to push the events that were queued up before processing the HCI Reset command. btusb_shutdown_intel_new routine shall reset the controller and stop all BT operation. Advantages: 1. Power save on the platform 2. Host and controller will be in Sync. Signed-off-by: Raghuram Hegde <raghuram.hegde@intel.com> Signed-off-by: Chethan T N <chethan.tumkur.narayan@intel.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'drivers/bluetooth/btusb.c')
-rw-r--r--drivers/bluetooth/btusb.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 9a890b2a7ee1..d4c8d989e714 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -2434,6 +2434,24 @@ static int btusb_shutdown_intel(struct hci_dev *hdev)
return 0;
}
+static int btusb_shutdown_intel_new(struct hci_dev *hdev)
+{
+ struct sk_buff *skb;
+
+ /* Send HCI Reset to the controller to stop any BT activity which
+ * were triggered. This will help to save power and maintain the
+ * sync b/w Host and controller
+ */
+ skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, HCI_INIT_TIMEOUT);
+ if (IS_ERR(skb)) {
+ bt_dev_err(hdev, "HCI reset during shutdown failed");
+ return PTR_ERR(skb);
+ }
+ kfree_skb(skb);
+
+ return 0;
+}
+
#ifdef CONFIG_PM
/* Configure an out-of-band gpio as wake-up pin, if specified in device tree */
static int marvell_config_oob_wake(struct hci_dev *hdev)
@@ -3139,6 +3157,7 @@ static int btusb_probe(struct usb_interface *intf,
hdev->manufacturer = 2;
hdev->send = btusb_send_frame_intel;
hdev->setup = btusb_setup_intel_new;
+ hdev->shutdown = btusb_shutdown_intel_new;
hdev->hw_error = btintel_hw_error;
hdev->set_diag = btintel_set_diag;
hdev->set_bdaddr = btintel_set_bdaddr;