Commit 604b3cf8 authored by Luiz Augusto von Dentz's avatar Luiz Augusto von Dentz Committed by Marcel Holtmann
Browse files

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: default avatarLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Tested-by: default avatarTedd Ho-Jeong An <tedd.an@intel.com>
Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
parent 21e31c65
Loading
Loading
Loading
Loading
+66 −82
Original line number Diff line number Diff line
@@ -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);