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

Commit dbb42d96 authored by Kouichi Tomita's avatar Kouichi Tomita Committed by Ulf Hansson
Browse files

mmc: sh_mmcif: Add exclusion between cmd and interrupt



A command end interrupt should not be processed between command issue
and setting of wait_for flag. It expects already the flag to be set.
Therefore the exclusive control was added.

Signed-off-by: default avatarKouichi Tomita <kouichi.tomita.yn@renesas.com>
Signed-off-by: default avatarYoshihiro Kaneko <ykaneko0929@gmail.com>
Signed-off-by: default avatarUlf Hansson <ulf.hansson@linaro.org>
parent 4cbd5224
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -875,6 +875,7 @@ static void sh_mmcif_start_cmd(struct sh_mmcif_host *host,
	struct mmc_command *cmd = mrq->cmd;
	u32 opc = cmd->opcode;
	u32 mask;
	unsigned long flags;

	switch (opc) {
	/* response busy check */
@@ -909,10 +910,12 @@ static void sh_mmcif_start_cmd(struct sh_mmcif_host *host,
	/* set arg */
	sh_mmcif_writel(host->addr, MMCIF_CE_ARG, cmd->arg);
	/* set cmd */
	spin_lock_irqsave(&host->lock, flags);
	sh_mmcif_writel(host->addr, MMCIF_CE_CMD_SET, opc);

	host->wait_for = MMCIF_WAIT_FOR_CMD;
	schedule_delayed_work(&host->timeout_work, host->timeout);
	spin_unlock_irqrestore(&host->lock, flags);
}

static void sh_mmcif_stop_cmd(struct sh_mmcif_host *host,
@@ -1171,6 +1174,12 @@ static irqreturn_t sh_mmcif_irqt(int irq, void *dev_id)
	struct sh_mmcif_host *host = dev_id;
	struct mmc_request *mrq;
	bool wait = false;
	unsigned long flags;
	int wait_work;

	spin_lock_irqsave(&host->lock, flags);
	wait_work = host->wait_for;
	spin_unlock_irqrestore(&host->lock, flags);

	cancel_delayed_work_sync(&host->timeout_work);

@@ -1188,7 +1197,7 @@ static irqreturn_t sh_mmcif_irqt(int irq, void *dev_id)
	 * All handlers return true, if processing continues, and false, if the
	 * request has to be completed - successfully or not
	 */
	switch (host->wait_for) {
	switch (wait_work) {
	case MMCIF_WAIT_FOR_REQUEST:
		/* We're too late, the timeout has already kicked in */
		mutex_unlock(&host->thread_lock);