Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+21 −7
Original line number Diff line number Diff line
@@ -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)
{
	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);
	}
}

/**