Commit 08a7e1df authored by Adrian Hunter's avatar Adrian Hunter Committed by Chris Ball

mmc: core: move ->request() call from atomic context

mmc_request_done() is sometimes called from interrupt or other atomic
context.  Mostly all mmc_request_done() does is complete(), however it
contains code to retry on error, which uses ->request().  As the error
path is certainly not performance critical, this may be moved to the
waiting function mmc_wait_for_req_done().

This allows ->request() to use runtime PM get_sync() and guarantee it
is never in an atomic context.
Signed-off-by: default avatarAdrian Hunter <adrian.hunter@intel.com>
Acked-by: default avatarUlf Hansson <ulf.hansson@stericsson.com>
Signed-off-by: default avatarChris Ball <cjb@laptop.org>
parent 88b47679
......@@ -141,12 +141,12 @@ void mmc_request_done(struct mmc_host *host, struct mmc_request *mrq)
}
if (err && cmd->retries) {
pr_debug("%s: req failed (CMD%u): %d, retrying...\n",
mmc_hostname(host), cmd->opcode, err);
cmd->retries--;
cmd->error = 0;
host->ops->request(host, mrq);
/*
* Request starter must handle retries - see
* mmc_wait_for_req_done().
*/
if (mrq->done)
mrq->done(mrq);
} else {
mmc_should_fail_request(host, mrq);
......@@ -253,7 +253,21 @@ static void __mmc_start_req(struct mmc_host *host, struct mmc_request *mrq)
static void mmc_wait_for_req_done(struct mmc_host *host,
struct mmc_request *mrq)
{
wait_for_completion(&mrq->completion);
struct mmc_command *cmd;
while (1) {
wait_for_completion(&mrq->completion);
cmd = mrq->cmd;
if (!cmd->error || !cmd->retries)
break;
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);
}
}
/**
......
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