Skip to content

Commit 215be99

Browse files
committed
BACKPORT: driver: bluetooth: hci_qca: Fix SSR (SubSystem Restart) fail when BT_EN is pulled up by hw
On QCS9075 and QCA8275 platforms, the BT_EN pin is always pulled up by hw and cannot be controlled by the host. As a result, in case of a firmware crash, the host cannot trigger a cold reset. Instead, the BT controller performs a warm restart on its own, without reloading the firmware. This leads to the controller remaining in IBS_WAKE state, while the host expects it to be in sleep mode. The mismatch causes HCI reset commands to time out. Additionally, the driver does not clear internal flags QCA_SSR_TRIGGERED and QCA_IBS_DISABLED, which blocks the reset sequence. If the SSR duration exceeds 2 seconds, the host may enter TX sleep mode due to tx_idle_timeout, further preventing recovery. Also, memcoredump_flag is not cleared, so only the first SSR generates a coredump. Tell the driver that the BT controller has undergone a proper restart sequence: - Clear QCA_SSR_TRIGGERED and QCA_IBS_DISABLED flags after SSR. - Add a 50ms delay to allow the controller to complete its warm reset. - Reset tx_idle_timer to prevent the host from entering TX sleep mode. - Clear memcoredump_flag to allow multiple coredump captures. Apply these steps only when HCI_QUIRK_NON_PERSISTENT_SETUP is not set, which indicates that BT_EN is defined in DTS and cannot be toggled. Refer to the comment in include/net/bluetooth/hci.h for details on HCI_QUIRK_NON_PERSISTENT_SETUP. Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> Signed-off-by: Shuai Zhang <shuai.zhang@oss.qualcomm.com> link: https://lore.kernel.org/all/20251203033712.446632-1-shuai.zhang@oss.qualcomm.com/
1 parent 0cf570b commit 215be99

1 file changed

Lines changed: 25 additions & 10 deletions

File tree

drivers/bluetooth/hci_qca.c

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1653,25 +1653,40 @@ static void qca_hw_error(struct hci_dev *hdev, u8 code)
16531653
skb_queue_purge(&qca->rx_memdump_q);
16541654
}
16551655

1656-
clear_bit(QCA_HW_ERROR_EVENT, &qca->flags);
1657-
16581656
/*
1659-
* If the SoC always enables the bt_en pin via hardware and the driver
1660-
* cannot control the bt_en pin of the SoC chip, then during SSR,
1661-
* the QCA_SSR_TRIGGERED and QCA_IBS_DISABLED bits cannot be cleared.
1662-
* This leads to a reset command timeout failure.
1657+
* If the BT chip's bt_en pin is connected to a 3.3V power supply via
1658+
* hardware and always stays high, driver cannot control the bt_en pin.
1659+
* As a result, during SSR (SubSystem Restart), QCA_SSR_TRIGGERED and
1660+
* QCA_IBS_DISABLED flags cannot be cleared, which leads to a reset
1661+
* command timeout.
1662+
* Add an msleep delay to ensure controller completes the SSR process.
1663+
*
1664+
* Host will not download the firmware after SSR, controller to remain
1665+
* in the IBS_WAKE state, and the host needs to synchronize with it
16631666
*
1664-
* To address this, clear QCA_SSR_TRIGGERED and QCA_IBS_DISABLED bits
1665-
* after the coredump collection is complete.
1666-
* Also, add msleep delay to wait for controller to complete SSR.
1667+
* Since the bluetooth chip has been reset, clear the memdump state.
16671668
*/
16681669
if (!hci_test_quirk(hu->hdev, HCI_QUIRK_NON_PERSISTENT_SETUP)) {
1670+
/*
1671+
* When the SSR (SubSystem Restart) duration exceeds 2 seconds,
1672+
* it triggers host tx_idle_delay, which sets host TX state
1673+
* to sleep. Reset tx_idle_timer after SSR to prevent
1674+
* host enter TX IBS_Sleep mode.
1675+
*/
1676+
mod_timer(&qca->tx_idle_timer, jiffies +
1677+
msecs_to_jiffies(qca->tx_idle_delay));
1678+
1679+
/* Controller reset completion time is 50ms */
1680+
msleep(50);
1681+
16691682
clear_bit(QCA_SSR_TRIGGERED, &qca->flags);
16701683
clear_bit(QCA_IBS_DISABLED, &qca->flags);
1684+
16711685
qca->tx_ibs_state = HCI_IBS_TX_AWAKE;
16721686
qca->memdump_state = QCA_MEMDUMP_IDLE;
1673-
msleep(50);
16741687
}
1688+
1689+
clear_bit(QCA_HW_ERROR_EVENT, &qca->flags);
16751690
}
16761691

16771692
static void qca_reset(struct hci_dev *hdev)

0 commit comments

Comments
 (0)