@@ -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);
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(-)