Skip to content

Commit 08a7e1d

Browse files
ahunter6cjb
authored andcommitted
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: Adrian Hunter <adrian.hunter@intel.com> Acked-by: Ulf Hansson <ulf.hansson@stericsson.com> Signed-off-by: Chris Ball <cjb@laptop.org>
1 parent 88b4767 commit 08a7e1d

File tree

1 file changed

+21
-7
lines changed

1 file changed

+21
-7
lines changed

drivers/mmc/core/core.c

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -141,12 +141,12 @@ void mmc_request_done(struct mmc_host *host, struct mmc_request *mrq)
141141
}
142142

143143
if (err && cmd->retries) {
144-
pr_debug("%s: req failed (CMD%u): %d, retrying...\n",
145-
mmc_hostname(host), cmd->opcode, err);
146-
147-
cmd->retries--;
148-
cmd->error = 0;
149-
host->ops->request(host, mrq);
144+
/*
145+
* Request starter must handle retries - see
146+
* mmc_wait_for_req_done().
147+
*/
148+
if (mrq->done)
149+
mrq->done(mrq);
150150
} else {
151151
mmc_should_fail_request(host, mrq);
152152

@@ -253,7 +253,21 @@ static void __mmc_start_req(struct mmc_host *host, struct mmc_request *mrq)
253253
static void mmc_wait_for_req_done(struct mmc_host *host,
254254
struct mmc_request *mrq)
255255
{
256-
wait_for_completion(&mrq->completion);
256+
struct mmc_command *cmd;
257+
258+
while (1) {
259+
wait_for_completion(&mrq->completion);
260+
261+
cmd = mrq->cmd;
262+
if (!cmd->error || !cmd->retries)
263+
break;
264+
265+
pr_debug("%s: req failed (CMD%u): %d, retrying...\n",
266+
mmc_hostname(host), cmd->opcode, cmd->error);
267+
cmd->retries--;
268+
cmd->error = 0;
269+
host->ops->request(host, mrq);
270+
}
257271
}
258272

259273
/**

0 commit comments

Comments
 (0)