aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/lib/delay.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/lib/delay.c')
-rw-r--r--arch/s390/lib/delay.c31
1 files changed, 14 insertions, 17 deletions
diff --git a/arch/s390/lib/delay.c b/arch/s390/lib/delay.c
index db92f044024c..9f1f71e85778 100644
--- a/arch/s390/lib/delay.c
+++ b/arch/s390/lib/delay.c
@@ -13,6 +13,7 @@
13#include <linux/irqflags.h> 13#include <linux/irqflags.h>
14#include <linux/interrupt.h> 14#include <linux/interrupt.h>
15#include <asm/div64.h> 15#include <asm/div64.h>
16#include <asm/timer.h>
16 17
17void __delay(unsigned long loops) 18void __delay(unsigned long loops)
18{ 19{
@@ -28,36 +29,33 @@ void __delay(unsigned long loops)
28 29
29static void __udelay_disabled(unsigned long long usecs) 30static void __udelay_disabled(unsigned long long usecs)
30{ 31{
31 unsigned long mask, cr0, cr0_saved; 32 unsigned long cr0, cr6, new;
32 u64 clock_saved; 33 u64 clock_saved, end;
33 u64 end;
34 34
35 mask = psw_kernel_bits | PSW_MASK_DAT | PSW_MASK_WAIT |
36 PSW_MASK_EXT | PSW_MASK_MCHECK;
37 end = get_clock() + (usecs << 12); 35 end = get_clock() + (usecs << 12);
38 clock_saved = local_tick_disable(); 36 clock_saved = local_tick_disable();
39 __ctl_store(cr0_saved, 0, 0); 37 __ctl_store(cr0, 0, 0);
40 cr0 = (cr0_saved & 0xffff00e0) | 0x00000800; 38 __ctl_store(cr6, 6, 6);
41 __ctl_load(cr0 , 0, 0); 39 new = (cr0 & 0xffff00e0) | 0x00000800;
40 __ctl_load(new , 0, 0);
41 new = 0;
42 __ctl_load(new, 6, 6);
42 lockdep_off(); 43 lockdep_off();
43 do { 44 do {
44 set_clock_comparator(end); 45 set_clock_comparator(end);
45 trace_hardirqs_on(); 46 vtime_stop_cpu();
46 __load_psw_mask(mask);
47 local_irq_disable(); 47 local_irq_disable();
48 } while (get_clock() < end); 48 } while (get_clock() < end);
49 lockdep_on(); 49 lockdep_on();
50 __ctl_load(cr0_saved, 0, 0); 50 __ctl_load(cr0, 0, 0);
51 __ctl_load(cr6, 6, 6);
51 local_tick_enable(clock_saved); 52 local_tick_enable(clock_saved);
52} 53}
53 54
54static void __udelay_enabled(unsigned long long usecs) 55static void __udelay_enabled(unsigned long long usecs)
55{ 56{
56 unsigned long mask; 57 u64 clock_saved, end;
57 u64 clock_saved;
58 u64 end;
59 58
60 mask = psw_kernel_bits | PSW_MASK_WAIT | PSW_MASK_EXT | PSW_MASK_IO;
61 end = get_clock() + (usecs << 12); 59 end = get_clock() + (usecs << 12);
62 do { 60 do {
63 clock_saved = 0; 61 clock_saved = 0;
@@ -65,8 +63,7 @@ static void __udelay_enabled(unsigned long long usecs)
65 clock_saved = local_tick_disable(); 63 clock_saved = local_tick_disable();
66 set_clock_comparator(end); 64 set_clock_comparator(end);
67 } 65 }
68 trace_hardirqs_on(); 66 vtime_stop_cpu();
69 __load_psw_mask(mask);
70 local_irq_disable(); 67 local_irq_disable();
71 if (clock_saved) 68 if (clock_saved)
72 local_tick_enable(clock_saved); 69 local_tick_enable(clock_saved);