From: Hans de Goede Date: Thu, 12 Feb 2026 14:17:21 +0000 (+0100) Subject: Bluetooth: hci_qca: Fix BT not getting powered-off on rmmod X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9ff5ff0b9175c37f1fc2ad4e94fa23c7bbc9504f;p=thirdparty%2Fkernel%2Flinux.git Bluetooth: hci_qca: Fix BT not getting powered-off on rmmod The BT core skips calling the hci_dev's shutdown method when the HCI is unregistered. This means that qca_power_off() was not getting called leaving BT powered on. This causes regulators / pwrseq providers to not get disabled which also causes problem when re-loading the module because regulators and pwrseq providers have an enablecount which now has never dropped to 0, causing the BT to not get properly reset between rmmod and re-load which causes initialization failure on the re-load. Fix this by calling qca_power_off() from qca_close() when BT has not already been powered off through a qca_hci_shutdown() call. hci_ldisc.c will call qca_close() after freeing the hdev, so this means that qca_power_off() can now no longer deref hu->hdev, change the logging in qca_power_off() to no longer use hu->hdev. Signed-off-by: Hans de Goede Reviewed-by: Bartosz Golaszewski Signed-off-by: Luiz Augusto von Dentz --- diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c index e66d1736acf6..d6e78201a675 100644 --- a/drivers/bluetooth/hci_qca.c +++ b/drivers/bluetooth/hci_qca.c @@ -722,6 +722,10 @@ static int qca_close(struct hci_uart *hu) BT_DBG("hu %p qca close", hu); + /* BT core skips qca_hci_shutdown() which calls qca_power_off() on rmmod */ + if (!test_bit(QCA_BT_OFF, &qca->flags)) + qca_power_off(hu); + serial_clock_vote(HCI_IBS_VOTE_STATS_UPDATE, hu); skb_queue_purge(&qca->tx_wait_q); @@ -2260,7 +2264,7 @@ static void qca_power_off(struct hci_uart *hu) qca_regulator_disable(qcadev); if (qcadev->sw_ctrl) { sw_ctrl_state = gpiod_get_value_cansleep(qcadev->sw_ctrl); - bt_dev_dbg(hu->hdev, "SW_CTRL is %d", sw_ctrl_state); + BT_DBG("SW_CTRL is %d", sw_ctrl_state); } break;