]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
[SPARC32]: Fix rounding errors in ndelay/udelay implementation.
authorMark Fortescue <mark@mtfhpc.demon.co.uk>
Thu, 30 Aug 2007 04:07:11 +0000 (06:07 +0200)
committerAdrian Bunk <bunk@stusta.de>
Thu, 30 Aug 2007 04:07:11 +0000 (06:07 +0200)
__ndelay and __udelay have not been delayung >= specified time.
The problem with __ndelay has been tacked down to the rounding of the
multiplier constant. By changing this, delays > app 18us are correctly
calculated.
The problem with __udelay has also been tracked down to rounding issues.
Changing the multiplier constant (to match that used in sparc64) corrects
for large delays and adding in a rounding constant corrects for trunctaion
errors in the claculations.
Many short delays will return without looping. This is not an error as there
is the fixed delay of doing all the maths to calculate the loop count.

Signed-off-by: Mark Fortescue <mark@mtfhpc.demon.co.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Adrian Bunk <bunk@kernel.org>
arch/sparc/kernel/entry.S

index 887f6a160c589a31c066055965c970922372d62b..fbbae5d381d1a90c0f26f95a1eb308b3b231deae 100644 (file)
@@ -1751,8 +1751,8 @@ fpload:
 __ndelay:
        save    %sp, -STACKFRAME_SZ, %sp
        mov     %i0, %o0
-       call    .umul
-        mov    0x1ad, %o1              ! 2**32 / (1 000 000 000 / HZ)
+       call    .umul                   ! round multiplier up so large ns ok
+        mov    0x1ae, %o1              ! 2**32 / (1 000 000 000 / HZ)
        call    .umul
         mov    %i1, %o1                ! udelay_val
        ba      delay_continue
@@ -1762,11 +1762,17 @@ __ndelay:
 __udelay:
        save    %sp, -STACKFRAME_SZ, %sp
        mov     %i0, %o0
-       sethi   %hi(0x10c6), %o1
+       sethi   %hi(0x10c7), %o1        ! round multiplier up so large us ok
        call    .umul
-        or     %o1, %lo(0x10c6), %o1   ! 2**32 / 1 000 000
+        or     %o1, %lo(0x10c7), %o1   ! 2**32 / 1 000 000
        call    .umul
         mov    %i1, %o1                ! udelay_val
+       sethi   %hi(0x028f4b62), %l0    ! Add in rounding constant * 2**32,
+       or      %g0, %lo(0x028f4b62), %l0
+       addcc   %o0, %l0, %o0           ! 2**32 * 0.009 999
+       bcs,a   3f
+        add    %o1, 0x01, %o1
+3:
        call    .umul
         mov    HZ, %o0                 ! >>32 earlier for wider range