Bluetooth: btintel: Fix the LED is not turning off immediately
authorTedd Ho-Jeong An <tedd.an@intel.com>
Thu, 5 Aug 2021 00:32:13 +0000 (17:32 -0700)
committerMarcel Holtmann <marcel@holtmann.org>
Thu, 5 Aug 2021 14:03:29 +0000 (16:03 +0200)
Some platforms have an issue with BT LED when the interface is
down or BT radio is turned off, which takes 5 seconds to BT LED
goes off. This command turns off the BT LED immediately.

This patch sends the Intel vendor command to turn off the LED.

Signed-off-by: Tedd Ho-Jeong An <tedd.an@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
drivers/bluetooth/btintel.c
drivers/bluetooth/btintel.h

index 8e6b497..fd947a8 100644 (file)
@@ -1737,6 +1737,13 @@ static int btintel_setup_combined(struct hci_dev *hdev)
                case 0x07:      /* WP */
                case 0x08:      /* StP */
                        /* Legacy ROM product */
+
+                       /* These devices have an issue with LED which doesn't
+                        * go off immediately during shutdown. Set the flag
+                        * here to send the LED OFF command during shutdown.
+                        */
+                       btintel_set_flag(hdev, INTEL_BROKEN_LED);
+
                        err = btintel_legacy_rom_setup(hdev, &ver);
                        break;
                case 0x0b:      /* SfP */
@@ -1785,6 +1792,7 @@ exit_error:
 static int btintel_shutdown_combined(struct hci_dev *hdev)
 {
        struct sk_buff *skb;
+       int ret;
 
        /* Send HCI Reset to the controller to stop any BT activity which
         * were triggered. This will help to save power and maintain the
@@ -1797,6 +1805,21 @@ static int btintel_shutdown_combined(struct hci_dev *hdev)
        }
        kfree_skb(skb);
 
+
+       /* Some platforms have an issue with BT LED when the interface is
+        * down or BT radio is turned off, which takes 5 seconds to BT LED
+        * goes off. This command turns off the BT LED immediately.
+        */
+       if (btintel_test_flag(hdev, INTEL_BROKEN_LED)) {
+               skb = __hci_cmd_sync(hdev, 0xfc3f, 0, NULL, HCI_INIT_TIMEOUT);
+               if (IS_ERR(skb)) {
+                       ret = PTR_ERR(skb);
+                       bt_dev_err(hdev, "turning off Intel device LED failed");
+                       return ret;
+               }
+               kfree_skb(skb);
+       }
+
        return 0;
 }
 
index 8a49795..aef04fa 100644 (file)
@@ -145,6 +145,7 @@ enum {
        INTEL_FIRMWARE_FAILED,
        INTEL_BOOTING,
        INTEL_BROKEN_INITIAL_NCMD,
+       INTEL_BROKEN_LED,
 
        __INTEL_NUM_FLAGS,
 };