Tegra2: mmc: Add data transfer completion timeout
authorAnton staaf <robotboy@chromium.org>
Thu, 10 Nov 2011 11:56:51 +0000 (11:56 +0000)
committerAndy Fleming <afleming@freescale.com>
Sat, 12 Nov 2011 21:39:29 +0000 (15:39 -0600)
Currently when no expected completion condition occures in the
mmc_send_cmd while loop that is waiting for a data transfer to
complete the MMC driver just hangs.

This patch adds an arbitrary 2 second timeout.  If nothing we
recognize occures within 2 seconds some diagnostic information
is printed and we fail out.

Signed-off-by: Anton Staaf <robotboy@chromium.org>
Cc: Andy Fleming <afleming@gmail.com>
Cc: Tom Warren <twarren@nvidia.com>
Cc: Stephen Warren <swarren@nvidia.com>
Cc: Albert Aribaud <albert.u.boot@aribaud.net>
drivers/mmc/tegra2_mmc.c

index 159cef1e0cc73a630bb734c1326e9843799a7e70..bbd0ccdf2af8f6f9508cad52ed5041a50a03b4b9 100644 (file)
@@ -260,6 +260,8 @@ static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
        }
 
        if (data) {
+               unsigned long   start = get_timer(0);
+
                while (1) {
                        mask = readl(&host->reg->norintsts);
 
@@ -284,6 +286,18 @@ static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
                                /* Transfer Complete */
                                debug("r/w is done\n");
                                break;
+                       } else if (get_timer(start) > 2000UL) {
+                               writel(mask, &host->reg->norintsts);
+                               printf("%s: MMC Timeout\n"
+                                      "    Interrupt status        0x%08x\n"
+                                      "    Interrupt status enable 0x%08x\n"
+                                      "    Interrupt signal enable 0x%08x\n"
+                                      "    Present status          0x%08x\n",
+                                      __func__, mask,
+                                      readl(&host->reg->norintstsen),
+                                      readl(&host->reg->norintsigen),
+                                      readl(&host->reg->prnsts));
+                               return -1;
                        }
                }
                writel(mask, &host->reg->norintsts);