diff options
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 | } |