Merge branch 'for-linus' of git://git.infradead.org/users/vkoul/slave-dma
[linux-2.6-block.git] / drivers / mmc / host / sh_mmcif.c
index 26b7889febb2760c40738f9af35965c00dcc2f95..2b6ef6bd5d5fee1c3277c4970549da294b4706da 100644 (file)
@@ -872,6 +872,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 */
@@ -906,10 +907,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,
@@ -1168,6 +1171,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);
 
@@ -1185,7 +1194,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);
@@ -1309,15 +1318,15 @@ static void mmcif_timeout_work(struct work_struct *work)
                /* Don't run after mmc_remove_host() */
                return;
 
-       dev_err(&host->pd->dev, "Timeout waiting for %u on CMD%u\n",
-               host->wait_for, mrq->cmd->opcode);
-
        spin_lock_irqsave(&host->lock, flags);
        if (host->state == STATE_IDLE) {
                spin_unlock_irqrestore(&host->lock, flags);
                return;
        }
 
+       dev_err(&host->pd->dev, "Timeout waiting for %u on CMD%u\n",
+               host->wait_for, mrq->cmd->opcode);
+
        host->state = STATE_TIMEOUT;
        spin_unlock_irqrestore(&host->lock, flags);