struct sc16is7xx_one {
        struct uart_port                port;
-       struct work_struct              tx_work;
+       struct kthread_work             tx_work;
        struct work_struct              md_work;
 };
 
        struct uart_driver              uart;
        struct sc16is7xx_devtype        *devtype;
        struct regmap                   *regmap;
-       struct mutex                    mutex;
        struct clk                      *clk;
 #ifdef CONFIG_GPIOLIB
        struct gpio_chip                gpio;
 #endif
        unsigned char                   buf[SC16IS7XX_FIFO_SIZE];
+       struct kthread_worker           kworker;
+       struct task_struct              *kworker_task;
+       struct kthread_work             irq_work;
        struct sc16is7xx_one            p[0];
 };
 
+#define to_sc16is7xx_port(p,e) ((container_of((p), struct sc16is7xx_port, e)))
 #define to_sc16is7xx_one(p,e)  ((container_of((p), struct sc16is7xx_one, e)))
 
 static u8 sc16is7xx_port_read(struct uart_port *port, u8 reg)
                                               !!(msr & SC16IS7XX_MSR_CTS_BIT));
                        break;
                case SC16IS7XX_IIR_THRI_SRC:
-                       mutex_lock(&s->mutex);
                        sc16is7xx_handle_tx(port);
-                       mutex_unlock(&s->mutex);
                        break;
                default:
                        dev_err_ratelimited(port->dev,
        } while (1);
 }
 
-static irqreturn_t sc16is7xx_ist(int irq, void *dev_id)
+static void sc16is7xx_ist(struct kthread_work *ws)
 {
-       struct sc16is7xx_port *s = (struct sc16is7xx_port *)dev_id;
+       struct sc16is7xx_port *s = to_sc16is7xx_port(ws, irq_work);
        int i;
 
        for (i = 0; i < s->uart.nr; ++i)
                sc16is7xx_port_irq(s, i);
+}
+
+static irqreturn_t sc16is7xx_irq(int irq, void *dev_id)
+{
+       struct sc16is7xx_port *s = (struct sc16is7xx_port *)dev_id;
+
+       queue_kthread_work(&s->kworker, &s->irq_work);
 
        return IRQ_HANDLED;
 }
 
-static void sc16is7xx_wq_proc(struct work_struct *ws)
+static void sc16is7xx_tx_proc(struct kthread_work *ws)
 {
        struct sc16is7xx_one *one = to_sc16is7xx_one(ws, tx_work);
-       struct sc16is7xx_port *s = dev_get_drvdata(one->port.dev);
 
-       mutex_lock(&s->mutex);
        sc16is7xx_handle_tx(&one->port);
-       mutex_unlock(&s->mutex);
 }
 
 static void sc16is7xx_stop_tx(struct uart_port* port)
 
 static void sc16is7xx_start_tx(struct uart_port *port)
 {
+       struct sc16is7xx_port *s = dev_get_drvdata(port->dev);
        struct sc16is7xx_one *one = to_sc16is7xx_one(port, port);
 
        /* handle rs485 */
                mdelay(port->rs485.delay_rts_before_send);
        }
 
-       if (!work_pending(&one->tx_work))
-               schedule_work(&one->tx_work);
+       queue_kthread_work(&s->kworker, &one->tx_work);
 }
 
 static unsigned int sc16is7xx_tx_empty(struct uart_port *port)
 
 static void sc16is7xx_shutdown(struct uart_port *port)
 {
+       struct sc16is7xx_port *s = dev_get_drvdata(port->dev);
+
        /* Disable all interrupts */
        sc16is7xx_port_write(port, SC16IS7XX_IER_REG, 0);
        /* Disable TX/RX */
                              SC16IS7XX_EFCR_TXDISABLE_BIT);
 
        sc16is7xx_power(port, 0);
+
+       flush_kthread_worker(&s->kworker);
 }
 
 static const char *sc16is7xx_type(struct uart_port *port)
                           struct sc16is7xx_devtype *devtype,
                           struct regmap *regmap, int irq, unsigned long flags)
 {
+       struct sched_param sched_param = { .sched_priority = MAX_RT_PRIO / 2 };
        unsigned long freq, *pfreq = dev_get_platdata(dev);
        int i, ret;
        struct sc16is7xx_port *s;
                goto out_clk;
        }
 
+       init_kthread_worker(&s->kworker);
+       init_kthread_work(&s->irq_work, sc16is7xx_ist);
+       s->kworker_task = kthread_run(kthread_worker_fn, &s->kworker,
+                                     "sc16is7xx");
+       if (IS_ERR(s->kworker_task)) {
+               ret = PTR_ERR(s->kworker_task);
+               goto out_uart;
+       }
+       sched_setscheduler(s->kworker_task, SCHED_FIFO, &sched_param);
+
 #ifdef CONFIG_GPIOLIB
        if (devtype->nr_gpio) {
                /* Setup GPIO cotroller */
                s->gpio.can_sleep        = 1;
                ret = gpiochip_add(&s->gpio);
                if (ret)
-                       goto out_uart;
+                       goto out_thread;
        }
 #endif
 
-       mutex_init(&s->mutex);
-
        for (i = 0; i < devtype->nr_uart; ++i) {
                /* Initialize port data */
                s->p[i].port.line       = i;
                                     SC16IS7XX_EFCR_RXDISABLE_BIT |
                                     SC16IS7XX_EFCR_TXDISABLE_BIT);
                /* Initialize queue for start TX */
-               INIT_WORK(&s->p[i].tx_work, sc16is7xx_wq_proc);
+               init_kthread_work(&s->p[i].tx_work, sc16is7xx_tx_proc);
                /* Initialize queue for changing mode */
                INIT_WORK(&s->p[i].md_work, sc16is7xx_md_proc);
                /* Register port */
        }
 
        /* Setup interrupt */
-       ret = devm_request_threaded_irq(dev, irq, NULL, sc16is7xx_ist,
-                                       IRQF_ONESHOT | flags, dev_name(dev), s);
+       ret = devm_request_irq(dev, irq, sc16is7xx_irq,
+                              IRQF_ONESHOT | flags, dev_name(dev), s);
        if (!ret)
                return 0;
 
        for (i = 0; i < s->uart.nr; i++)
                uart_remove_one_port(&s->uart, &s->p[i].port);
 
-       mutex_destroy(&s->mutex);
-
 #ifdef CONFIG_GPIOLIB
        if (devtype->nr_gpio)
                gpiochip_remove(&s->gpio);
 
-out_uart:
+out_thread:
 #endif
+       kthread_stop(s->kworker_task);
+
+out_uart:
        uart_unregister_driver(&s->uart);
 
 out_clk:
 #endif
 
        for (i = 0; i < s->uart.nr; i++) {
-               cancel_work_sync(&s->p[i].tx_work);
                cancel_work_sync(&s->p[i].md_work);
                uart_remove_one_port(&s->uart, &s->p[i].port);
                sc16is7xx_power(&s->p[i].port, 0);
        }
 
-       mutex_destroy(&s->mutex);
+       flush_kthread_worker(&s->kworker);
+       kthread_stop(s->kworker_task);
+
        uart_unregister_driver(&s->uart);
        if (!IS_ERR(s->clk))
                clk_disable_unprepare(s->clk);