diff options
-rw-r--r-- | drivers/mmc/host/sdhci.c | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 0851a4bba413..48055666c655 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -888,7 +888,8 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd) static inline bool sdhci_auto_cmd12(struct sdhci_host *host, struct mmc_request *mrq) { - return !mrq->sbc && (host->flags & SDHCI_AUTO_CMD12); + return !mrq->sbc && (host->flags & SDHCI_AUTO_CMD12) && + !mrq->cap_cmd_during_tfr; } static void sdhci_set_transfer_mode(struct sdhci_host *host, @@ -1031,9 +1032,18 @@ static void sdhci_finish_data(struct sdhci_host *host) sdhci_do_reset(host, SDHCI_RESET_DATA); } - /* Avoid triggering warning in sdhci_send_command() */ - host->cmd = NULL; - sdhci_send_command(host, data->stop); + /* + * 'cap_cmd_during_tfr' request must not use the command line + * after mmc_command_done() has been called. It is upper layer's + * responsibility to send the stop command if required. + */ + if (data->mrq->cap_cmd_during_tfr) { + sdhci_finish_mrq(host, data->mrq); + } else { + /* Avoid triggering warning in sdhci_send_command() */ + host->cmd = NULL; + sdhci_send_command(host, data->stop); + } } else { sdhci_finish_mrq(host, data->mrq); } @@ -1165,6 +1175,9 @@ static void sdhci_finish_command(struct sdhci_host *host) } } + if (cmd->mrq->cap_cmd_during_tfr && cmd == cmd->mrq->cmd) + mmc_command_done(host->mmc, cmd->mrq); + /* * The host can send and interrupt when the busy state has * ended, allowing us to wait without wasting CPU cycles. |