diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c index 1fe54a889ce33e780df8e24691abd386e4ceb93d..67e680c128c5fcb0c36568862ed0be057531522f 100644 --- a/drivers/mmc/host/sunxi-mmc.c +++ b/drivers/mmc/host/sunxi-mmc.c @@ -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"); + + /* + * 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); 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; u32 imask = SDXC_INTERRUPT_ERROR_BIT; u32 cmd_val = SDXC_START | (cmd->opcode & 0x3f); + bool wait_dma = host->wait_dma; int ret; /* 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) cmd_val |= SDXC_WRITE; else - host->wait_dma = true; + wait_dma = true; } else { 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->wait_dma = wait_dma; mmc_writel(host, REG_IMASK, host->sdio_imask | imask); mmc_writel(host, REG_CARG, cmd->arg); mmc_writel(host, REG_CMDR, cmd_val);