Skip to content

Commit 2be43ab

Browse files
Venkata Lakshmi Narayana Gubbaholtmann
authored andcommitted
Bluetooth: hci_qca: Wait for timeout during suspend
Currently qca_suspend() is relied on IBS mechanism. During FW download and memory dump collections, IBS will be disabled. In those cases, driver will allow suspend and still uses the serdev port, which results to errors. Now added a wait timeout if suspend is triggered during FW download and memory collections. Signed-off-by: Venkata Lakshmi Narayana Gubba <[email protected]> Signed-off-by: Balakrishna Godavarthi <[email protected]> Reviewed-by: Abhishek Pandit-Subedi <[email protected]> Signed-off-by: Marcel Holtmann <[email protected]>
1 parent f5e8e21 commit 2be43ab

File tree

1 file changed

+39
-9
lines changed

1 file changed

+39
-9
lines changed

drivers/bluetooth/hci_qca.c

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@
5050
#define IBS_HOST_TX_IDLE_TIMEOUT_MS 2000
5151
#define CMD_TRANS_TIMEOUT_MS 100
5252
#define MEMDUMP_TIMEOUT_MS 8000
53+
#define IBS_DISABLE_SSR_TIMEOUT_MS (MEMDUMP_TIMEOUT_MS + 1000)
54+
#define FW_DOWNLOAD_TIMEOUT_MS 3000
5355

5456
/* susclk rate */
5557
#define SUSCLK_RATE_32KHZ 32768
@@ -68,12 +70,13 @@
6870
#define QCA_MEMDUMP_BYTE 0xFB
6971

7072
enum qca_flags {
71-
QCA_IBS_ENABLED,
73+
QCA_IBS_DISABLED,
7274
QCA_DROP_VENDOR_EVENT,
7375
QCA_SUSPENDING,
7476
QCA_MEMDUMP_COLLECTION,
7577
QCA_HW_ERROR_EVENT,
76-
QCA_SSR_TRIGGERED
78+
QCA_SSR_TRIGGERED,
79+
QCA_BT_OFF
7780
};
7881

7982
enum qca_capabilities {
@@ -870,7 +873,7 @@ static int qca_enqueue(struct hci_uart *hu, struct sk_buff *skb)
870873
* Out-Of-Band(GPIOs control) sleep is selected.
871874
* Don't wake the device up when suspending.
872875
*/
873-
if (!test_bit(QCA_IBS_ENABLED, &qca->flags) ||
876+
if (test_bit(QCA_IBS_DISABLED, &qca->flags) ||
874877
test_bit(QCA_SUSPENDING, &qca->flags)) {
875878
skb_queue_tail(&qca->txq, skb);
876879
spin_unlock_irqrestore(&qca->hci_ibs_lock, flags);
@@ -1015,7 +1018,7 @@ static void qca_controller_memdump(struct work_struct *work)
10151018
* the controller to send the dump is 8 seconds. let us
10161019
* start timer to handle this asynchronous activity.
10171020
*/
1018-
clear_bit(QCA_IBS_ENABLED, &qca->flags);
1021+
set_bit(QCA_IBS_DISABLED, &qca->flags);
10191022
set_bit(QCA_MEMDUMP_COLLECTION, &qca->flags);
10201023
dump = (void *) skb->data;
10211024
dump_size = __le32_to_cpu(dump->dump_size);
@@ -1619,6 +1622,7 @@ static int qca_power_on(struct hci_dev *hdev)
16191622
struct hci_uart *hu = hci_get_drvdata(hdev);
16201623
enum qca_btsoc_type soc_type = qca_soc_type(hu);
16211624
struct qca_serdev *qcadev;
1625+
struct qca_data *qca = hu->priv;
16221626
int ret = 0;
16231627

16241628
/* Non-serdev device usually is powered by external power
@@ -1638,6 +1642,7 @@ static int qca_power_on(struct hci_dev *hdev)
16381642
}
16391643
}
16401644

1645+
clear_bit(QCA_BT_OFF, &qca->flags);
16411646
return ret;
16421647
}
16431648

@@ -1657,7 +1662,7 @@ static int qca_setup(struct hci_uart *hu)
16571662
return ret;
16581663

16591664
/* Patch downloading has to be done without IBS mode */
1660-
clear_bit(QCA_IBS_ENABLED, &qca->flags);
1665+
set_bit(QCA_IBS_DISABLED, &qca->flags);
16611666

16621667
/* Enable controller to do both LE scan and BR/EDR inquiry
16631668
* simultaneously.
@@ -1708,7 +1713,7 @@ static int qca_setup(struct hci_uart *hu)
17081713
ret = qca_uart_setup(hdev, qca_baudrate, soc_type, soc_ver,
17091714
firmware_name);
17101715
if (!ret) {
1711-
set_bit(QCA_IBS_ENABLED, &qca->flags);
1716+
clear_bit(QCA_IBS_DISABLED, &qca->flags);
17121717
qca_debugfs_init(hdev);
17131718
hu->hdev->hw_error = qca_hw_error;
17141719
hu->hdev->cmd_timeout = qca_cmd_timeout;
@@ -1816,7 +1821,7 @@ static void qca_power_shutdown(struct hci_uart *hu)
18161821
* data in skb's.
18171822
*/
18181823
spin_lock_irqsave(&qca->hci_ibs_lock, flags);
1819-
clear_bit(QCA_IBS_ENABLED, &qca->flags);
1824+
set_bit(QCA_IBS_DISABLED, &qca->flags);
18201825
qca_flush(hu);
18211826
spin_unlock_irqrestore(&qca->hci_ibs_lock, flags);
18221827

@@ -1833,6 +1838,8 @@ static void qca_power_shutdown(struct hci_uart *hu)
18331838
} else if (qcadev->bt_en) {
18341839
gpiod_set_value_cansleep(qcadev->bt_en, 0);
18351840
}
1841+
1842+
set_bit(QCA_BT_OFF, &qca->flags);
18361843
}
18371844

18381845
static int qca_power_off(struct hci_dev *hdev)
@@ -2090,11 +2097,34 @@ static int __maybe_unused qca_suspend(struct device *dev)
20902097
bool tx_pending = false;
20912098
int ret = 0;
20922099
u8 cmd;
2100+
u32 wait_timeout = 0;
20932101

20942102
set_bit(QCA_SUSPENDING, &qca->flags);
20952103

2096-
/* Device is downloading patch or doesn't support in-band sleep. */
2097-
if (!test_bit(QCA_IBS_ENABLED, &qca->flags))
2104+
if (test_bit(QCA_BT_OFF, &qca->flags))
2105+
return 0;
2106+
2107+
if (test_bit(QCA_IBS_DISABLED, &qca->flags)) {
2108+
wait_timeout = test_bit(QCA_SSR_TRIGGERED, &qca->flags) ?
2109+
IBS_DISABLE_SSR_TIMEOUT_MS :
2110+
FW_DOWNLOAD_TIMEOUT_MS;
2111+
2112+
/* QCA_IBS_DISABLED flag is set to true, During FW download
2113+
* and during memory dump collection. It is reset to false,
2114+
* After FW download complete and after memory dump collections.
2115+
*/
2116+
wait_on_bit_timeout(&qca->flags, QCA_IBS_DISABLED,
2117+
TASK_UNINTERRUPTIBLE, msecs_to_jiffies(wait_timeout));
2118+
2119+
if (test_bit(QCA_IBS_DISABLED, &qca->flags)) {
2120+
bt_dev_err(hu->hdev, "SSR or FW download time out");
2121+
ret = -ETIMEDOUT;
2122+
goto error;
2123+
}
2124+
}
2125+
2126+
/* After memory dump collection, Controller is powered off.*/
2127+
if (test_bit(QCA_BT_OFF, &qca->flags))
20982128
return 0;
20992129

21002130
cancel_work_sync(&qca->ws_awake_device);

0 commit comments

Comments
 (0)