| From stable-bounces@linux.kernel.org Tue Jul 24 21:45:49 2007 |
| From: Mark Fortescue <mark@mtfhpc.demon.co.uk> |
| Date: Tue, 24 Jul 2007 21:45:44 -0700 (PDT) |
| Subject: Fix sparc32 udelay() rounding errors. |
| To: stable@kernel.org |
| Cc: bunk@stusta.de |
| Message-ID: <20070724.214544.35015303.davem@davemloft.net> |
| |
| |
| From: Mark Fortescue <mark@mtfhpc.demon.co.uk> |
| |
| [SPARC32]: Fix rounding errors in ndelay/udelay implementation. |
| |
| __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: Greg Kroah-Hartman <gregkh@suse.de> |
| |
| --- |
| arch/sparc/kernel/entry.S | 14 ++++++++++---- |
| 1 file changed, 10 insertions(+), 4 deletions(-) |
| |
| --- a/arch/sparc/kernel/entry.S |
| +++ b/arch/sparc/kernel/entry.S |
| @@ -1749,8 +1749,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 |
| @@ -1760,11 +1760,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 |
| |