Skip to contentSkip to conversation

Bluetooth: Add device shutdown routine for Intel Bluetooth device

PATCH Superseded Tedd Ho-Jeong An 2 participants 2 messages Feb 5, 2015 – Feb 12, 2015 Bluetooth drivers

v1 of 2 Superseded Latest is v2 →

lore
Share & tools
lore
#0 lore raw

PATCH 2/2 Bluetooth: Add device shutdown routine for Intel Bluetooth device

From: Tedd Ho-Jeong An <[email protected]>

This patch adds the device shutdown routine for Intel Bluetooth device.

Some platforms have BT LED issue with Intel Bluetooth device that BT LED goes off 5 seconds after BT is turned off

For Intel Bluetooth device, the BT LED is turned off when:
- there is no active connection or radio activity
- USB is suspend

So, when the BT is turned off, it takes 5 seconds because USB suspend timeone is 5 seconds by default. And if the USB suspend is not enabled, BT LED won't be turned off.

To fix this issue, recently Intel Bluetooth firmware patch had been submitted to turn off the BT LED explicitly by the vendor specific command(0xFC3F). And this patch sends this command to the device before closing the device.

For backward compatibility of this command with old firmware, this command was supported before, but it behaves same as HCI_RESET internally. So, it won't be the problem even if the system doesn't have the latest firmware patch.

---
 drivers/bluetooth/btusb.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)
drivers/bluetooth/btusb.c +18 -0
index b876888..e0f8a15 100644
@@ -2331,6 +2331,23 @@ static int btusb_set_bdaddr_intel(struct hci_dev *hdev, const bdaddr_t *bdaddr)
 	return 0;
 }
 
+static int btusb_shutdown_intel(struct hci_dev *hdev)
+{
+	struct sk_buff *skb;
+	long ret;
+
+	skb = __hci_cmd_sync(hdev, 0xfc3f, 0, NULL, HCI_INIT_TIMEOUT);
+	if (IS_ERR(skb)) {
+		ret = PTR_ERR(skb);
+		BT_ERR("%s: turning off Intel device LED failed (%ld)",
+		       hdev->name, ret);
+		return ret;
+	}
+	kfree_skb(skb);
+
+	return 0;
+}
+
 static int btusb_set_bdaddr_marvell(struct hci_dev *hdev,
 				    const bdaddr_t *bdaddr)
 {
@@ -2709,6 +2726,7 @@ static int btusb_probe(struct usb_interface *intf,
 	if (id->driver_info & BTUSB_INTEL) {
 		hdev->setup = btusb_setup_intel;
 		hdev->set_bdaddr = btusb_set_bdaddr_intel;
+		hdev->shutdown = btusb_shutdown_intel;
 		set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks);
 	}
 
Signature · 1 line
1.9.1
maintainer
#1 lore raw

Hi Tedd,

Quoted 31 lines

This patch adds the device shutdown routine for Intel Bluetooth device.

Some platforms have BT LED issue with Intel Bluetooth device that BT LED goes off 5 seconds after BT is turned off

For Intel Bluetooth device, the BT LED is turned off when:
- there is no active connection or radio activity
- USB is suspend

So, when the BT is turned off, it takes 5 seconds because USB suspend timeone is 5 seconds by default. And if the USB suspend is not enabled, BT LED won't be turned off.

To fix this issue, recently Intel Bluetooth firmware patch had been submitted to turn off the BT LED explicitly by the vendor specific command(0xFC3F). And this patch sends this command to the device before closing the device.

For backward compatibility of this command with old firmware, this command was supported before, but it behaves same as HCI_RESET internally. So, it won't be the problem even if the system doesn't have the latest firmware patch.

---
drivers/bluetooth/btusb.c | 18 ++++++++++++++++++

1 file changed, 18 insertions(+)
drivers/bluetooth/btusb.c +0 -0
index b876888..e0f8a15 100644

drivers/bluetooth/btusb.c static int btusb_set_bdaddr_intel(struct hci_dev *hdev, const bdaddr_t *bdaddr) · line 2338

Quoted 8 lines
drivers/bluetooth/btusb.c +5 -0
@@ -2331,6 +2331,23 @@ static int btusb_set_bdaddr_intel(struct hci_dev *hdev, const bdaddr_t *bdaddr)
 	return 0;
 }
 
+static int btusb_shutdown_intel(struct hci_dev *hdev)
+{
+	struct sk_buff *skb;
+	long ret;
+

please add a comment on why we are doing this and what it does. I know you have it in the commit message, but I think an extra one would be helpful here.

Quoted 16 lines
drivers/bluetooth/btusb.c +12 -0
+	skb = __hci_cmd_sync(hdev, 0xfc3f, 0, NULL, HCI_INIT_TIMEOUT);
+	if (IS_ERR(skb)) {
+		ret = PTR_ERR(skb);
+		BT_ERR("%s: turning off Intel device LED failed (%ld)",
+		       hdev->name, ret);
+		return ret;
+	}
+	kfree_skb(skb);
+
+	return 0;
+}
+
 static int btusb_set_bdaddr_marvell(struct hci_dev *hdev,
 				    const bdaddr_t *bdaddr)
 {

drivers/bluetooth/btusb.c static int btusb_probe(struct usb_interface *intf, · line 2729

Quoted 4 lines
drivers/bluetooth/btusb.c +1 -0
@@ -2709,6 +2726,7 @@ static int btusb_probe(struct usb_interface *intf,
 	if (id->driver_info & BTUSB_INTEL) {
 		hdev->setup = btusb_setup_intel;
 		hdev->set_bdaddr = btusb_set_bdaddr_intel;
+		hdev->shutdown = btusb_shutdown_intel;

Please sort it after setup().

Regards

Marcel