From 9b3d1873c8c829debe8e8ab487783577285530d3 Mon Sep 17 00:00:00 2001
From: Anton staaf <robotboy@chromium.org>
Date: Thu, 10 Nov 2011 11:56:51 +0000
Subject: [PATCH] Tegra2: mmc: Add data transfer completion timeout

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 | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/drivers/mmc/tegra2_mmc.c b/drivers/mmc/tegra2_mmc.c
index 159cef1e0c..bbd0ccdf2a 100644
--- a/drivers/mmc/tegra2_mmc.c
+++ b/drivers/mmc/tegra2_mmc.c
@@ -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);
-- 
2.39.5