|
@@ -572,6 +572,15 @@ static irqreturn_t sunxi_mmc_handle_manual_stop(int irq, void *dev_id)
|
|
}
|
|
}
|
|
|
|
|
|
dev_err(mmc_dev(host->mmc), "data error, sending stop command\n");
|
|
dev_err(mmc_dev(host->mmc), "data error, sending stop command\n");
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * We will never have more than one outstanding request,
|
|
|
|
+ * and we do not complete the request until after
|
|
|
|
+ * we've cleared host->manual_stop_mrq so we do not need to
|
|
|
|
+ * spin lock this function.
|
|
|
|
+ * Additionally we have wait states within this function
|
|
|
|
+ * so having it in a lock is a very bad idea.
|
|
|
|
+ */
|
|
sunxi_mmc_send_manual_stop(host, mrq);
|
|
sunxi_mmc_send_manual_stop(host, mrq);
|
|
|
|
|
|
spin_lock_irqsave(&host->lock, iflags);
|
|
spin_lock_irqsave(&host->lock, iflags);
|
|
@@ -768,6 +777,7 @@ static void sunxi_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
|
|
unsigned long iflags;
|
|
unsigned long iflags;
|
|
u32 imask = SDXC_INTERRUPT_ERROR_BIT;
|
|
u32 imask = SDXC_INTERRUPT_ERROR_BIT;
|
|
u32 cmd_val = SDXC_START | (cmd->opcode & 0x3f);
|
|
u32 cmd_val = SDXC_START | (cmd->opcode & 0x3f);
|
|
|
|
+ bool wait_dma = host->wait_dma;
|
|
int ret;
|
|
int ret;
|
|
|
|
|
|
/* Check for set_ios errors (should never happen) */
|
|
/* Check for set_ios errors (should never happen) */
|
|
@@ -818,7 +828,7 @@ static void sunxi_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
|
|
if (cmd->data->flags & MMC_DATA_WRITE)
|
|
if (cmd->data->flags & MMC_DATA_WRITE)
|
|
cmd_val |= SDXC_WRITE;
|
|
cmd_val |= SDXC_WRITE;
|
|
else
|
|
else
|
|
- host->wait_dma = true;
|
|
|
|
|
|
+ wait_dma = true;
|
|
} else {
|
|
} else {
|
|
imask |= SDXC_COMMAND_DONE;
|
|
imask |= SDXC_COMMAND_DONE;
|
|
}
|
|
}
|
|
@@ -852,6 +862,7 @@ static void sunxi_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
|
|
}
|
|
}
|
|
|
|
|
|
host->mrq = mrq;
|
|
host->mrq = mrq;
|
|
|
|
+ host->wait_dma = wait_dma;
|
|
mmc_writel(host, REG_IMASK, host->sdio_imask | imask);
|
|
mmc_writel(host, REG_IMASK, host->sdio_imask | imask);
|
|
mmc_writel(host, REG_CARG, cmd->arg);
|
|
mmc_writel(host, REG_CARG, cmd->arg);
|
|
mmc_writel(host, REG_CMDR, cmd_val);
|
|
mmc_writel(host, REG_CMDR, cmd_val);
|