msm: watchdog: store worst case watchdog slack time

Record the amount of slack the watchdog count has each time we pet.
Record this both in ticks as read from the watchdog status register, and
in nanoseconds as read from the timer. This will allow us to catch any
potential discrepancies from the expected watchdog tick rate.

Having statistics across a number of runs will allow us to see if we
commonly are close to the watchdog bark time, or if that only happens in
exceptional cases.

Change-Id: I6e6c9995d53a7093e1e9d939e9da6c0c35c3490f
Signed-off-by: Jeff Ohlstein <johlstei@codeaurora.org>
diff --git a/arch/arm/mach-msm/msm_watchdog.c b/arch/arm/mach-msm/msm_watchdog.c
index a1316b7..f04148a 100644
--- a/arch/arm/mach-msm/msm_watchdog.c
+++ b/arch/arm/mach-msm/msm_watchdog.c
@@ -35,6 +35,7 @@
 
 #define WDT0_RST	0x38
 #define WDT0_EN		0x40
+#define WDT0_STS	0x44
 #define WDT0_BARK_TIME	0x4C
 #define WDT0_BITE_TIME	0x5C
 
@@ -180,10 +181,26 @@
 	return ret;
 }
 
+unsigned min_slack_ticks = UINT_MAX;
+unsigned long long min_slack_ns = ULLONG_MAX;
+
 void pet_watchdog(void)
 {
+	int slack;
+	unsigned long long time_ns;
+	unsigned long long slack_ns;
+	unsigned long long bark_time_ns = bark_time * 1000000ULL;
+
+	slack = __raw_readl(msm_tmr0_base + WDT0_STS) >> 3;
+	slack = ((bark_time*WDT_HZ)/1000) - slack;
+	if (slack < min_slack_ticks)
+		min_slack_ticks = slack;
 	__raw_writel(1, msm_tmr0_base + WDT0_RST);
-	last_pet = sched_clock();
+	time_ns = sched_clock();
+	slack_ns = (last_pet + bark_time_ns) - time_ns;
+	if (slack_ns < min_slack_ns)
+		min_slack_ns = slack_ns;
+	last_pet = time_ns;
 }
 
 static void pet_watchdog_work(struct work_struct *work)