]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
Bluetooth: hci_qca: Use 100 ms SSR delay for rampatch and NVM loading
authorShuai Zhang <shuai.zhang@oss.qualcomm.com>
Mon, 25 May 2026 06:51:56 +0000 (14:51 +0800)
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Wed, 27 May 2026 20:44:02 +0000 (16:44 -0400)
When bt_en is pulled high by hardware, the host does not re-download
the firmware after SSR. The controller loads the rampatch and NVM
internally.

On HMT chip, the rampatch is ~264 KB and the NVM is ~9.4 KB. The
loading process takes approximately 70 ms. The previous 50 ms delay is
too short, causing the controller to not respond to the reset command
sent by the host, which leads to BT initialization failure:

 Bluetooth: hci0: QCA memdump Done, received 458752, total 458752
 Bluetooth: hci0: mem_dump_status: 2
 Bluetooth: hci0: Opcode 0x0c03 failed: -110

Increase the delay to 100 ms, which was confirmed as a safe value by
the controller, to ensure the controller has finished loading the
firmware before the host sends commands.

Steps to reproduce:
1. Trigger SSR and wait for SSR to complete:
   hcitool cmd 0x3f 0c 26
2. Run "bluetoothctl power on" and observe that BT fails to start.

Fixes: fce1a9244a0f ("Bluetooth: hci_qca: Fix SSR (SubSystem Restart) fail when BT_EN is pulled up by hw")
Cc: stable@vger.kernel.org
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Signed-off-by: Shuai Zhang <shuai.zhang@oss.qualcomm.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
drivers/bluetooth/hci_qca.c

index ed280399bf4741977a021614cfe68e2b816fb4c2..34500137df2c107bf4fb820b3d7df21c4d085635 100644 (file)
@@ -1680,8 +1680,8 @@ static void qca_hw_error(struct hci_dev *hdev, u8 code)
                mod_timer(&qca->tx_idle_timer, jiffies +
                                  msecs_to_jiffies(qca->tx_idle_delay));
 
-               /* Controller reset completion time is 50ms */
-               msleep(50);
+               /* Wait for the controller to load the rampatch and NVM. */
+               msleep(100);
 
                clear_bit(QCA_SSR_TRIGGERED, &qca->flags);
                clear_bit(QCA_IBS_DISABLED, &qca->flags);