From: Chris Lu Date: Tue, 3 Feb 2026 06:25:10 +0000 (+0800) Subject: Bluetooth: btmtk: Add reset mechanism if downloading firmware failed X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=679621a767bfa0a2cb77fbd8b664412e9e3f89cf;p=thirdparty%2Fkernel%2Flinux.git Bluetooth: btmtk: Add reset mechanism if downloading firmware failed Add a new flag 'BTMTK_FIRMWARE_DL_RETRY'. If an error occurs during mt79xx firmware download process, this flag will be set and cleared after a reset. If the flag is already set and firmware still cannot be loaded successfully after a reset, no further reset attempts will be made. In other words, if there is a problem during firmware download, only one reset will be attempted. Signed-off-by: Chris Lu Signed-off-by: Luiz Augusto von Dentz --- diff --git a/drivers/bluetooth/btmtk.c b/drivers/bluetooth/btmtk.c index 5c62b802a1994..e4cee251852ed 100644 --- a/drivers/bluetooth/btmtk.c +++ b/drivers/bluetooth/btmtk.c @@ -1344,6 +1344,9 @@ int btmtk_usb_setup(struct hci_dev *hdev) err = btmtk_setup_firmware_79xx(hdev, fw_bin_name, btmtk_usb_hci_wmt_sync); if (err < 0) { + /* retry once if setup firmware error */ + if (!test_and_set_bit(BTMTK_FIRMWARE_DL_RETRY, &btmtk_data->flags)) + btmtk_reset_sync(hdev); bt_dev_err(hdev, "Failed to set up firmware (%d)", err); return err; } @@ -1371,6 +1374,9 @@ int btmtk_usb_setup(struct hci_dev *hdev) hci_set_msft_opcode(hdev, 0xFD30); hci_set_aosp_capable(hdev); + /* Clear BTMTK_FIRMWARE_DL_RETRY if setup successfully */ + test_and_clear_bit(BTMTK_FIRMWARE_DL_RETRY, &btmtk_data->flags); + /* Set up ISO interface after protocol enabled */ if (test_bit(BTMTK_ISOPKT_OVER_INTR, &btmtk_data->flags)) { if (!btmtk_usb_isointf_init(hdev)) diff --git a/drivers/bluetooth/btmtk.h b/drivers/bluetooth/btmtk.h index 5df7c32966247..b9df2b8f06273 100644 --- a/drivers/bluetooth/btmtk.h +++ b/drivers/bluetooth/btmtk.h @@ -147,6 +147,7 @@ enum { BTMTK_HW_RESET_ACTIVE, BTMTK_ISOPKT_OVER_INTR, BTMTK_ISOPKT_RUNNING, + BTMTK_FIRMWARE_DL_RETRY, }; typedef int (*btmtk_reset_sync_func_t)(struct hci_dev *, void *);