Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PW_SID:360339] [v1] Bluetooth: hci_qca: Wait for timeout during suspend #6

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions .github/workflows/schedule_work.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Scheduled Work

on:
schedule:
- cron: "15,45 * * * *"

jobs:
sync_repo:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Sync Repo
uses: tedd-an/action-manage-repo@master
with:
src_repo: "bluez/bluetooth-next"
for_upstream_branch: 'for-upstream'
workflow_branch: 'workflow'
github_token: ${{ secrets.GITHUB_TOKEN }}

sync_patchwork:
needs: sync_repo
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Sync Patchwork
uses: tedd-an/action-patchwork-to-pr@master
with:
pw_exclude_str: 'BlueZ'
base_branch: 'workflow'
github_token: ${{ secrets.GITHUB_TOKEN }}
48 changes: 39 additions & 9 deletions drivers/bluetooth/hci_qca.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@
#define IBS_HOST_TX_IDLE_TIMEOUT_MS 2000
#define CMD_TRANS_TIMEOUT_MS 100
#define MEMDUMP_TIMEOUT_MS 8000
#define IBS_DISABLE_SSR_TIMEOUT_MS (MEMDUMP_TIMEOUT_MS + 1000)
#define FW_DOWNLOAD_TIMEOUT_MS 3000

/* susclk rate */
#define SUSCLK_RATE_32KHZ 32768
Expand All @@ -68,12 +70,13 @@
#define QCA_MEMDUMP_BYTE 0xFB

enum qca_flags {
QCA_IBS_ENABLED,
QCA_IBS_DISABLED,
QCA_DROP_VENDOR_EVENT,
QCA_SUSPENDING,
QCA_MEMDUMP_COLLECTION,
QCA_HW_ERROR_EVENT,
QCA_SSR_TRIGGERED
QCA_SSR_TRIGGERED,
QCA_BT_OFF
};

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

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

clear_bit(QCA_BT_OFF, &qca->flags);
return ret;
}

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

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

/* Enable controller to do both LE scan and BR/EDR inquiry
* simultaneously.
Expand Down Expand Up @@ -1708,7 +1713,7 @@ static int qca_setup(struct hci_uart *hu)
ret = qca_uart_setup(hdev, qca_baudrate, soc_type, soc_ver,
firmware_name);
if (!ret) {
set_bit(QCA_IBS_ENABLED, &qca->flags);
clear_bit(QCA_IBS_DISABLED, &qca->flags);
qca_debugfs_init(hdev);
hu->hdev->hw_error = qca_hw_error;
hu->hdev->cmd_timeout = qca_cmd_timeout;
Expand Down Expand Up @@ -1814,7 +1819,7 @@ static void qca_power_shutdown(struct hci_uart *hu)
* data in skb's.
*/
spin_lock_irqsave(&qca->hci_ibs_lock, flags);
clear_bit(QCA_IBS_ENABLED, &qca->flags);
set_bit(QCA_IBS_DISABLED, &qca->flags);
qca_flush(hu);
spin_unlock_irqrestore(&qca->hci_ibs_lock, flags);

Expand All @@ -1831,6 +1836,8 @@ static void qca_power_shutdown(struct hci_uart *hu)
} else if (qcadev->bt_en) {
gpiod_set_value_cansleep(qcadev->bt_en, 0);
}

set_bit(QCA_BT_OFF, &qca->flags);
}

static int qca_power_off(struct hci_dev *hdev)
Expand Down Expand Up @@ -2088,11 +2095,34 @@ static int __maybe_unused qca_suspend(struct device *dev)
bool tx_pending = false;
int ret = 0;
u8 cmd;
u32 wait_timeout = 0;

set_bit(QCA_SUSPENDING, &qca->flags);

/* Device is downloading patch or doesn't support in-band sleep. */
if (!test_bit(QCA_IBS_ENABLED, &qca->flags))
if (test_bit(QCA_BT_OFF, &qca->flags))
return 0;

if (test_bit(QCA_IBS_DISABLED, &qca->flags)) {
wait_timeout = test_bit(QCA_SSR_TRIGGERED, &qca->flags) ?
IBS_DISABLE_SSR_TIMEOUT_MS :
FW_DOWNLOAD_TIMEOUT_MS;

/* QCA_IBS_DISABLED flag is set to true, During FW download
* and during memory dump collection. It is reset to false,
* After FW download complete and after memory dump collections.
*/
wait_on_bit_timeout(&qca->flags, QCA_IBS_DISABLED,
TASK_UNINTERRUPTIBLE, msecs_to_jiffies(wait_timeout));

if (test_bit(QCA_IBS_DISABLED, &qca->flags)) {
bt_dev_err(hu->hdev, "SSR or FW download time out");
ret = -ETIMEDOUT;
goto error;
}
}

/* After memory dump collection, Controller is powered off.*/
if (test_bit(QCA_BT_OFF, &qca->flags))
return 0;

cancel_work_sync(&qca->ws_awake_device);
Expand Down