* [PATCH 1/4] mmc: sdhci: Fix CMD line reset interfering with ongoing data transfer
2016-11-02 13:49 [PATCH 0/4] mmc: sdhci: Fixes Adrian Hunter
@ 2016-11-02 13:49 ` Adrian Hunter
2016-11-02 13:49 ` [PATCH 2/4] mmc: sdhci: Fix unexpected data interrupt handling Adrian Hunter
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Adrian Hunter @ 2016-11-02 13:49 UTC (permalink / raw)
To: Ulf Hansson; +Cc: linux-mmc, Harjani Ritesh
CMD line reset during an ongoing data transfer can cause the data transfer
to hang. Fix by delaying the reset until the data transfer is finished.
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: stable@vger.kernel.org # v4.8+
---
drivers/mmc/host/sdhci.c | 23 ++++++++++++++++-------
1 file changed, 16 insertions(+), 7 deletions(-)
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 1e25b01600e1..ad135d4449e6 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -2283,10 +2283,8 @@ static bool sdhci_request_done(struct sdhci_host *host)
for (i = 0; i < SDHCI_MAX_MRQS; i++) {
mrq = host->mrqs_done[i];
- if (mrq) {
- host->mrqs_done[i] = NULL;
+ if (mrq)
break;
- }
}
if (!mrq) {
@@ -2317,6 +2315,17 @@ static bool sdhci_request_done(struct sdhci_host *host)
* upon error conditions.
*/
if (sdhci_needs_reset(host, mrq)) {
+ /*
+ * Do not finish until command and data lines are available for
+ * reset. Note there can only be one other mrq, so it cannot
+ * also be in mrqs_done, otherwise host->cmd and host->data_cmd
+ * would both be null.
+ */
+ if (host->cmd || host->data_cmd) {
+ spin_unlock_irqrestore(&host->lock, flags);
+ return true;
+ }
+
/* Some controllers need this kick or reset won't work here */
if (host->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET)
/* This is to force an update */
@@ -2324,10 +2333,8 @@ static bool sdhci_request_done(struct sdhci_host *host)
/* Spec says we should do both at the same time, but Ricoh
controllers do not like that. */
- if (!host->cmd)
- sdhci_do_reset(host, SDHCI_RESET_CMD);
- if (!host->data_cmd)
- sdhci_do_reset(host, SDHCI_RESET_DATA);
+ sdhci_do_reset(host, SDHCI_RESET_CMD);
+ sdhci_do_reset(host, SDHCI_RESET_DATA);
host->pending_reset = false;
}
@@ -2335,6 +2342,8 @@ static bool sdhci_request_done(struct sdhci_host *host)
if (!sdhci_has_requests(host))
sdhci_led_deactivate(host);
+ host->mrqs_done[i] = NULL;
+
mmiowb();
spin_unlock_irqrestore(&host->lock, flags);
--
1.9.1
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH 2/4] mmc: sdhci: Fix unexpected data interrupt handling
2016-11-02 13:49 [PATCH 0/4] mmc: sdhci: Fixes Adrian Hunter
2016-11-02 13:49 ` [PATCH 1/4] mmc: sdhci: Fix CMD line reset interfering with ongoing data transfer Adrian Hunter
@ 2016-11-02 13:49 ` Adrian Hunter
2016-11-02 13:49 ` [PATCH 3/4] mmc: sdhci: Reset cmd and data circuits after tuning failure Adrian Hunter
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Adrian Hunter @ 2016-11-02 13:49 UTC (permalink / raw)
To: Ulf Hansson; +Cc: linux-mmc, Harjani Ritesh
In the busy response case (i.e. !host->data), an unexpected data interrupt
would result in clearing the data command as though it had completed but
without informing the upper layers and thus resulting in a hang. Fix by
only clearing the data command for data interrupts that are expected.
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: stable@vger.kernel.org # v4.8+
---
drivers/mmc/host/sdhci.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index ad135d4449e6..e7e1a70645e3 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -2518,9 +2518,6 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
if (!host->data) {
struct mmc_command *data_cmd = host->data_cmd;
- if (data_cmd)
- host->data_cmd = NULL;
-
/*
* The "data complete" interrupt is also used to
* indicate that a busy state has ended. See comment
@@ -2528,11 +2525,13 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
*/
if (data_cmd && (data_cmd->flags & MMC_RSP_BUSY)) {
if (intmask & SDHCI_INT_DATA_TIMEOUT) {
+ host->data_cmd = NULL;
data_cmd->error = -ETIMEDOUT;
sdhci_finish_mrq(host, data_cmd->mrq);
return;
}
if (intmask & SDHCI_INT_DATA_END) {
+ host->data_cmd = NULL;
/*
* Some cards handle busy-end interrupt
* before the command completed, so make
--
1.9.1
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH 3/4] mmc: sdhci: Reset cmd and data circuits after tuning failure
2016-11-02 13:49 [PATCH 0/4] mmc: sdhci: Fixes Adrian Hunter
2016-11-02 13:49 ` [PATCH 1/4] mmc: sdhci: Fix CMD line reset interfering with ongoing data transfer Adrian Hunter
2016-11-02 13:49 ` [PATCH 2/4] mmc: sdhci: Fix unexpected data interrupt handling Adrian Hunter
@ 2016-11-02 13:49 ` Adrian Hunter
2016-11-02 13:49 ` [PATCH 4/4] mmc: sdhci: Fix missing enhanced strobe setting during runtime resume Adrian Hunter
2016-11-07 12:43 ` [PATCH 0/4] mmc: sdhci: Fixes Ulf Hansson
4 siblings, 0 replies; 6+ messages in thread
From: Adrian Hunter @ 2016-11-02 13:49 UTC (permalink / raw)
To: Ulf Hansson; +Cc: linux-mmc, Harjani Ritesh
To prevent subsequent commands failing, ensure the cmd and data circuits
are reset after a tuning timeout.
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
drivers/mmc/host/sdhci.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index e7e1a70645e3..f8cb9a958738 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -2083,6 +2083,10 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
if (!host->tuning_done) {
pr_info(DRIVER_NAME ": Timeout waiting for Buffer Read Ready interrupt during tuning procedure, falling back to fixed sampling clock\n");
+
+ sdhci_do_reset(host, SDHCI_RESET_CMD);
+ sdhci_do_reset(host, SDHCI_RESET_DATA);
+
ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
ctrl &= ~SDHCI_CTRL_TUNED_CLK;
ctrl &= ~SDHCI_CTRL_EXEC_TUNING;
--
1.9.1
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH 4/4] mmc: sdhci: Fix missing enhanced strobe setting during runtime resume
2016-11-02 13:49 [PATCH 0/4] mmc: sdhci: Fixes Adrian Hunter
` (2 preceding siblings ...)
2016-11-02 13:49 ` [PATCH 3/4] mmc: sdhci: Reset cmd and data circuits after tuning failure Adrian Hunter
@ 2016-11-02 13:49 ` Adrian Hunter
2016-11-07 12:43 ` [PATCH 0/4] mmc: sdhci: Fixes Ulf Hansson
4 siblings, 0 replies; 6+ messages in thread
From: Adrian Hunter @ 2016-11-02 13:49 UTC (permalink / raw)
To: Ulf Hansson; +Cc: linux-mmc, Harjani Ritesh
Restore enhanced strobe setting during runtime resume.
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
drivers/mmc/host/sdhci.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index f8cb9a958738..146f442de1ad 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -2921,6 +2921,10 @@ int sdhci_runtime_resume_host(struct sdhci_host *host)
spin_unlock_irqrestore(&host->lock, flags);
}
+ if ((mmc->caps2 & MMC_CAP2_HS400_ES) &&
+ mmc->ops->hs400_enhanced_strobe)
+ mmc->ops->hs400_enhanced_strobe(mmc, &mmc->ios);
+
spin_lock_irqsave(&host->lock, flags);
host->runtime_suspended = false;
--
1.9.1
^ permalink raw reply related [flat|nested] 6+ messages in thread* Re: [PATCH 0/4] mmc: sdhci: Fixes
2016-11-02 13:49 [PATCH 0/4] mmc: sdhci: Fixes Adrian Hunter
` (3 preceding siblings ...)
2016-11-02 13:49 ` [PATCH 4/4] mmc: sdhci: Fix missing enhanced strobe setting during runtime resume Adrian Hunter
@ 2016-11-07 12:43 ` Ulf Hansson
4 siblings, 0 replies; 6+ messages in thread
From: Ulf Hansson @ 2016-11-07 12:43 UTC (permalink / raw)
To: Adrian Hunter; +Cc: linux-mmc, Harjani Ritesh
On 2 November 2016 at 14:49, Adrian Hunter <adrian.hunter@intel.com> wrote:
> Hi
>
> Here are 4 small sdhci fixes. Some of the fixes improve sdhci ability to
> deal with errors (e.g. CRC errors ) when software command queuing is active.
>
>
> Adrian Hunter (4):
> mmc: sdhci: Fix CMD line reset interfering with ongoing data transfer
> mmc: sdhci: Fix unexpected data interrupt handling
> mmc: sdhci: Reset cmd and data circuits after tuning failure
> mmc: sdhci: Fix missing enhanced strobe setting during runtime resume
>
> drivers/mmc/host/sdhci.c | 36 ++++++++++++++++++++++++++----------
> 1 file changed, 26 insertions(+), 10 deletions(-)
>
>
> Regards
> Adrian
Thanks, applied for fixes!
Kind regards
Uffe
^ permalink raw reply [flat|nested] 6+ messages in thread