Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Kouichi Tomita and committed by
Ulf Hansson
dbb42d96 4cbd5224

+10 -1
+10 -1
drivers/mmc/host/sh_mmcif.c
··· 875 875 struct mmc_command *cmd = mrq->cmd; 876 876 u32 opc = cmd->opcode; 877 877 u32 mask; 878 + unsigned long flags; 878 879 879 880 switch (opc) { 880 881 /* response busy check */ ··· 910 909 /* set arg */ 911 910 sh_mmcif_writel(host->addr, MMCIF_CE_ARG, cmd->arg); 912 911 /* set cmd */ 912 + spin_lock_irqsave(&host->lock, flags); 913 913 sh_mmcif_writel(host->addr, MMCIF_CE_CMD_SET, opc); 914 914 915 915 host->wait_for = MMCIF_WAIT_FOR_CMD; 916 916 schedule_delayed_work(&host->timeout_work, host->timeout); 917 + spin_unlock_irqrestore(&host->lock, flags); 917 918 } 918 919 919 920 static void sh_mmcif_stop_cmd(struct sh_mmcif_host *host, ··· 1174 1171 struct sh_mmcif_host *host = dev_id; 1175 1172 struct mmc_request *mrq; 1176 1173 bool wait = false; 1174 + unsigned long flags; 1175 + int wait_work; 1176 + 1177 + spin_lock_irqsave(&host->lock, flags); 1178 + wait_work = host->wait_for; 1179 + spin_unlock_irqrestore(&host->lock, flags); 1177 1180 1178 1181 cancel_delayed_work_sync(&host->timeout_work); 1179 1182 ··· 1197 1188 * All handlers return true, if processing continues, and false, if the 1198 1189 * request has to be completed - successfully or not 1199 1190 */ 1200 - switch (host->wait_for) { 1191 + switch (wait_work) { 1201 1192 case MMCIF_WAIT_FOR_REQUEST: 1202 1193 /* We're too late, the timeout has already kicked in */ 1203 1194 mutex_unlock(&host->thread_lock);