summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeeraj Sanjay Kale <neeraj.sanjaykale@nxp.com>2023-04-19 20:54:13 +0530
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>2023-04-23 22:07:11 -0700
commitb0310d6ed684b862dd29049d7b9cca5589555654 (patch)
tree1b419c151c7eab6e2b29ba42d0c9b1eeb500c3c9
parentf419863588217f76eaf754e1dfce21ea7fcb026d (diff)
downloadlinux-stable-b0310d6ed684b862dd29049d7b9cca5589555654.tar.gz
linux-stable-b0310d6ed684b862dd29049d7b9cca5589555654.tar.bz2
linux-stable-b0310d6ed684b862dd29049d7b9cca5589555654.zip
Bluetooth: btnxpuart: Enable flow control before checking boot signature
This enables flow control before checking for bootloader signature and deciding whether FW download is needed or not. In case of V1 bootloader chips w8987 and w8997, it is observed that if WLAN FW is downloaded first and power save is enabled in wlan core, bootloader signatures are not emitted by the BT core when the chip is put to sleep. As a result, the driver skips FW download and subsequent HCI commands get timeout errors in dmesg as shown below: [ 112.898867] Bluetooth: hci0: Opcode 0x c03 failed: -110 [ 114.914865] Bluetooth: hci0: Setting baudrate failed (-110) [ 116.930856] Bluetooth: hci0: Setting wake-up method failed (-110) By enabling the flow control, the host enables its RTS pin, and an interrupt in chip's UART peripheral causes the bootloader to wake up, enabling the bootloader signatures, which then helps in downloading the bluetooth FW file. This changes all instances of 0/1 for serdev_device_set_flow_control() to false/true. Signed-off-by: Neeraj Sanjay Kale <neeraj.sanjaykale@nxp.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
-rw-r--r--drivers/bluetooth/btnxpuart.c13
1 files changed, 6 insertions, 7 deletions
diff --git a/drivers/bluetooth/btnxpuart.c b/drivers/bluetooth/btnxpuart.c
index 31046f26e712..3a34d7c1475b 100644
--- a/drivers/bluetooth/btnxpuart.c
+++ b/drivers/bluetooth/btnxpuart.c
@@ -535,7 +535,7 @@ static int nxp_download_firmware(struct hci_dev *hdev)
nxpdev->helper_downloaded = false;
serdev_device_set_baudrate(nxpdev->serdev, HCI_NXP_PRI_BAUDRATE);
- serdev_device_set_flow_control(nxpdev->serdev, 0);
+ serdev_device_set_flow_control(nxpdev->serdev, false);
nxpdev->current_baudrate = HCI_NXP_PRI_BAUDRATE;
/* Wait till FW is downloaded and CTS becomes low */
@@ -548,7 +548,7 @@ static int nxp_download_firmware(struct hci_dev *hdev)
return -ETIMEDOUT;
}
- serdev_device_set_flow_control(nxpdev->serdev, 1);
+ serdev_device_set_flow_control(nxpdev->serdev, true);
err = serdev_device_wait_for_cts(nxpdev->serdev, 1, 60000);
if (err < 0) {
bt_dev_err(hdev, "CTS is still high. FW Download failed.");
@@ -740,7 +740,7 @@ static int nxp_recv_fw_req_v1(struct hci_dev *hdev, struct sk_buff *skb)
if (nxpdev->baudrate_changed) {
serdev_device_set_baudrate(nxpdev->serdev,
HCI_NXP_SEC_BAUDRATE);
- serdev_device_set_flow_control(nxpdev->serdev, 1);
+ serdev_device_set_flow_control(nxpdev->serdev, true);
nxpdev->current_baudrate = HCI_NXP_SEC_BAUDRATE;
}
goto free_skb;
@@ -763,7 +763,7 @@ static int nxp_recv_fw_req_v1(struct hci_dev *hdev, struct sk_buff *skb)
serdev_device_wait_until_sent(nxpdev->serdev, 0);
serdev_device_set_baudrate(nxpdev->serdev,
HCI_NXP_SEC_BAUDRATE);
- serdev_device_set_flow_control(nxpdev->serdev, 1);
+ serdev_device_set_flow_control(nxpdev->serdev, true);
} else {
clear_bit(BTNXPUART_FW_DOWNLOADING, &nxpdev->tx_state);
wake_up_interruptible(&nxpdev->fw_dnld_done_wait_q);
@@ -880,7 +880,7 @@ static int nxp_recv_fw_req_v3(struct hci_dev *hdev, struct sk_buff *skb)
if (nxpdev->baudrate_changed) {
serdev_device_set_baudrate(nxpdev->serdev,
HCI_NXP_SEC_BAUDRATE);
- serdev_device_set_flow_control(nxpdev->serdev, 1);
+ serdev_device_set_flow_control(nxpdev->serdev, true);
nxpdev->current_baudrate = HCI_NXP_SEC_BAUDRATE;
}
goto free_skb;
@@ -984,7 +984,7 @@ free_skb:
static int nxp_check_boot_sign(struct btnxpuart_dev *nxpdev)
{
serdev_device_set_baudrate(nxpdev->serdev, HCI_NXP_PRI_BAUDRATE);
- serdev_device_set_flow_control(nxpdev->serdev, 0);
+ serdev_device_set_flow_control(nxpdev->serdev, true);
set_bit(BTNXPUART_CHECK_BOOT_SIGNATURE, &nxpdev->tx_state);
return wait_event_interruptible_timeout(nxpdev->check_boot_sign_wait_q,
@@ -1012,7 +1012,6 @@ static int nxp_setup(struct hci_dev *hdev)
clear_bit(BTNXPUART_FW_DOWNLOADING, &nxpdev->tx_state);
}
- serdev_device_set_flow_control(nxpdev->serdev, 1);
device_property_read_u32(&nxpdev->serdev->dev, "fw-init-baudrate",
&nxpdev->fw_init_baudrate);
if (!nxpdev->fw_init_baudrate)