diff -ruPN a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c
--- a/drivers/tty/n_tty.c	2015-08-17 05:52:51.000000000 +0200
+++ b/drivers/tty/n_tty.c	2015-08-28 08:31:43.690718910 +0200
@@ -201,7 +201,7 @@
 		 */
 		WARN_RATELIMIT(test_bit(TTY_LDISC_HALTED, &tty->flags),
 			       "scheduling buffer work for halted ldisc\n");
-		queue_work(system_unbound_wq, &tty->port->buf.work);
+		tty_buffer_queue_work(tty->port);
 	}
 }
 
diff -ruPN a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c
--- a/drivers/tty/tty_buffer.c	2015-08-17 05:52:51.000000000 +0200
+++ b/drivers/tty/tty_buffer.c	2015-08-28 09:13:56.604475262 +0200
@@ -4,6 +4,7 @@
 
 #include <linux/types.h>
 #include <linux/errno.h>
+#include <linux/kthread.h>
 #include <linux/tty.h>
 #include <linux/tty_driver.h>
 #include <linux/tty_flip.h>
@@ -11,6 +12,7 @@
 #include <linux/string.h>
 #include <linux/slab.h>
 #include <linux/sched.h>
+#include <linux/sched/prio.h>
 #include <linux/wait.h>
 #include <linux/bitops.h>
 #include <linux/delay.h>
@@ -94,7 +96,7 @@
 	atomic_dec(&buf->priority);
 	mutex_unlock(&buf->lock);
 	if (restart)
-		queue_work(system_unbound_wq, &buf->work);
+		tty_buffer_queue_work(port);
 }
 EXPORT_SYMBOL_GPL(tty_buffer_unlock_exclusive);
 
@@ -394,7 +396,7 @@
 	struct tty_bufhead *buf = &port->buf;
 
 	buf->tail->commit = buf->tail->used;
-	schedule_work(&buf->work);
+	tty_buffer_queue_work(port);
 }
 EXPORT_SYMBOL(tty_schedule_flip);
 
@@ -461,7 +463,7 @@
  *		 'consumer'
  */
 
-static void flush_to_ldisc(struct work_struct *work)
+static void flush_to_ldisc(struct kthread_work *work)
 {
 	struct tty_port *port = container_of(work, struct tty_port, buf.work);
 	struct tty_bufhead *buf = &port->buf;
@@ -531,6 +533,33 @@
 }
 EXPORT_SYMBOL(tty_flip_buffer_push);
 
+static DEFINE_KTHREAD_WORKER(tty_buffer_worker);
+static DEFINE_KTHREAD_WORKER(tty_buffer_worker_ll);
+
+void tty_buffer_init_kthread()
+{
+	struct task_struct *task;
+	struct sched_param param = { .sched_priority = MAX_USER_RT_PRIO/4 };
+
+ 	kthread_run(kthread_worker_fn, &tty_buffer_worker, "tty");
+	task = kthread_run(kthread_worker_fn, &tty_buffer_worker_ll,
+			   "tty-low-latency");
+	sched_setscheduler(task, SCHED_FIFO, &param);
+}
+
+void tty_buffer_queue_work(struct tty_port *port)
+{
+	if (port->low_latency)
+		queue_kthread_work(&tty_buffer_worker_ll, &port->buf.work);
+	else
+		queue_kthread_work(&tty_buffer_worker, &port->buf.work);
+}
+
+void tty_buffer_flush_work(struct tty_port *port)
+{
+	flush_kthread_work(&port->buf.work);
+}
+
 /**
  *	tty_buffer_init		-	prepare a tty buffer structure
  *	@tty: tty to initialise
@@ -550,7 +579,7 @@
 	init_llist_head(&buf->free);
 	atomic_set(&buf->mem_used, 0);
 	atomic_set(&buf->priority, 0);
-	INIT_WORK(&buf->work, flush_to_ldisc);
+	init_kthread_work(&buf->work, flush_to_ldisc);
 	buf->mem_limit = TTYB_DEFAULT_MEM_LIMIT;
 }
 
diff -ruPN a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
--- a/drivers/tty/tty_io.c	2015-08-17 05:52:51.000000000 +0200
+++ b/drivers/tty/tty_io.c	2015-08-28 08:47:18.044489672 +0200
@@ -1698,7 +1698,7 @@
 	tty->port->itty = NULL;
 	if (tty->link)
 		tty->link->port->itty = NULL;
-	cancel_work_sync(&tty->port->buf.work);
+	tty_buffer_flush_work(tty->port);
 
 	tty_kref_put(tty->link);
 	tty_kref_put(tty);
@@ -3669,6 +3669,7 @@
  */
 int __init tty_init(void)
 {
+  tty_buffer_init_kthread();
 	cdev_init(&tty_cdev, &tty_fops);
 	if (cdev_add(&tty_cdev, MKDEV(TTYAUX_MAJOR, 0), 1) ||
 	    register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0)
diff -ruPN a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c
--- a/drivers/tty/tty_ldisc.c	2015-08-17 05:52:51.000000000 +0200
+++ b/drivers/tty/tty_ldisc.c	2015-08-28 08:39:53.340493681 +0200
@@ -593,7 +593,7 @@
 
 	/* Restart the work queue in case no characters kick it off. Safe if
 	   already running */
-	schedule_work(&tty->port->buf.work);
+	tty_buffer_queue_work(tty->port);
 
 	tty_unlock(tty);
 	return retval;
diff -ruPN a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c
--- a/drivers/tty/tty_port.c	2015-08-17 05:52:51.000000000 +0200
+++ b/drivers/tty/tty_port.c	2015-08-28 08:48:27.852489043 +0200
@@ -131,7 +131,7 @@
  */
 void tty_port_destroy(struct tty_port *port)
 {
-	cancel_work_sync(&port->buf.work);
+	tty_buffer_flush_work(port);
 	tty_buffer_free_all(port);
 }
 EXPORT_SYMBOL(tty_port_destroy);
diff -ruPN a/include/linux/tty.h b/include/linux/tty.h
--- a/include/linux/tty.h	2015-08-17 05:52:51.000000000 +0200
+++ b/include/linux/tty.h	2015-08-28 08:49:52.368488281 +0200
@@ -3,8 +3,8 @@
 
 #include <linux/fs.h>
 #include <linux/major.h>
+#include <linux/kthread.h>
 #include <linux/termios.h>
-#include <linux/workqueue.h>
 #include <linux/tty_driver.h>
 #include <linux/tty_ldisc.h>
 #include <linux/mutex.h>
@@ -82,7 +82,7 @@
 
 struct tty_bufhead {
 	struct tty_buffer *head;	/* Queue head */
-	struct work_struct work;
+	struct kthread_work work;
 	struct mutex	   lock;
 	atomic_t	   priority;
 	struct tty_buffer sentinel;
@@ -466,6 +466,9 @@
 extern void tty_buffer_free_all(struct tty_port *port);
 extern void tty_buffer_flush(struct tty_struct *tty, struct tty_ldisc *ld);
 extern void tty_buffer_init(struct tty_port *port);
+extern void tty_buffer_queue_work(struct tty_port *port);
+extern void tty_buffer_flush_work(struct tty_port *port);
+extern void tty_buffer_init_kthread(void);
 extern void tty_buffer_set_lock_subclass(struct tty_port *port);
 extern speed_t tty_termios_baud_rate(struct ktermios *termios);
 extern speed_t tty_termios_input_baud_rate(struct ktermios *termios);
