diff options
| -rw-r--r-- | arch/s390/kernel/process.c | 5 | ||||
| -rw-r--r-- | arch/s390/kernel/time.c | 7 | ||||
| -rw-r--r-- | arch/s390/mm/pgtable.c | 2 | ||||
| -rw-r--r-- | drivers/s390/char/con3215.c | 22 |
4 files changed, 24 insertions, 12 deletions
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index 3201ae447990..4261aa799774 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c | |||
| @@ -76,7 +76,6 @@ static void default_idle(void) | |||
| 76 | if (test_thread_flag(TIF_MCCK_PENDING)) { | 76 | if (test_thread_flag(TIF_MCCK_PENDING)) { |
| 77 | local_mcck_enable(); | 77 | local_mcck_enable(); |
| 78 | local_irq_enable(); | 78 | local_irq_enable(); |
| 79 | s390_handle_mcck(); | ||
| 80 | return; | 79 | return; |
| 81 | } | 80 | } |
| 82 | trace_hardirqs_on(); | 81 | trace_hardirqs_on(); |
| @@ -93,10 +92,12 @@ void cpu_idle(void) | |||
| 93 | for (;;) { | 92 | for (;;) { |
| 94 | tick_nohz_idle_enter(); | 93 | tick_nohz_idle_enter(); |
| 95 | rcu_idle_enter(); | 94 | rcu_idle_enter(); |
| 96 | while (!need_resched()) | 95 | while (!need_resched() && !test_thread_flag(TIF_MCCK_PENDING)) |
| 97 | default_idle(); | 96 | default_idle(); |
| 98 | rcu_idle_exit(); | 97 | rcu_idle_exit(); |
| 99 | tick_nohz_idle_exit(); | 98 | tick_nohz_idle_exit(); |
| 99 | if (test_thread_flag(TIF_MCCK_PENDING)) | ||
| 100 | s390_handle_mcck(); | ||
| 100 | preempt_enable_no_resched(); | 101 | preempt_enable_no_resched(); |
| 101 | schedule(); | 102 | schedule(); |
| 102 | preempt_disable(); | 103 | preempt_disable(); |
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index fa02f443f5f6..14da278febbf 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c | |||
| @@ -113,11 +113,14 @@ static void fixup_clock_comparator(unsigned long long delta) | |||
| 113 | static int s390_next_ktime(ktime_t expires, | 113 | static int s390_next_ktime(ktime_t expires, |
| 114 | struct clock_event_device *evt) | 114 | struct clock_event_device *evt) |
| 115 | { | 115 | { |
| 116 | struct timespec ts; | ||
| 116 | u64 nsecs; | 117 | u64 nsecs; |
| 117 | 118 | ||
| 118 | nsecs = ktime_to_ns(ktime_sub(expires, ktime_get_monotonic_offset())); | 119 | ts.tv_sec = ts.tv_nsec = 0; |
| 120 | monotonic_to_bootbased(&ts); | ||
| 121 | nsecs = ktime_to_ns(ktime_add(timespec_to_ktime(ts), expires)); | ||
| 119 | do_div(nsecs, 125); | 122 | do_div(nsecs, 125); |
| 120 | S390_lowcore.clock_comparator = TOD_UNIX_EPOCH + (nsecs << 9); | 123 | S390_lowcore.clock_comparator = sched_clock_base_cc + (nsecs << 9); |
| 121 | set_clock_comparator(S390_lowcore.clock_comparator); | 124 | set_clock_comparator(S390_lowcore.clock_comparator); |
| 122 | return 0; | 125 | return 0; |
| 123 | } | 126 | } |
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index 9a4d02f64f16..51b0738e13d1 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c | |||
| @@ -574,7 +574,7 @@ static inline void page_table_free_pgste(unsigned long *table) | |||
| 574 | page = pfn_to_page(__pa(table) >> PAGE_SHIFT); | 574 | page = pfn_to_page(__pa(table) >> PAGE_SHIFT); |
| 575 | mp = (struct gmap_pgtable *) page->index; | 575 | mp = (struct gmap_pgtable *) page->index; |
| 576 | BUG_ON(!list_empty(&mp->mapper)); | 576 | BUG_ON(!list_empty(&mp->mapper)); |
| 577 | pgtable_page_ctor(page); | 577 | pgtable_page_dtor(page); |
| 578 | atomic_set(&page->_mapcount, -1); | 578 | atomic_set(&page->_mapcount, -1); |
| 579 | kfree(mp); | 579 | kfree(mp); |
| 580 | __free_page(page); | 580 | __free_page(page); |
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c index 934458ad55e5..e71a50d4b221 100644 --- a/drivers/s390/char/con3215.c +++ b/drivers/s390/char/con3215.c | |||
| @@ -87,6 +87,7 @@ struct raw3215_info { | |||
| 87 | struct tty_struct *tty; /* pointer to tty structure if present */ | 87 | struct tty_struct *tty; /* pointer to tty structure if present */ |
| 88 | struct raw3215_req *queued_read; /* pointer to queued read requests */ | 88 | struct raw3215_req *queued_read; /* pointer to queued read requests */ |
| 89 | struct raw3215_req *queued_write;/* pointer to queued write requests */ | 89 | struct raw3215_req *queued_write;/* pointer to queued write requests */ |
| 90 | struct tasklet_struct tlet; /* tasklet to invoke tty_wakeup */ | ||
| 90 | wait_queue_head_t empty_wait; /* wait queue for flushing */ | 91 | wait_queue_head_t empty_wait; /* wait queue for flushing */ |
| 91 | struct timer_list timer; /* timer for delayed output */ | 92 | struct timer_list timer; /* timer for delayed output */ |
| 92 | int line_pos; /* position on the line (for tabs) */ | 93 | int line_pos; /* position on the line (for tabs) */ |
| @@ -334,19 +335,23 @@ static inline void raw3215_try_io(struct raw3215_info *raw) | |||
| 334 | } | 335 | } |
| 335 | 336 | ||
| 336 | /* | 337 | /* |
| 338 | * Call tty_wakeup from tasklet context | ||
| 339 | */ | ||
| 340 | static void raw3215_wakeup(unsigned long data) | ||
| 341 | { | ||
| 342 | struct raw3215_info *raw = (struct raw3215_info *) data; | ||
| 343 | tty_wakeup(raw->tty); | ||
| 344 | } | ||
| 345 | |||
| 346 | /* | ||
| 337 | * Try to start the next IO and wake up processes waiting on the tty. | 347 | * Try to start the next IO and wake up processes waiting on the tty. |
| 338 | */ | 348 | */ |
| 339 | static void raw3215_next_io(struct raw3215_info *raw) | 349 | static void raw3215_next_io(struct raw3215_info *raw) |
| 340 | { | 350 | { |
| 341 | struct tty_struct *tty; | ||
| 342 | |||
| 343 | raw3215_mk_write_req(raw); | 351 | raw3215_mk_write_req(raw); |
| 344 | raw3215_try_io(raw); | 352 | raw3215_try_io(raw); |
| 345 | tty = raw->tty; | 353 | if (raw->tty && RAW3215_BUFFER_SIZE - raw->count >= RAW3215_MIN_SPACE) |
| 346 | if (tty != NULL && | 354 | tasklet_schedule(&raw->tlet); |
| 347 | RAW3215_BUFFER_SIZE - raw->count >= RAW3215_MIN_SPACE) { | ||
| 348 | tty_wakeup(tty); | ||
| 349 | } | ||
| 350 | } | 355 | } |
| 351 | 356 | ||
| 352 | /* | 357 | /* |
| @@ -682,6 +687,7 @@ static int raw3215_probe (struct ccw_device *cdev) | |||
| 682 | return -ENOMEM; | 687 | return -ENOMEM; |
| 683 | } | 688 | } |
| 684 | init_waitqueue_head(&raw->empty_wait); | 689 | init_waitqueue_head(&raw->empty_wait); |
| 690 | tasklet_init(&raw->tlet, raw3215_wakeup, (unsigned long) raw); | ||
| 685 | 691 | ||
| 686 | dev_set_drvdata(&cdev->dev, raw); | 692 | dev_set_drvdata(&cdev->dev, raw); |
| 687 | cdev->handler = raw3215_irq; | 693 | cdev->handler = raw3215_irq; |
| @@ -901,6 +907,7 @@ static int __init con3215_init(void) | |||
| 901 | 907 | ||
| 902 | raw->flags |= RAW3215_FIXED; | 908 | raw->flags |= RAW3215_FIXED; |
| 903 | init_waitqueue_head(&raw->empty_wait); | 909 | init_waitqueue_head(&raw->empty_wait); |
| 910 | tasklet_init(&raw->tlet, raw3215_wakeup, (unsigned long) raw); | ||
| 904 | 911 | ||
| 905 | /* Request the console irq */ | 912 | /* Request the console irq */ |
| 906 | if (raw3215_startup(raw) != 0) { | 913 | if (raw3215_startup(raw) != 0) { |
| @@ -966,6 +973,7 @@ static void tty3215_close(struct tty_struct *tty, struct file * filp) | |||
| 966 | tty->closing = 1; | 973 | tty->closing = 1; |
| 967 | /* Shutdown the terminal */ | 974 | /* Shutdown the terminal */ |
| 968 | raw3215_shutdown(raw); | 975 | raw3215_shutdown(raw); |
| 976 | tasklet_kill(&raw->tlet); | ||
| 969 | tty->closing = 0; | 977 | tty->closing = 0; |
| 970 | raw->tty = NULL; | 978 | raw->tty = NULL; |
| 971 | } | 979 | } |
