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@xxxxxxxxxxxxxxxxxxx> --- drivers/bluetooth/btmrvl_sdio.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c index 9959d4c..6b6abb2 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, /* Wait for firmware to become ready */ 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; if (firmwarestat == FIRMWARE_READY) { @@ -882,19 +885,20 @@ static int btmrvl_sdio_download_fw(struct btmrvl_sdio_card *card) BT_ERR("card or function is NULL!"); return -EINVAL; } - sdio_claim_host(card->func); if (!btmrvl_sdio_verify_fw_download(card, 1)) { BT_DBG("Firmware already downloaded!"); - goto done; + return 0; } + sdio_claim_host(card->func); + /* Check if other function driver is downloading the firmware */ fws0 = sdio_readb(card->func, card->reg->card_fw_status0, &ret); if (ret) { BT_ERR("Failed to read FW downloading status!"); ret = -EIO; - goto done; + goto release_host; } if (fws0) { BT_DBG("BT not the winner (%#x). Skip FW downloading", fws0); @@ -907,26 +911,28 @@ static int btmrvl_sdio_download_fw(struct btmrvl_sdio_card *card) if (ret) { BT_ERR("Failed to download helper!"); ret = -EIO; - goto done; + goto release_host; } } if (btmrvl_sdio_download_fw_w_helper(card)) { BT_ERR("Failed to download firmware!"); ret = -EIO; - goto done; + goto release_host; } } + sdio_release_host(card->func); + if (btmrvl_sdio_verify_fw_download(card, pollnum)) { BT_ERR("FW failed to be active in time!"); - ret = -ETIMEDOUT; - goto done; + return -ETIMEDOUT; } -done: - sdio_release_host(card->func); + return 0; +release_host: + sdio_release_host(card->func); return ret; } -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html