diff -urN oldtree/include/linux/clocksource.h newtree.new/include/linux/clocksource.h
--- oldtree/include/linux/clocksource.h	2006-06-27 12:28:59.000000000 +0000
+++ newtree.new/include/linux/clocksource.h	2006-06-28 11:57:55.000000000 +0000
@@ -55,7 +55,7 @@
 	int rating;
 	cycle_t (*read)(void);
 	cycle_t mask;
-	u32 mult;
+	u32 mult, multi_min;
 	u32 shift;
 	int (*update_callback)(void);
 	int is_continuous;
@@ -169,6 +169,8 @@
 	tmp += c->mult/2;
 	do_div(tmp, c->mult);
 
+        c->multi_min = max(c->multi >> 2, 1u);
+
 	c->cycle_interval = (cycle_t)tmp;
 	if (c->cycle_interval == 0)
 		c->cycle_interval = 1;
diff -urN oldtree/kernel/timer.c newtree.new/kernel/timer.c
--- oldtree/kernel/timer.c	2006-06-27 12:28:59.000000000 +0000
+++ newtree.new/kernel/timer.c	2006-06-28 12:01:32.000000000 +0000
@@ -1051,6 +1051,12 @@
 	if (sign > 0 ? error > *interval : error < *interval)
 		adj++;
 
+        if (sign < 0 && unlikely(clock->multi < clock->multi_min + (1 << adj))) {
+                if (clock->multi <= clock->multi_min)
+                       return 0;
+                adj = fls(clock->multi - clock->multi_min) - 1;
+        } 
+
 	*interval <<= adj;
 	*offset <<= adj;
 	return sign << adj;
