diff --git a/drivers/mmc/host/rk_sdmmc.c b/drivers/mmc/host/rk_sdmmc.c index 9d81ce83f7a6..4d1d2c19e68d 100755 --- a/drivers/mmc/host/rk_sdmmc.c +++ b/drivers/mmc/host/rk_sdmmc.c @@ -1165,12 +1165,8 @@ static void dw_mci_command_complete(struct dw_mci *host, struct mmc_command *cmd /* newer ip versions need a delay between retries */ if (host->quirks & DW_MCI_QUIRK_RETRY_DELAY) mdelay(20); - - if (cmd->data) { - dw_mci_stop_dma(host); - host->data = NULL; - } } + } static void dw_mci_tasklet_func(unsigned long priv) @@ -1209,6 +1205,18 @@ static void dw_mci_tasklet_func(unsigned long priv) host->mrq->cmd); goto unlock; } + + if (cmd->data && cmd->error) { + dw_mci_stop_dma(host); + if (data->stop) { + send_stop_cmd(host, data); + state = STATE_SENDING_STOP; + break; + } else { + host->data = NULL; + } + } + if (!host->mrq->data || cmd->error) { dw_mci_request_end(host, host->mrq); @@ -1303,8 +1311,19 @@ static void dw_mci_tasklet_func(unsigned long priv) if (!test_and_clear_bit(EVENT_CMD_COMPLETE, &host->pending_events)) break; + + /* CMD error in data command */ + if (host->mrq->cmd->error && host->mrq->data) { + sg_miter_stop(&host->sg_miter); + host->sg = NULL; + ctrl = mci_readl(host, CTRL); + ctrl |= SDMMC_CTRL_FIFO_RESET; + mci_writel(host, CTRL, ctrl); + } + host->cmd = NULL; + host->data = NULL; dw_mci_command_complete(host, host->mrq->stop); dw_mci_request_end(host, host->mrq); goto unlock;