aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/s390/lib/delay.c4
-rw-r--r--drivers/s390/char/sclp.c6
-rw-r--r--include/asm-s390/hardirq.h14
3 files changed, 20 insertions, 4 deletions
diff --git a/arch/s390/lib/delay.c b/arch/s390/lib/delay.c
index eae21a8ac72d..fc6ab6094df8 100644
--- a/arch/s390/lib/delay.c
+++ b/arch/s390/lib/delay.c
@@ -43,7 +43,7 @@ void __udelay(unsigned long usecs)
43 local_bh_disable(); 43 local_bh_disable();
44 local_irq_save(flags); 44 local_irq_save(flags);
45 if (raw_irqs_disabled_flags(flags)) { 45 if (raw_irqs_disabled_flags(flags)) {
46 old_cc = S390_lowcore.clock_comparator; 46 old_cc = local_tick_disable();
47 S390_lowcore.clock_comparator = -1ULL; 47 S390_lowcore.clock_comparator = -1ULL;
48 __ctl_store(cr0, 0, 0); 48 __ctl_store(cr0, 0, 0);
49 dummy = (cr0 & 0xffff00e0) | 0x00000800; 49 dummy = (cr0 & 0xffff00e0) | 0x00000800;
@@ -65,7 +65,7 @@ void __udelay(unsigned long usecs)
65 65
66 if (raw_irqs_disabled_flags(flags)) { 66 if (raw_irqs_disabled_flags(flags)) {
67 __ctl_load(cr0, 0, 0); 67 __ctl_load(cr0, 0, 0);
68 S390_lowcore.clock_comparator = old_cc; 68 local_tick_enable(old_cc);
69 } 69 }
70 if (!irq_context) 70 if (!irq_context)
71 _local_bh_enable(); 71 _local_bh_enable();
diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c
index 3c8b25e6c345..1fd8f2193ed8 100644
--- a/drivers/s390/char/sclp.c
+++ b/drivers/s390/char/sclp.c
@@ -399,6 +399,7 @@ sclp_tod_from_jiffies(unsigned long jiffies)
399void 399void
400sclp_sync_wait(void) 400sclp_sync_wait(void)
401{ 401{
402 unsigned long long old_tick;
402 unsigned long flags; 403 unsigned long flags;
403 unsigned long cr0, cr0_sync; 404 unsigned long cr0, cr0_sync;
404 u64 timeout; 405 u64 timeout;
@@ -419,11 +420,12 @@ sclp_sync_wait(void)
419 if (!irq_context) 420 if (!irq_context)
420 local_bh_disable(); 421 local_bh_disable();
421 /* Enable service-signal interruption, disable timer interrupts */ 422 /* Enable service-signal interruption, disable timer interrupts */
423 old_tick = local_tick_disable();
422 trace_hardirqs_on(); 424 trace_hardirqs_on();
423 __ctl_store(cr0, 0, 0); 425 __ctl_store(cr0, 0, 0);
424 cr0_sync = cr0; 426 cr0_sync = cr0;
427 cr0_sync &= 0xffff00a0;
425 cr0_sync |= 0x00000200; 428 cr0_sync |= 0x00000200;
426 cr0_sync &= 0xFFFFF3AC;
427 __ctl_load(cr0_sync, 0, 0); 429 __ctl_load(cr0_sync, 0, 0);
428 __raw_local_irq_stosm(0x01); 430 __raw_local_irq_stosm(0x01);
429 /* Loop until driver state indicates finished request */ 431 /* Loop until driver state indicates finished request */
@@ -439,9 +441,9 @@ sclp_sync_wait(void)
439 __ctl_load(cr0, 0, 0); 441 __ctl_load(cr0, 0, 0);
440 if (!irq_context) 442 if (!irq_context)
441 _local_bh_enable(); 443 _local_bh_enable();
444 local_tick_enable(old_tick);
442 local_irq_restore(flags); 445 local_irq_restore(flags);
443} 446}
444
445EXPORT_SYMBOL(sclp_sync_wait); 447EXPORT_SYMBOL(sclp_sync_wait);
446 448
447/* Dispatch changes in send and receive mask to registered listeners. */ 449/* Dispatch changes in send and receive mask to registered listeners. */
diff --git a/include/asm-s390/hardirq.h b/include/asm-s390/hardirq.h
index 4b7cb964ff35..89ec7056da28 100644
--- a/include/asm-s390/hardirq.h
+++ b/include/asm-s390/hardirq.h
@@ -34,4 +34,18 @@ typedef struct {
34 34
35void clock_comparator_work(void); 35void clock_comparator_work(void);
36 36
37static inline unsigned long long local_tick_disable(void)
38{
39 unsigned long long old;
40
41 old = S390_lowcore.clock_comparator;
42 S390_lowcore.clock_comparator = -1ULL;
43 return old;
44}
45
46static inline void local_tick_enable(unsigned long long comp)
47{
48 S390_lowcore.clock_comparator = comp;
49}
50
37#endif /* __ASM_HARDIRQ_H */ 51#endif /* __ASM_HARDIRQ_H */