[PATCH 2/3] mmc: bcm2835: Don't exit cmd wait loop on error

Stefan Wahren stefan.wahren at i2se.com
Thu Mar 2 11:24:09 PST 2017


The FAIL flag can be set in the CMD register before command processing
is complete, leading to spurious "failed to complete" errors. This has
the effect of promoting harmless CRC7 errors during CMD1 processing
into errors that can delay and even prevent booting.

Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>
---
 drivers/mmc/host/bcm2835.c |   14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/drivers/mmc/host/bcm2835.c b/drivers/mmc/host/bcm2835.c
index f5b8cac..3f4c4a8 100644
--- a/drivers/mmc/host/bcm2835.c
+++ b/drivers/mmc/host/bcm2835.c
@@ -583,22 +583,18 @@ void bcm2835_prepare_data(struct bcm2835_host *host, struct mmc_command *cmd)
 	writel(data->blocks, host->ioaddr + SDHBLC);
 }
 
-static u32 bcm2835_read_wait_sdcmd(struct bcm2835_host *host, u32 max_ms,
-				   bool check_fail)
+static u32 bcm2835_read_wait_sdcmd(struct bcm2835_host *host, u32 max_ms)
 {
 	struct device *dev = &host->pdev->dev;
 	u32 value;
 	int ret;
 
 	ret = readl_poll_timeout(host->ioaddr + SDCMD, value,
-				 (!(value & SDCMD_NEW_FLAG)) ||
-				 (check_fail && (value & SDCMD_FAIL_FLAG)),
-				 1, 10);
+				 !(value & SDCMD_NEW_FLAG), 1, 10);
 	if (ret == -ETIMEDOUT)
 		/* if it takes a while make poll interval bigger */
 		ret = readl_poll_timeout(host->ioaddr + SDCMD, value,
-					 (!(value & SDCMD_NEW_FLAG)) ||
-					 (check_fail && (value & SDCMD_FAIL_FLAG)),
+					 !(value & SDCMD_NEW_FLAG),
 					 10, max_ms * 1000);
 	if (ret == -ETIMEDOUT)
 		dev_err(dev, "%s: timeout (%d ms)\n", __func__, max_ms);
@@ -643,7 +639,7 @@ bool bcm2835_send_command(struct bcm2835_host *host, struct mmc_command *cmd)
 
 	WARN_ON(host->cmd);
 
-	sdcmd = bcm2835_read_wait_sdcmd(host, 100, false);
+	sdcmd = bcm2835_read_wait_sdcmd(host, 100);
 	if (sdcmd & SDCMD_NEW_FLAG) {
 		dev_err(dev, "previous command never completed.\n");
 		bcm2835_dumpregs(host);
@@ -759,7 +755,7 @@ static void bcm2835_finish_command(struct bcm2835_host *host)
 	struct mmc_command *cmd = host->cmd;
 	u32 sdcmd;
 
-	sdcmd = bcm2835_read_wait_sdcmd(host, 100, true);
+	sdcmd = bcm2835_read_wait_sdcmd(host, 100);
 
 	/* Check for errors */
 	if (sdcmd & SDCMD_NEW_FLAG) {
-- 
1.7.9.5




More information about the linux-rpi-kernel mailing list