diff options
author | Jakub Kicinski <kubakici@wp.pl> | 2015-05-29 22:20:32 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2015-06-01 00:47:27 +0300 |
commit | 059d5815304bdbe440d0ffc957d832aebf076ca3 (patch) | |
tree | a826710893d6d52676f92176f559e9008425fbda /drivers/tty/serial/sc16is7xx.c | |
parent | a0104085362ff90438151e3b96513900a274d241 (diff) | |
download | linux-059d5815304bdbe440d0ffc957d832aebf076ca3.tar.xz |
sc16is7xx: use kworker to update ier bits
.stop_rx/tx() are called in atomic context, we cannot use
blocking I/O. While at it correct the name of RX bit and
'*' placement in pointer declarations.
Signed-off-by: Jakub Kicinski <kubakici@wp.pl>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/serial/sc16is7xx.c')
-rw-r--r-- | drivers/tty/serial/sc16is7xx.c | 29 |
1 files changed, 19 insertions, 10 deletions
diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c index f218e24463c9..86a679a5870b 100644 --- a/drivers/tty/serial/sc16is7xx.c +++ b/drivers/tty/serial/sc16is7xx.c @@ -302,9 +302,11 @@ struct sc16is7xx_devtype { }; #define SC16IS7XX_RECONF_MD (1 << 0) +#define SC16IS7XX_RECONF_IER (1 << 1) struct sc16is7xx_one_config { unsigned int flags; + u8 ier_clear; }; struct sc16is7xx_one { @@ -682,23 +684,30 @@ static void sc16is7xx_reg_proc(struct kthread_work *ws) SC16IS7XX_MCR_LOOP_BIT, (one->port.mctrl & TIOCM_LOOP) ? SC16IS7XX_MCR_LOOP_BIT : 0); + + if (config.flags & SC16IS7XX_RECONF_IER) + sc16is7xx_port_update(&one->port, SC16IS7XX_IER_REG, + config.ier_clear, 0); } -static void sc16is7xx_stop_tx(struct uart_port* port) +static void sc16is7xx_ier_clear(struct uart_port *port, u8 bit) { - sc16is7xx_port_update(port, SC16IS7XX_IER_REG, - SC16IS7XX_IER_THRI_BIT, - 0); + struct sc16is7xx_port *s = dev_get_drvdata(port->dev); + struct sc16is7xx_one *one = to_sc16is7xx_one(port, port); + + one->config.flags |= SC16IS7XX_RECONF_IER; + one->config.ier_clear |= bit; + queue_kthread_work(&s->kworker, &one->reg_work); } -static void sc16is7xx_stop_rx(struct uart_port* port) +static void sc16is7xx_stop_tx(struct uart_port *port) { - struct sc16is7xx_one *one = to_sc16is7xx_one(port, port); + sc16is7xx_ier_clear(port, SC16IS7XX_IER_THRI_BIT); +} - one->port.read_status_mask &= ~SC16IS7XX_LSR_DR_BIT; - sc16is7xx_port_update(port, SC16IS7XX_IER_REG, - SC16IS7XX_LSR_DR_BIT, - 0); +static void sc16is7xx_stop_rx(struct uart_port *port) +{ + sc16is7xx_ier_clear(port, SC16IS7XX_IER_RDI_BIT); } static void sc16is7xx_start_tx(struct uart_port *port) |