Commit fdfd31c6 authored by Dominik Brodowski's avatar Dominik Brodowski Committed by Linus Torvalds

[PATCH] mull'ify multiplication with HZ in __const_udelay()

John Stultz mentioned on lkml ( http://lkml.org/lkml/2004/6/5/15 ) that
calls to udelay() don't delay long enough, causing trouble e.g.  in the USB
subsystem.  The following patches address this issue.

Move the multiplication of (loops_per_jiffy * xloops) with HZ into the
"mull" asm operation.  This increases the accuracy of the delay functions
largely:

n usec delay on a system with loops_per_jiffy = 1500000 :

  n 	   before	  after
  1	 1000 ticks	 1499 ticks
 10	14000 ticks	14999 ticks

n usec delay on a system with loops_per_jiffy = 100000 : 

 n 	   before	  after
  1	    0 ticks	   99 ticks
 10	    0 ticks	  999 ticks
100	 9000 ticks	 9999 ticks

As noted by Kurt Garloff, it's necessary to adjust for large
loops_per_jiffies, as the multiplication of it with HZ fails for 4GHz or
larger.  So, John Stultz suggested multiplying xloops with 4 first, and
multiplying with (HZ/4).
Signed-off-by: default avatarDominik Brodowski <linux@brodo.de>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 8fa2186c
......@@ -31,10 +31,11 @@ void __delay(unsigned long loops)
inline void __const_udelay(unsigned long xloops)
{
int d0;
xloops *= 4;
__asm__("mull %0"
:"=d" (xloops), "=&a" (d0)
:"1" (xloops),"0" (current_cpu_data.loops_per_jiffy));
__delay(xloops * HZ);
:"1" (xloops),"0" (current_cpu_data.loops_per_jiffy * (HZ/4)));
__delay(xloops);
}
void __udelay(unsigned long usecs)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment