public inbox for linux-bluetooth@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Bluetooth: btnxpuart: Fix baudrate reset on remove
@ 2025-02-26 15:13 Loic Poulain
  2025-02-26 15:33 ` bluez.test.bot
  0 siblings, 1 reply; 2+ messages in thread
From: Loic Poulain @ 2025-02-26 15:13 UTC (permalink / raw)
  To: neeraj.sanjaykale, marcel; +Cc: amitkumar.karwar, linux-bluetooth, Loic Poulain

Trying to reset the baudrate from device remove callback does not
work if HCI dev is down and not running, causing the next device
probing to fail, as host/controller baudrates are then out-of-sync.

To prevent this issue, we ensure the controller's baudrate is always
reset to its initial value in the shutdown callback, during the hdev
close procedure. That guarantees subsequent open procedure to succeed,
regardless of any device removal/binding in between. This also means
we want to reconfigure the baudrate in the next hdev open procedure
via the setup() callback (HCI_QUIRK_NON_PERSISTENT_SETUP required).

In case of removal when the hdev is up and running, we have to call
the shutdown procedure explicitly before unregistering the hdev.

Signed-off-by: Loic Poulain <loic.poulain@linaro.org>
---
 drivers/bluetooth/btnxpuart.c | 20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/drivers/bluetooth/btnxpuart.c b/drivers/bluetooth/btnxpuart.c
index fc313559c2aa..b1344a9a8925 100644
--- a/drivers/bluetooth/btnxpuart.c
+++ b/drivers/bluetooth/btnxpuart.c
@@ -1274,6 +1274,9 @@ static int nxp_shutdown(struct hci_dev *hdev)
 			set_bit(BTNXPUART_FW_DOWNLOADING, &nxpdev->tx_state);
 		}
 		kfree_skb(skb);
+	} else if (nxpdev->current_baudrate != nxpdev->fw_init_baudrate) {
+		nxpdev->new_baudrate = nxpdev->fw_init_baudrate;
+		nxp_set_baudrate_cmd(hdev, NULL);
 	}
 
 	return 0;
@@ -1578,6 +1581,8 @@ static int nxp_serdev_probe(struct serdev_device *serdev)
 	hdev->wakeup = nxp_wakeup;
 	SET_HCIDEV_DEV(hdev, &serdev->dev);
 
+	set_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks);
+
 	if (hci_register_dev(hdev) < 0) {
 		dev_err(&serdev->dev, "Can't register HCI device\n");
 		goto probe_fail;
@@ -1603,16 +1608,15 @@ static void nxp_serdev_remove(struct serdev_device *serdev)
 		clear_bit(BTNXPUART_FW_DOWNLOADING, &nxpdev->tx_state);
 		wake_up_interruptible(&nxpdev->check_boot_sign_wait_q);
 		wake_up_interruptible(&nxpdev->fw_dnld_done_wait_q);
-	} else {
-		/* Restore FW baudrate to fw_init_baudrate if changed.
-		 * This will ensure FW baudrate is in sync with
-		 * driver baudrate in case this driver is re-inserted.
+	}
+
+	if (test_bit(HCI_RUNNING, &hdev->flags)) {
+		/* Ensure shutdown callback is executed before unregistering, so
+		 * that baudrate is reset to initial value.
 		 */
-		if (nxpdev->current_baudrate != nxpdev->fw_init_baudrate) {
-			nxpdev->new_baudrate = nxpdev->fw_init_baudrate;
-			nxp_set_baudrate_cmd(hdev, NULL);
-		}
+		nxp_shutdown(hdev);
 	}
+
 	ps_cleanup(nxpdev);
 	hci_unregister_dev(hdev);
 	hci_free_dev(hdev);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2025-02-26 15:33 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-02-26 15:13 [PATCH] Bluetooth: btnxpuart: Fix baudrate reset on remove Loic Poulain
2025-02-26 15:33 ` bluez.test.bot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox