msm: timer: use appropriate workaround for timer instability

We currently use a simple workaround for the timer instability, which
involves reading the timer twice, and returning the higher value if two
consecutive reads are within one tick of each other. However, this
sometimes fails to converge with the DGT. So, instead do three reads,
and return either if two of them are within one of each other, or t3 if
t3-t2 is equal to t2-t1. This should cover more of the valid cases,
while not allowing false positives to come through.

A compiler barrier is necessary to guarantee we get three ldr
instructions in a row.

Change-Id: I0d56e74bba339c42239a88dd495e4d0ed93416aa
Signed-off-by: Jeff Ohlstein <johlstei@codeaurora.org>
diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
index 8f24d81..9647646 100644
--- a/arch/arm/mach-msm/timer.c
+++ b/arch/arm/mach-msm/timer.c
@@ -235,11 +235,14 @@
 		t1 = __raw_readl(addr);
 		t2 = __raw_readl(addr);
 		t3 = __raw_readl(addr);
+		cpu_relax();
 		if ((t3-t2) <= 1)
 			return t3;
 		if ((t2-t1) <= 1)
 			return t2;
-		if (++loop_count == 10) {
+		if (((t3-t2) == (t2-t1)) && (t3-t2) <= 8)
+			return t3;
+		if (++loop_count == 5) {
 			pr_err("msm_read_timer_count timer %s did not "
 			       "stabilize: %u -> %u -> %u\n",
 			       clock->clockevent.name, t1, t2, t3);