chrome-internal-fetch has submitted this change and it was merged.
Change subject: CHROMIUM: mmc: sdhci: handle busy-end interrupt during
command
......................................................................
CHROMIUM: mmc: sdhci: handle busy-end interrupt during command
Patch derived from
https://lkml.org/lkml/2014/2/3/12
When controller supports busy-end interrupts, they may send it
before commands complete. If the host sends a new command too early,
it will result in CRC errors.
CMD : CMD | ,,,, | RESPONSE |
DATA : | busy |
. .
. . sdhci_cmd_irq (command interupt)
.
. sdhci_data_irq ("busy end" interrupt)
Before this patch, if the CPU is very fast, when sdhci_data_irq is
executed, it would complete the command and issue a new one while
CMD line is still driven by the device, resulting in a CRC error.
With this patch, we wait for both interrupts to be received before
completing the command.
TEST=On swanky with Tohisba eMMC, check the error messages:
mmc0: Got command interrupt 0x00000001 even though no command operation
was in progress.
and
mmc0: unexpected status 0x800800 after switch
are gone.
BUG=chrome-os-partner:29817
Change-Id: I43b7467d59eb133d8c545115b48a5acbc450c2dd
Signed-off-by: Hankyung Yu <
hanky...@lge.com>
Signed-off-by: Chanho Min <
chanh...@lge.com>
Signed-off-by: Gwendal Grignou <
gwe...@chromium.org>
Reviewed-on:
https://chromium-review.googlesource.com/206033
Reviewed-by: Sonny Rao <
sonn...@chromium.org>
Tested-by: Yung Leem <
yung...@chromium.org>
(cherry picked from commit e794c9f173a20d7788ca50cf543fce65fbda3f29)
Reviewed-on:
https://chromium-review.googlesource.com/206406
---
M drivers/mmc/host/sdhci.c
M include/linux/mmc/sdhci.h
2 files changed, 22 insertions(+), 5 deletions(-)
Approvals:
Sonny Rao: Looks good to me, approved
Gwendal Grignou: Ready; Verified
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index ac3a4b1..2dadf55 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1026,6 +1026,7 @@
mod_timer(&host->timer, timeout);
host->cmd = cmd;
+ host->busy_handle = 0;
sdhci_prepare_data(host, cmd);
@@ -2312,11 +2313,18 @@
if (host->cmd->data)
DBG("Cannot wait for busy signal when also "
"doing a data transfer");
- else if (!(host->quirks & SDHCI_QUIRK_NO_BUSY_IRQ))
+ else if ((host->quirks & SDHCI_QUIRK_NO_BUSY_IRQ) ||
+ (host->busy_handle == 1)) {
+ /*
+ * The controller does not support the end-of-busy IRQ,
+ * or we already received end-of-busy IRQ,
+ * fall through and take the SDHCI_INT_RESPONSE
+ */
+ } else {
+ /* Mark that command complete before busy is ended */
+ host->busy_handle = 1;
return;
-
- /* The controller does not support the end-of-busy IRQ,
- * fall through and take the SDHCI_INT_RESPONSE */
+ }
}
if (intmask & SDHCI_INT_RESPONSE)
@@ -2376,7 +2384,15 @@
*/
if (host->cmd && (host->cmd->flags & MMC_RSP_BUSY)) {
if (intmask & SDHCI_INT_DATA_END) {
- sdhci_finish_command(host);
+ /*
+ * Some cards handle busy-end interrupt
+ * before the command completed, so make
+ * sure we do things in the proper order.
+ */
+ if (host->busy_handle)
+ sdhci_finish_command(host);
+ else
+ host->busy_handle = 1;
return;
}
}
diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h
index 352b8ce..fb9ad6e 100644
--- a/include/linux/mmc/sdhci.h
+++ b/include/linux/mmc/sdhci.h
@@ -154,6 +154,7 @@
struct mmc_command *cmd; /* Current command */
struct mmc_data *data; /* Current data request */
unsigned int data_early:1; /* Data finished before cmd */
+ unsigned int busy_handle:1; /* Handling the order of Busy-end */
struct sg_mapping_iter sg_miter; /* SG state for PIO */
unsigned int blocks; /* remaining PIO blocks */
--
To view, visit
https://chromium-review.googlesource.com/206406
To unsubscribe, visit
https://chromium-review.googlesource.com/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: I43b7467d59eb133d8c545115b48a5acbc450c2dd
Gerrit-PatchSet: 2
Gerrit-Project: chromiumos/third_party/kernel-next
Gerrit-Branch: chromeos-3.14
Gerrit-Owner: Gwendal Grignou <
gwe...@chromium.org>
Gerrit-Reviewer: Gwendal Grignou <
gwe...@chromium.org>
Gerrit-Reviewer: Sonny Rao <
sonn...@chromium.org>
Gerrit-Reviewer: chrome-internal-fetch <
chrome-int...@google.com>