Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

authored by

Shuai Zhang and committed by
Luiz Augusto von Dentz
fce1a924 e75e408d

+33
+33
drivers/bluetooth/hci_qca.c
··· 1653 1653 skb_queue_purge(&qca->rx_memdump_q); 1654 1654 } 1655 1655 1656 + /* 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 1666 + * 1667 + * Since the bluetooth chip has been reset, clear the memdump state. 1668 + */ 1669 + 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 + 1682 + clear_bit(QCA_SSR_TRIGGERED, &qca->flags); 1683 + clear_bit(QCA_IBS_DISABLED, &qca->flags); 1684 + 1685 + qca->tx_ibs_state = HCI_IBS_TX_AWAKE; 1686 + qca->memdump_state = QCA_MEMDUMP_IDLE; 1687 + } 1688 + 1656 1689 clear_bit(QCA_HW_ERROR_EVENT, &qca->flags); 1657 1690 } 1658 1691