summaryrefslogtreecommitdiff
path: root/drivers/tty
diff options
context:
space:
mode:
authorPeter Hurley <peter@hurleysoftware.com>2015-01-22 20:24:31 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-02-02 21:11:27 +0300
commite9cef8625e997a5ade9cddd2d501257dfee7cb62 (patch)
treeb76b44f9d048028855a3233e02c1d03515b87676 /drivers/tty
parent4516d50aabedbe5ae334155193e4d35c02390d9a (diff)
downloadlinux-e9cef8625e997a5ade9cddd2d501257dfee7cb62.tar.xz
serial: 8250: Prevent concurrent updates to shadow registers
The port shadow registers, ->fcr and ->mcr, must be protected from concurrent updates. Relocate the shadow register updates in serial8250_do_set_termios() to the port lock critical section. Signed-off-by: Peter Hurley <peter@hurleysoftware.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty')
-rw-r--r--drivers/tty/serial/8250/8250_core.c18
1 files changed, 9 insertions, 9 deletions
diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c
index 1449c56506b7..57d13b058a48 100644
--- a/drivers/tty/serial/8250/8250_core.c
+++ b/drivers/tty/serial/8250/8250_core.c
@@ -2549,6 +2549,15 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
port->uartclk / 16);
quot = serial8250_get_divisor(up, baud, &frac);
+ /*
+ * Ok, we're now changing the port state. Do it with
+ * interrupts disabled.
+ */
+ serial8250_rpm_get(up);
+ spin_lock_irqsave(&port->lock, flags);
+
+ up->lcr = cval; /* Save computed LCR */
+
if (up->capabilities & UART_CAP_FIFO && port->fifosize > 1) {
/* NOTE: If fifo_bug is not set, a user can set RX_trigger. */
if ((baud < 2400 && !up->dma) || up->fifo_bug) {
@@ -2572,15 +2581,6 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
}
/*
- * Ok, we're now changing the port state. Do it with
- * interrupts disabled.
- */
- serial8250_rpm_get(up);
- spin_lock_irqsave(&port->lock, flags);
-
- up->lcr = cval; /* Save computed LCR */
-
- /*
* Update the per-port timeout.
*/
uart_update_timeout(port, termios->c_cflag, baud);