CHROMIUM: mmc: sdhci: handle busy-end interrupt during comma... [chromiumos/third_party/kernel-next : chromeos-3.14]

35 views
Skip to first unread message

chrome-internal-fetch (Gerrit)

unread,
Jul 2, 2014, 1:45:34 AM7/2/14
to Gwendal Grignou, Sonny Rao
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>
Reply all
Reply to author
Forward
0 new messages