Bluetooth: btusb: Consolidate code for waiting firmware to boot

This moves duplicated code for waiting firmware download completion to
a function that can be reused.

Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Tested-by: Tedd Ho-Jeong An <tedd.an@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
This commit is contained in:
Luiz Augusto von Dentz 2021-03-23 11:59:01 -07:00 committed by Marcel Holtmann
parent 21e31c6501
commit 604b3cf87f

View file

@ -2739,6 +2739,68 @@ static int btusb_intel_download_firmware(struct hci_dev *hdev,
return err;
}
static int btusb_boot_wait(struct hci_dev *hdev, ktime_t calltime, int msec)
{
struct btusb_data *data = hci_get_drvdata(hdev);
ktime_t delta, rettime;
unsigned long long duration;
int err;
bt_dev_info(hdev, "Waiting for device to boot");
err = wait_on_bit_timeout(&data->flags, BTUSB_BOOTING,
TASK_INTERRUPTIBLE,
msecs_to_jiffies(msec));
if (err == -EINTR) {
bt_dev_err(hdev, "Device boot interrupted");
return -EINTR;
}
if (err) {
bt_dev_err(hdev, "Device boot timeout");
return -ETIMEDOUT;
}
rettime = ktime_get();
delta = ktime_sub(rettime, calltime);
duration = (unsigned long long) ktime_to_ns(delta) >> 10;
bt_dev_info(hdev, "Device booted in %llu usecs", duration);
return 0;
}
static int btusb_intel_boot(struct hci_dev *hdev, u32 boot_addr)
{
struct btusb_data *data = hci_get_drvdata(hdev);
ktime_t calltime;
int err;
calltime = ktime_get();
set_bit(BTUSB_BOOTING, &data->flags);
err = btintel_send_intel_reset(hdev, boot_addr);
if (err) {
bt_dev_err(hdev, "Intel Soft Reset failed (%d)", err);
btintel_reset_to_bootloader(hdev);
return err;
}
/* The bootloader will not indicate when the device is ready. This
* is done by the operational firmware sending bootup notification.
*
* Booting into operational firmware should not take longer than
* 1 second. However if that happens, then just fail the setup
* since something went wrong.
*/
err = btusb_boot_wait(hdev, calltime, 1000);
if (err == -ETIMEDOUT)
btintel_reset_to_bootloader(hdev);
return err;
}
static int btusb_setup_intel_new(struct hci_dev *hdev)
{
struct btusb_data *data = hci_get_drvdata(hdev);
@ -2746,8 +2808,6 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)
struct intel_boot_params params;
u32 boot_param;
char ddcname[64];
ktime_t calltime, delta, rettime;
unsigned long long duration;
int err;
struct intel_debug_features features;
@ -2782,46 +2842,9 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)
if (ver.fw_variant == 0x23)
goto finish;
calltime = ktime_get();
set_bit(BTUSB_BOOTING, &data->flags);
err = btintel_send_intel_reset(hdev, boot_param);
if (err) {
bt_dev_err(hdev, "Intel Soft Reset failed (%d)", err);
btintel_reset_to_bootloader(hdev);
err = btusb_intel_boot(hdev, boot_param);
if (err)
return err;
}
/* The bootloader will not indicate when the device is ready. This
* is done by the operational firmware sending bootup notification.
*
* Booting into operational firmware should not take longer than
* 1 second. However if that happens, then just fail the setup
* since something went wrong.
*/
bt_dev_info(hdev, "Waiting for device to boot");
err = wait_on_bit_timeout(&data->flags, BTUSB_BOOTING,
TASK_INTERRUPTIBLE,
msecs_to_jiffies(1000));
if (err == -EINTR) {
bt_dev_err(hdev, "Device boot interrupted");
return -EINTR;
}
if (err) {
bt_dev_err(hdev, "Device boot timeout");
btintel_reset_to_bootloader(hdev);
return -ETIMEDOUT;
}
rettime = ktime_get();
delta = ktime_sub(rettime, calltime);
duration = (unsigned long long) ktime_to_ns(delta) >> 10;
bt_dev_info(hdev, "Device booted in %llu usecs", duration);
clear_bit(BTUSB_BOOTLOADER, &data->flags);
@ -2885,8 +2908,6 @@ static int btusb_setup_intel_newgen(struct hci_dev *hdev)
struct btusb_data *data = hci_get_drvdata(hdev);
u32 boot_param;
char ddcname[64];
ktime_t calltime, delta, rettime;
unsigned long long duration;
int err;
struct intel_debug_features features;
struct intel_version_tlv version;
@ -2922,46 +2943,9 @@ static int btusb_setup_intel_newgen(struct hci_dev *hdev)
if (version.img_type == 0x03)
goto finish;
calltime = ktime_get();
set_bit(BTUSB_BOOTING, &data->flags);
err = btintel_send_intel_reset(hdev, boot_param);
if (err) {
bt_dev_err(hdev, "Intel Soft Reset failed (%d)", err);
btintel_reset_to_bootloader(hdev);
err = btusb_intel_boot(hdev, boot_param);
if (err)
return err;
}
/* The bootloader will not indicate when the device is ready. This
* is done by the operational firmware sending bootup notification.
*
* Booting into operational firmware should not take longer than
* 1 second. However if that happens, then just fail the setup
* since something went wrong.
*/
bt_dev_info(hdev, "Waiting for device to boot");
err = wait_on_bit_timeout(&data->flags, BTUSB_BOOTING,
TASK_INTERRUPTIBLE,
msecs_to_jiffies(1000));
if (err == -EINTR) {
bt_dev_err(hdev, "Device boot interrupted");
return -EINTR;
}
if (err) {
bt_dev_err(hdev, "Device boot timeout");
btintel_reset_to_bootloader(hdev);
return -ETIMEDOUT;
}
rettime = ktime_get();
delta = ktime_sub(rettime, calltime);
duration = (unsigned long long)ktime_to_ns(delta) >> 10;
bt_dev_info(hdev, "Device booted in %llu usecs", duration);
clear_bit(BTUSB_BOOTLOADER, &data->flags);