aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKouichi Tomita <kouichi.tomita.yn@renesas.com>2015-02-15 09:46:46 -0500
committerUlf Hansson <ulf.hansson@linaro.org>2015-03-23 09:13:43 -0400
commitdbb42d962c4149fe2e97f74bf1343b5229eefe5e (patch)
treea2a1fced0c5290bbf1c677a9fe2171654683182e
parent4cbd52246533d1dc6449ef8278e95e5e0944a1e5 (diff)
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>
-rw-r--r--drivers/mmc/host/sh_mmcif.c11
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,
875 struct mmc_command *cmd = mrq->cmd; 875 struct mmc_command *cmd = mrq->cmd;
876 u32 opc = cmd->opcode; 876 u32 opc = cmd->opcode;
877 u32 mask; 877 u32 mask;
878 unsigned long flags;
878 879
879 switch (opc) { 880 switch (opc) {
880 /* response busy check */ 881 /* response busy check */
@@ -909,10 +910,12 @@ static void sh_mmcif_start_cmd(struct sh_mmcif_host *host,
909 /* set arg */ 910 /* set arg */
910 sh_mmcif_writel(host->addr, MMCIF_CE_ARG, cmd->arg); 911 sh_mmcif_writel(host->addr, MMCIF_CE_ARG, cmd->arg);
911 /* set cmd */ 912 /* set cmd */
913 spin_lock_irqsave(&host->lock, flags);
912 sh_mmcif_writel(host->addr, MMCIF_CE_CMD_SET, opc); 914 sh_mmcif_writel(host->addr, MMCIF_CE_CMD_SET, opc);
913 915
914 host->wait_for = MMCIF_WAIT_FOR_CMD; 916 host->wait_for = MMCIF_WAIT_FOR_CMD;
915 schedule_delayed_work(&host->timeout_work, host->timeout); 917 schedule_delayed_work(&host->timeout_work, host->timeout);
918 spin_unlock_irqrestore(&host->lock, flags);
916} 919}
917 920
918static void sh_mmcif_stop_cmd(struct sh_mmcif_host *host, 921static 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)
1171 struct sh_mmcif_host *host = dev_id; 1174 struct sh_mmcif_host *host = dev_id;
1172 struct mmc_request *mrq; 1175 struct mmc_request *mrq;
1173 bool wait = false; 1176 bool wait = false;
1177 unsigned long flags;
1178 int wait_work;
1179
1180 spin_lock_irqsave(&host->lock, flags);
1181 wait_work = host->wait_for;
1182 spin_unlock_irqrestore(&host->lock, flags);
1174 1183
1175 cancel_delayed_work_sync(&host->timeout_work); 1184 cancel_delayed_work_sync(&host->timeout_work);
1176 1185
@@ -1188,7 +1197,7 @@ static irqreturn_t sh_mmcif_irqt(int irq, void *dev_id)
1188 * All handlers return true, if processing continues, and false, if the 1197 * All handlers return true, if processing continues, and false, if the
1189 * request has to be completed - successfully or not 1198 * request has to be completed - successfully or not
1190 */ 1199 */
1191 switch (host->wait_for) { 1200 switch (wait_work) {
1192 case MMCIF_WAIT_FOR_REQUEST: 1201 case MMCIF_WAIT_FOR_REQUEST:
1193 /* We're too late, the timeout has already kicked in */ 1202 /* We're too late, the timeout has already kicked in */
1194 mutex_unlock(&host->thread_lock); 1203 mutex_unlock(&host->thread_lock);