diff options
author | Peter Teichmann <mail@peter-teichmann.de> | 2006-03-20 12:10:09 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2006-03-21 17:06:07 -0500 |
commit | 6d4518d76f9612d580f9423cc0c3364a06b69588 (patch) | |
tree | 27e2287ecc9b858089a667def26b7d9555212337 /arch/arm/lib | |
parent | 0328ad23cfd8a0501f44a1b83e49d5b0e47e2b3c (diff) |
[ARM] 3346/1: Fix udelay() for HZ values different from 100
Patch from Peter Teichmann
Currently, if the kernels HZ value is greater than 100, delays with the udelay function are too short. This can cause trouble for instance with the zd1201 usb wlan driver.
This patch suggests a solution that keeps the overhead small and maintains (hopefully) sufficient resolution.
Signed-off-by: Peter Teichmann
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/lib')
-rw-r--r-- | arch/arm/lib/delay.S | 20 |
1 files changed, 12 insertions, 8 deletions
diff --git a/arch/arm/lib/delay.S b/arch/arm/lib/delay.S index b3fb475b4120..9183b06c0e2f 100644 --- a/arch/arm/lib/delay.S +++ b/arch/arm/lib/delay.S | |||
@@ -9,28 +9,32 @@ | |||
9 | */ | 9 | */ |
10 | #include <linux/linkage.h> | 10 | #include <linux/linkage.h> |
11 | #include <asm/assembler.h> | 11 | #include <asm/assembler.h> |
12 | #include <asm/param.h> | ||
12 | .text | 13 | .text |
13 | 14 | ||
14 | .LC0: .word loops_per_jiffy | 15 | .LC0: .word loops_per_jiffy |
16 | .LC1: .word (2199023*HZ)>>11 | ||
15 | 17 | ||
16 | /* | 18 | /* |
17 | * 0 <= r0 <= 2000 | 19 | * r0 <= 2000 |
20 | * lpj <= 0x01ffffff (max. 3355 bogomips) | ||
21 | * HZ <= 1000 | ||
18 | */ | 22 | */ |
23 | |||
19 | ENTRY(__udelay) | 24 | ENTRY(__udelay) |
20 | mov r2, #0x6800 | 25 | ldr r2, .LC1 |
21 | orr r2, r2, #0x00db | ||
22 | mul r0, r2, r0 | 26 | mul r0, r2, r0 |
23 | ENTRY(__const_udelay) @ 0 <= r0 <= 0x01ffffff | 27 | ENTRY(__const_udelay) @ 0 <= r0 <= 0x7fffff06 |
24 | ldr r2, .LC0 | 28 | ldr r2, .LC0 |
25 | ldr r2, [r2] @ max = 0x0fffffff | 29 | ldr r2, [r2] @ max = 0x01ffffff |
26 | mov r0, r0, lsr #11 @ max = 0x00003fff | 30 | mov r0, r0, lsr #14 @ max = 0x0001ffff |
27 | mov r2, r2, lsr #11 @ max = 0x0003ffff | 31 | mov r2, r2, lsr #10 @ max = 0x00007fff |
28 | mul r0, r2, r0 @ max = 2^32-1 | 32 | mul r0, r2, r0 @ max = 2^32-1 |
29 | movs r0, r0, lsr #6 | 33 | movs r0, r0, lsr #6 |
30 | RETINSTR(moveq,pc,lr) | 34 | RETINSTR(moveq,pc,lr) |
31 | 35 | ||
32 | /* | 36 | /* |
33 | * loops = (r0 * 0x10c6 * 100 * loops_per_jiffy) / 2^32 | 37 | * loops = r0 * HZ * loops_per_jiffy / 1000000 |
34 | * | 38 | * |
35 | * Oh, if only we had a cycle counter... | 39 | * Oh, if only we had a cycle counter... |
36 | */ | 40 | */ |