diff options
author | Andreas Fenkart <andreas.fenkart@streamunlimited.com> | 2013-04-22 05:10:22 -0400 |
---|---|---|
committer | Gustavo Padovan <gustavo.padovan@collabora.co.uk> | 2013-04-23 19:55:51 -0400 |
commit | c1c999e27ce5681c5b43c7f82947030e7134f1d0 (patch) | |
tree | e8820bcc9b74a65a1f6f7a4f4b56f84b0850b567 /drivers/bluetooth | |
parent | 9da226c7919aaed40e0195f0b7c7713ed00e380f (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.c | 18 |
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 | |||
927 | done: | 934 | done: |
928 | sdio_release_host(card->func); | 935 | sdio_release_host(card->func); |
929 | |||
930 | return ret; | 936 | return ret; |
931 | } | 937 | } |
932 | 938 | ||