aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/mmc/host/mmci.c25
-rw-r--r--drivers/mmc/host/mmci.h1
2 files changed, 24 insertions, 2 deletions
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 7dd3ccf5baf0..387ff14587b8 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -1127,6 +1127,12 @@ mmci_start_command(struct mmci_host *host, struct mmc_command *cmd, u32 c)
1127 writel(c, base + MMCICOMMAND); 1127 writel(c, base + MMCICOMMAND);
1128} 1128}
1129 1129
1130static void mmci_stop_command(struct mmci_host *host)
1131{
1132 host->stop_abort.error = 0;
1133 mmci_start_command(host, &host->stop_abort, 0);
1134}
1135
1130static void 1136static void
1131mmci_data_irq(struct mmci_host *host, struct mmc_data *data, 1137mmci_data_irq(struct mmci_host *host, struct mmc_data *data,
1132 unsigned int status) 1138 unsigned int status)
@@ -1196,10 +1202,16 @@ mmci_data_irq(struct mmci_host *host, struct mmc_data *data,
1196 /* The error clause is handled above, success! */ 1202 /* The error clause is handled above, success! */
1197 data->bytes_xfered = data->blksz * data->blocks; 1203 data->bytes_xfered = data->blksz * data->blocks;
1198 1204
1199 if (!data->stop || (host->mrq->sbc && !data->error)) 1205 if (!data->stop) {
1206 if (host->variant->cmdreg_stop && data->error)
1207 mmci_stop_command(host);
1208 else
1209 mmci_request_end(host, data->mrq);
1210 } else if (host->mrq->sbc && !data->error) {
1200 mmci_request_end(host, data->mrq); 1211 mmci_request_end(host, data->mrq);
1201 else 1212 } else {
1202 mmci_start_command(host, data->stop, 0); 1213 mmci_start_command(host, data->stop, 0);
1214 }
1203 } 1215 }
1204} 1216}
1205 1217
@@ -1298,6 +1310,10 @@ mmci_cmd_irq(struct mmci_host *host, struct mmc_command *cmd,
1298 mmci_dma_error(host); 1310 mmci_dma_error(host);
1299 1311
1300 mmci_stop_data(host); 1312 mmci_stop_data(host);
1313 if (host->variant->cmdreg_stop && cmd->error) {
1314 mmci_stop_command(host);
1315 return;
1316 }
1301 } 1317 }
1302 mmci_request_end(host, host->mrq); 1318 mmci_request_end(host, host->mrq);
1303 } else if (sbc) { 1319 } else if (sbc) {
@@ -1956,6 +1972,11 @@ static int mmci_probe(struct amba_device *dev,
1956 mmc->max_busy_timeout = 0; 1972 mmc->max_busy_timeout = 0;
1957 } 1973 }
1958 1974
1975 /* Prepare a CMD12 - needed to clear the DPSM on some variants. */
1976 host->stop_abort.opcode = MMC_STOP_TRANSMISSION;
1977 host->stop_abort.arg = 0;
1978 host->stop_abort.flags = MMC_RSP_R1B | MMC_CMD_AC;
1979
1959 mmc->ops = &mmci_ops; 1980 mmc->ops = &mmci_ops;
1960 1981
1961 /* We support these PM capabilities. */ 1982 /* We support these PM capabilities. */
diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h
index 24229097d05c..14df81054438 100644
--- a/drivers/mmc/host/mmci.h
+++ b/drivers/mmc/host/mmci.h
@@ -377,6 +377,7 @@ struct mmci_host {
377 void __iomem *base; 377 void __iomem *base;
378 struct mmc_request *mrq; 378 struct mmc_request *mrq;
379 struct mmc_command *cmd; 379 struct mmc_command *cmd;
380 struct mmc_command stop_abort;
380 struct mmc_data *data; 381 struct mmc_data *data;
381 struct mmc_host *mmc; 382 struct mmc_host *mmc;
382 struct clk *clk; 383 struct clk *clk;