diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 007c44443332..ec3453fd39aa 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -186,12 +186,29 @@ void mmc_request_done(struct mmc_host *host, struct mmc_request *mrq) EXPORT_SYMBOL(mmc_request_done); +static void __mmc_start_request(struct mmc_host *host, struct mmc_request *mrq) +{ + int err; + + /* Assumes host controller has been runtime resumed by mmc_claim_host */ + err = mmc_retune(host); + if (err) { + mrq->cmd->error = err; + mmc_request_done(host, mrq); + return; + } + + host->ops->request(host, mrq); +} + static int mmc_start_request(struct mmc_host *host, struct mmc_request *mrq) { #ifdef CONFIG_MMC_DEBUG unsigned int i, sz; struct scatterlist *sg; #endif + mmc_retune_hold(host); + if (mmc_card_removed(host->card)) return -ENOMEDIUM; @@ -252,7 +269,7 @@ static int mmc_start_request(struct mmc_host *host, struct mmc_request *mrq) } mmc_host_clk_hold(host); led_trigger_event(host->led, LED_FULL); - host->ops->request(host, mrq); + __mmc_start_request(host, mrq); return 0; } @@ -417,22 +434,22 @@ static int mmc_wait_for_data_req_done(struct mmc_host *host, host->areq); break; /* return err */ } else { + mmc_retune_recheck(host); pr_info("%s: req failed (CMD%u): %d, retrying...\n", mmc_hostname(host), cmd->opcode, cmd->error); cmd->retries--; cmd->error = 0; - host->ops->request(host, mrq); + __mmc_start_request(host, mrq); continue; /* wait for done/new event again */ } } else if (context_info->is_new_req) { context_info->is_new_req = false; - if (!next_req) { - err = MMC_BLK_NEW_REQUEST; - break; /* return err */ - } + if (!next_req) + return MMC_BLK_NEW_REQUEST; } } + mmc_retune_release(host); return err; } @@ -467,12 +484,16 @@ static void mmc_wait_for_req_done(struct mmc_host *host, mmc_card_removed(host->card)) break; + mmc_retune_recheck(host); + pr_debug("%s: req failed (CMD%u): %d, retrying...\n", mmc_hostname(host), cmd->opcode, cmd->error); cmd->retries--; cmd->error = 0; - host->ops->request(host, mrq); + __mmc_start_request(host, mrq); } + + mmc_retune_release(host); } /**