From 017a01ccfbc5a35aed83acbf2ee2735f8c3efe8a Mon Sep 17 00:00:00 2001 From: Raghuram Hegde Date: Tue, 29 Jan 2019 17:54:48 +0530 Subject: 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 Signed-off-by: Chethan T N Signed-off-by: Marcel Holtmann --- drivers/bluetooth/btusb.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'drivers/bluetooth/btusb.c') 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; -- cgit v1.2.3-59-g8ed1b