diff options
-rw-r--r-- | drivers/mmc/host/mmci.c | 25 | ||||
-rw-r--r-- | drivers/mmc/host/mmci.h | 1 |
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 | ||
1130 | static 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 | |||
1130 | static void | 1136 | static void |
1131 | mmci_data_irq(struct mmci_host *host, struct mmc_data *data, | 1137 | mmci_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; |