diff options
author | Raghuram Hegde <raghuram.hegde@intel.com> | 2019-01-29 07:24:48 -0500 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2019-01-29 10:15:29 -0500 |
commit | 017a01ccfbc5a35aed83acbf2ee2735f8c3efe8a (patch) | |
tree | b0cb2687e69abede6b7570a757bc6762e17bd5af /drivers/bluetooth/btusb.c | |
parent | 2de66bb87351086ce9bef37c1b98d9bae93eddcd (diff) |
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.c | 19 |
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) | |||
2434 | return 0; | 2434 | return 0; |
2435 | } | 2435 | } |
2436 | 2436 | ||
2437 | static int btusb_shutdown_intel_new(struct hci_dev *hdev) | ||
2438 | { | ||
2439 | struct sk_buff *skb; | ||
2440 | |||
2441 | /* Send HCI Reset to the controller to stop any BT activity which | ||
2442 | * were triggered. This will help to save power and maintain the | ||
2443 | * sync b/w Host and controller | ||
2444 | */ | ||
2445 | skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, HCI_INIT_TIMEOUT); | ||
2446 | if (IS_ERR(skb)) { | ||
2447 | bt_dev_err(hdev, "HCI reset during shutdown failed"); | ||
2448 | return PTR_ERR(skb); | ||
2449 | } | ||
2450 | kfree_skb(skb); | ||
2451 | |||
2452 | return 0; | ||
2453 | } | ||
2454 | |||
2437 | #ifdef CONFIG_PM | 2455 | #ifdef CONFIG_PM |
2438 | /* Configure an out-of-band gpio as wake-up pin, if specified in device tree */ | 2456 | /* Configure an out-of-band gpio as wake-up pin, if specified in device tree */ |
2439 | static int marvell_config_oob_wake(struct hci_dev *hdev) | 2457 | static int marvell_config_oob_wake(struct hci_dev *hdev) |
@@ -3139,6 +3157,7 @@ static int btusb_probe(struct usb_interface *intf, | |||
3139 | hdev->manufacturer = 2; | 3157 | hdev->manufacturer = 2; |
3140 | hdev->send = btusb_send_frame_intel; | 3158 | hdev->send = btusb_send_frame_intel; |
3141 | hdev->setup = btusb_setup_intel_new; | 3159 | hdev->setup = btusb_setup_intel_new; |
3160 | hdev->shutdown = btusb_shutdown_intel_new; | ||
3142 | hdev->hw_error = btintel_hw_error; | 3161 | hdev->hw_error = btintel_hw_error; |
3143 | hdev->set_diag = btintel_set_diag; | 3162 | hdev->set_diag = btintel_set_diag; |
3144 | hdev->set_bdaddr = btintel_set_bdaddr; | 3163 | hdev->set_bdaddr = btintel_set_bdaddr; |