diff options
author | Kouichi Tomita <kouichi.tomita.yn@renesas.com> | 2015-02-15 23:46:46 +0900 |
---|---|---|
committer | Ulf Hansson <ulf.hansson@linaro.org> | 2015-03-23 14:13:43 +0100 |
commit | dbb42d962c4149fe2e97f74bf1343b5229eefe5e (patch) | |
tree | a2a1fced0c5290bbf1c677a9fe2171654683182e /drivers/mmc/host/sh_mmcif.c | |
parent | 4cbd52246533d1dc6449ef8278e95e5e0944a1e5 (diff) | |
download | linux-stable-dbb42d962c4149fe2e97f74bf1343b5229eefe5e.tar.gz linux-stable-dbb42d962c4149fe2e97f74bf1343b5229eefe5e.tar.bz2 linux-stable-dbb42d962c4149fe2e97f74bf1343b5229eefe5e.zip |
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: Kouichi Tomita <kouichi.tomita.yn@renesas.com>
Signed-off-by: Yoshihiro Kaneko <ykaneko0929@gmail.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Diffstat (limited to 'drivers/mmc/host/sh_mmcif.c')
-rw-r--r-- | drivers/mmc/host/sh_mmcif.c | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c index e0758044a263..072f67066df3 100644 --- a/drivers/mmc/host/sh_mmcif.c +++ b/drivers/mmc/host/sh_mmcif.c @@ -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); |