[PARISC] disable cr16 clocksource when multiple CPUs are online

Signed-off-by: Helge Deller <deller@gmx.de>
Signed-off-by: Kyle McMartin <kyle@parisc-linux.org>
diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c
index e47e27c..c33b6e0 100644
--- a/arch/parisc/kernel/time.c
+++ b/arch/parisc/kernel/time.c
@@ -99,7 +99,7 @@
 	 * cycles after the IT fires. But it's arbitrary how much time passes
 	 * before we call it "late". I've picked one second.
 	 */
-	if (ticks_elapsed > HZ) {
+	if (unlikely(ticks_elapsed > HZ)) {
 		/* Scenario 3: very long delay?  bad in any case */
 		printk (KERN_CRIT "timer_interrupt(CPU %d): delayed!"
 			" cycles %lX rem %lX "
@@ -180,6 +180,8 @@
 	return get_cycles();
 }
 
+static int cr16_update_callback(void);
+
 static struct clocksource clocksource_cr16 = {
 	.name			= "cr16",
 	.rating			= 300,
@@ -187,9 +189,25 @@
 	.mask			= CLOCKSOURCE_MASK(BITS_PER_LONG),
 	.mult			= 0, /* to be set */
 	.shift			= 22,
+	.update_callback	= cr16_update_callback,
 	.is_continuous		= 1,
 };
 
+static int cr16_update_callback(void)
+{
+	int change = 0;
+
+	/* since the cr16 cycle counters are not syncronized across CPUs,
+	   we'll check if we should switch to a safe clocksource: */
+	if (clocksource_cr16.rating != 0 && num_online_cpus() > 1) {
+		clocksource_cr16.rating = 0;
+		clocksource_reselect();
+		change = 1;
+	}
+
+	return change;
+}
+
 
 /*
  * XXX: We can do better than this.
@@ -225,10 +243,6 @@
 	current_cr16_khz = PAGE0->mem_10msec/10;  /* kHz */
 	clocksource_cr16.mult = clocksource_khz2mult(current_cr16_khz,
 						clocksource_cr16.shift);
-	/* lower the rating if we already know its unstable: */
-	if (num_online_cpus()>1)
-		clocksource_cr16.rating = 200;
-
 	clocksource_register(&clocksource_cr16);
 
 	if (pdc_tod_read(&tod_data) == 0) {