aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/bluetooth
diff options
context:
space:
mode:
authorAndreas Fenkart <andreas.fenkart@streamunlimited.com>2013-04-22 05:10:22 -0400
committerGustavo Padovan <gustavo.padovan@collabora.co.uk>2013-04-23 19:55:51 -0400
commitc1c999e27ce5681c5b43c7f82947030e7134f1d0 (patch)
treee8820bcc9b74a65a1f6f7a4f4b56f84b0850b567 /drivers/bluetooth
parent9da226c7919aaed40e0195f0b7c7713ed00e380f (diff)
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: Andreas Fenkart <andreas.fenkart@streamunlimited.com> Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
Diffstat (limited to 'drivers/bluetooth')
-rw-r--r--drivers/bluetooth/btmrvl_sdio.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c
index 0e9e8e95916d..758d5ac81ecc 100644
--- a/drivers/bluetooth/btmrvl_sdio.c
+++ b/drivers/bluetooth/btmrvl_sdio.c
@@ -234,7 +234,10 @@ static int btmrvl_sdio_verify_fw_download(struct btmrvl_sdio_card *card,
234 234
235 /* Wait for firmware to become ready */ 235 /* Wait for firmware to become ready */
236 for (tries = 0; tries < pollnum; tries++) { 236 for (tries = 0; tries < pollnum; tries++) {
237 if (btmrvl_sdio_read_fw_status(card, &firmwarestat) < 0) 237 sdio_claim_host(card->func);
238 ret = btmrvl_sdio_read_fw_status(card, &firmwarestat);
239 sdio_release_host(card->func);
240 if (ret < 0)
238 continue; 241 continue;
239 242
240 if (firmwarestat == FIRMWARE_READY) { 243 if (firmwarestat == FIRMWARE_READY) {
@@ -882,13 +885,14 @@ static int btmrvl_sdio_download_fw(struct btmrvl_sdio_card *card)
882 BT_ERR("card or function is NULL!"); 885 BT_ERR("card or function is NULL!");
883 return -EINVAL; 886 return -EINVAL;
884 } 887 }
885 sdio_claim_host(card->func);
886 888
887 if (!btmrvl_sdio_verify_fw_download(card, 1)) { 889 if (!btmrvl_sdio_verify_fw_download(card, 1)) {
888 BT_DBG("Firmware already downloaded!"); 890 BT_DBG("Firmware already downloaded!");
889 goto done; 891 return 0;
890 } 892 }
891 893
894 sdio_claim_host(card->func);
895
892 /* Check if other function driver is downloading the firmware */ 896 /* Check if other function driver is downloading the firmware */
893 fws0 = sdio_readb(card->func, card->reg->card_fw_status0, &ret); 897 fws0 = sdio_readb(card->func, card->reg->card_fw_status0, &ret);
894 if (ret) { 898 if (ret) {
@@ -918,15 +922,17 @@ static int btmrvl_sdio_download_fw(struct btmrvl_sdio_card *card)
918 } 922 }
919 } 923 }
920 924
925 sdio_release_host(card->func);
926
921 if (btmrvl_sdio_verify_fw_download(card, pollnum)) { 927 if (btmrvl_sdio_verify_fw_download(card, pollnum)) {
922 BT_ERR("FW failed to be active in time!"); 928 BT_ERR("FW failed to be active in time!");
923 ret = -ETIMEDOUT; 929 return -ETIMEDOUT;
924 goto done;
925 } 930 }
926 931
932 return 0;
933
927done: 934done:
928 sdio_release_host(card->func); 935 sdio_release_host(card->func);
929
930 return ret; 936 return ret;
931} 937}
932 938