diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-10-11 14:34:50 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-10-11 14:34:50 -0400 |
commit | f144c78e525542c94e0dcb171b41cc5ef7b341b3 (patch) | |
tree | a94920a3f87a11ad1875e08619a60e748b626e34 /arch/s390/lib/delay.c | |
parent | ef1f7a7e878e4ae37b3a78ebdeef9f911bae59df (diff) | |
parent | 6fca97a958bc3c67566aa91eafc6a5be2e66d6b3 (diff) |
Merge branch 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6
* 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6: (21 commits)
[S390] dasd: fix race condition in resume code
[S390] Add EX_TABLE for addressing exception in usercopy functions.
[S390] 64-bit register support for 31-bit processes
[S390] hibernate: Use correct place for CPU address in lowcore
[S390] pm: ignore time spend in suspended state
[S390] zcrypt: Improve some comments
[S390] zcrypt: Fix sparse warning.
[S390] perf_counter: fix vdso detection
[S390] ftrace: drop nmi protection
[S390] compat: fix truncate system call wrapper
[S390] Provide arch specific mdelay implementation.
[S390] Fix enabled udelay for short delays.
[S390] cio: allow setting boxed devices offline
[S390] cio: make not operational handling consistent
[S390] cio: make disconnected handling consistent
[S390] Fix memory leak in /proc/cio_ignore
[S390] cio: channel path memory leak
[S390] module: fix memory leak in s390 module loader
[S390] Enable kmemleak on s390.
[S390] 3270 console build fix
...
Diffstat (limited to 'arch/s390/lib/delay.c')
-rw-r--r-- | arch/s390/lib/delay.c | 27 |
1 files changed, 16 insertions, 11 deletions
diff --git a/arch/s390/lib/delay.c b/arch/s390/lib/delay.c index 97c1eca83cc2..752b362bf651 100644 --- a/arch/s390/lib/delay.c +++ b/arch/s390/lib/delay.c | |||
@@ -25,13 +25,13 @@ void __delay(unsigned long loops) | |||
25 | asm volatile("0: brct %0,0b" : : "d" ((loops/2) + 1)); | 25 | asm volatile("0: brct %0,0b" : : "d" ((loops/2) + 1)); |
26 | } | 26 | } |
27 | 27 | ||
28 | static void __udelay_disabled(unsigned long usecs) | 28 | static void __udelay_disabled(unsigned long long usecs) |
29 | { | 29 | { |
30 | unsigned long mask, cr0, cr0_saved; | 30 | unsigned long mask, cr0, cr0_saved; |
31 | u64 clock_saved; | 31 | u64 clock_saved; |
32 | 32 | ||
33 | clock_saved = local_tick_disable(); | 33 | clock_saved = local_tick_disable(); |
34 | set_clock_comparator(get_clock() + ((u64) usecs << 12)); | 34 | set_clock_comparator(get_clock() + (usecs << 12)); |
35 | __ctl_store(cr0_saved, 0, 0); | 35 | __ctl_store(cr0_saved, 0, 0); |
36 | cr0 = (cr0_saved & 0xffff00e0) | 0x00000800; | 36 | cr0 = (cr0_saved & 0xffff00e0) | 0x00000800; |
37 | __ctl_load(cr0 , 0, 0); | 37 | __ctl_load(cr0 , 0, 0); |
@@ -46,20 +46,25 @@ static void __udelay_disabled(unsigned long usecs) | |||
46 | set_clock_comparator(S390_lowcore.clock_comparator); | 46 | set_clock_comparator(S390_lowcore.clock_comparator); |
47 | } | 47 | } |
48 | 48 | ||
49 | static void __udelay_enabled(unsigned long usecs) | 49 | static void __udelay_enabled(unsigned long long usecs) |
50 | { | 50 | { |
51 | unsigned long mask; | 51 | unsigned long mask; |
52 | u64 end, time; | 52 | u64 clock_saved; |
53 | u64 end; | ||
53 | 54 | ||
54 | mask = psw_kernel_bits | PSW_MASK_WAIT | PSW_MASK_EXT | PSW_MASK_IO; | 55 | mask = psw_kernel_bits | PSW_MASK_WAIT | PSW_MASK_EXT | PSW_MASK_IO; |
55 | end = get_clock() + ((u64) usecs << 12); | 56 | end = get_clock() + (usecs << 12); |
56 | do { | 57 | do { |
57 | time = end < S390_lowcore.clock_comparator ? | 58 | clock_saved = 0; |
58 | end : S390_lowcore.clock_comparator; | 59 | if (end < S390_lowcore.clock_comparator) { |
59 | set_clock_comparator(time); | 60 | clock_saved = local_tick_disable(); |
61 | set_clock_comparator(end); | ||
62 | } | ||
60 | trace_hardirqs_on(); | 63 | trace_hardirqs_on(); |
61 | __load_psw_mask(mask); | 64 | __load_psw_mask(mask); |
62 | local_irq_disable(); | 65 | local_irq_disable(); |
66 | if (clock_saved) | ||
67 | local_tick_enable(clock_saved); | ||
63 | } while (get_clock() < end); | 68 | } while (get_clock() < end); |
64 | set_clock_comparator(S390_lowcore.clock_comparator); | 69 | set_clock_comparator(S390_lowcore.clock_comparator); |
65 | } | 70 | } |
@@ -67,7 +72,7 @@ static void __udelay_enabled(unsigned long usecs) | |||
67 | /* | 72 | /* |
68 | * Waits for 'usecs' microseconds using the TOD clock comparator. | 73 | * Waits for 'usecs' microseconds using the TOD clock comparator. |
69 | */ | 74 | */ |
70 | void __udelay(unsigned long usecs) | 75 | void __udelay(unsigned long long usecs) |
71 | { | 76 | { |
72 | unsigned long flags; | 77 | unsigned long flags; |
73 | 78 | ||
@@ -101,11 +106,11 @@ EXPORT_SYMBOL(__udelay); | |||
101 | * Simple udelay variant. To be used on startup and reboot | 106 | * Simple udelay variant. To be used on startup and reboot |
102 | * when the interrupt handler isn't working. | 107 | * when the interrupt handler isn't working. |
103 | */ | 108 | */ |
104 | void udelay_simple(unsigned long usecs) | 109 | void udelay_simple(unsigned long long usecs) |
105 | { | 110 | { |
106 | u64 end; | 111 | u64 end; |
107 | 112 | ||
108 | end = get_clock() + ((u64) usecs << 12); | 113 | end = get_clock() + (usecs << 12); |
109 | while (get_clock() < end) | 114 | while (get_clock() < end) |
110 | cpu_relax(); | 115 | cpu_relax(); |
111 | } | 116 | } |