Commit c1c999e2 authored by Andreas Fenkart's avatar Andreas Fenkart Committed by Gustavo Padovan

Bluetooth: btmrvl: release lock while waiting for fw download complete

If not winner, driver must release the sdio host lock, so the fw
download can progress. While holding the lock fw download is stalled
and the following error is produced:

[  235.746015] Bluetooth: FW failed to be active in time!
[  235.752799] Bluetooth: Downloading firmware failed!
Signed-off-by: default avatarAndreas Fenkart <andreas.fenkart@streamunlimited.com>
Signed-off-by: default avatarGustavo Padovan <gustavo.padovan@collabora.co.uk>
parent 9da226c7
...@@ -234,7 +234,10 @@ static int btmrvl_sdio_verify_fw_download(struct btmrvl_sdio_card *card, ...@@ -234,7 +234,10 @@ static int btmrvl_sdio_verify_fw_download(struct btmrvl_sdio_card *card,
/* Wait for firmware to become ready */ /* Wait for firmware to become ready */
for (tries = 0; tries < pollnum; tries++) { for (tries = 0; tries < pollnum; tries++) {
if (btmrvl_sdio_read_fw_status(card, &firmwarestat) < 0) sdio_claim_host(card->func);
ret = btmrvl_sdio_read_fw_status(card, &firmwarestat);
sdio_release_host(card->func);
if (ret < 0)
continue; continue;
if (firmwarestat == FIRMWARE_READY) { if (firmwarestat == FIRMWARE_READY) {
...@@ -882,13 +885,14 @@ static int btmrvl_sdio_download_fw(struct btmrvl_sdio_card *card) ...@@ -882,13 +885,14 @@ static int btmrvl_sdio_download_fw(struct btmrvl_sdio_card *card)
BT_ERR("card or function is NULL!"); BT_ERR("card or function is NULL!");
return -EINVAL; return -EINVAL;
} }
sdio_claim_host(card->func);
if (!btmrvl_sdio_verify_fw_download(card, 1)) { if (!btmrvl_sdio_verify_fw_download(card, 1)) {
BT_DBG("Firmware already downloaded!"); BT_DBG("Firmware already downloaded!");
goto done; return 0;
} }
sdio_claim_host(card->func);
/* Check if other function driver is downloading the firmware */ /* Check if other function driver is downloading the firmware */
fws0 = sdio_readb(card->func, card->reg->card_fw_status0, &ret); fws0 = sdio_readb(card->func, card->reg->card_fw_status0, &ret);
if (ret) { if (ret) {
...@@ -918,15 +922,17 @@ static int btmrvl_sdio_download_fw(struct btmrvl_sdio_card *card) ...@@ -918,15 +922,17 @@ static int btmrvl_sdio_download_fw(struct btmrvl_sdio_card *card)
} }
} }
sdio_release_host(card->func);
if (btmrvl_sdio_verify_fw_download(card, pollnum)) { if (btmrvl_sdio_verify_fw_download(card, pollnum)) {
BT_ERR("FW failed to be active in time!"); BT_ERR("FW failed to be active in time!");
ret = -ETIMEDOUT; return -ETIMEDOUT;
goto done;
} }
return 0;
done: done:
sdio_release_host(card->func); sdio_release_host(card->func);
return ret; return ret;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment