Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

serial: Test/disable MSIs if switching from N_PPS

Switching to the N_PPS line discipline may require enabling
modem status interrupts; conversely switching from N_PPS may
require disabling modem status interrupts.

Affected drivers:
8250
amba-pl010
atmel

Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
Cc: Russell King <linux@arm.linux.org.uk>
Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Peter Hurley and committed by
Greg Kroah-Hartman
cab68f89 d41510ce

+42 -2
+20 -1
drivers/tty/serial/8250/8250_core.c
··· 1402 1402 serial8250_rpm_put(up); 1403 1403 } 1404 1404 1405 + static void serial8250_disable_ms(struct uart_port *port) 1406 + { 1407 + struct uart_8250_port *up = 1408 + container_of(port, struct uart_8250_port, port); 1409 + 1410 + /* no MSR capabilities */ 1411 + if (up->bugs & UART_BUG_NOMSR) 1412 + return; 1413 + 1414 + up->ier &= ~UART_IER_MSI; 1415 + serial_port_out(port, UART_IER, up->ier); 1416 + } 1417 + 1405 1418 static void serial8250_enable_ms(struct uart_port *port) 1406 1419 { 1407 1420 struct uart_8250_port *up = up_to_u8250p(port); ··· 2629 2616 spin_lock_irq(&port->lock); 2630 2617 serial8250_enable_ms(port); 2631 2618 spin_unlock_irq(&port->lock); 2632 - } else 2619 + } else { 2633 2620 port->flags &= ~UPF_HARDPPS_CD; 2621 + if (!UART_ENABLE_MS(port, termios->c_cflag)) { 2622 + spin_lock_irq(&port->lock); 2623 + serial8250_disable_ms(port); 2624 + spin_unlock_irq(&port->lock); 2625 + } 2626 + } 2634 2627 } 2635 2628 2636 2629
+17 -1
drivers/tty/serial/amba-pl010.c
··· 106 106 writel(cr, uap->port.membase + UART010_CR); 107 107 } 108 108 109 + static void pl010_disable_ms(struct uart_port *port) 110 + { 111 + struct uart_amba_port *uap = (struct uart_amba_port *)port; 112 + unsigned int cr; 113 + 114 + cr = readb(uap->port.membase + UART010_CR); 115 + cr &= ~UART010_CR_MSIE; 116 + writel(cr, uap->port.membase + UART010_CR); 117 + } 118 + 109 119 static void pl010_enable_ms(struct uart_port *port) 110 120 { 111 121 struct uart_amba_port *uap = ··· 496 486 spin_lock_irq(&port->lock); 497 487 pl010_enable_ms(port); 498 488 spin_unlock_irq(&port->lock); 499 - } else 489 + } else { 500 490 port->flags &= ~UPF_HARDPPS_CD; 491 + if (!UART_ENABLE_MS(port, termios->c_cflag)) { 492 + spin_lock_irq(&port->lock); 493 + pl010_disable_ms(port); 494 + spin_unlock_irq(&port->lock); 495 + } 496 + } 501 497 } 502 498 503 499 static const char *pl010_type(struct uart_port *port)
+5
drivers/tty/serial/atmel_serial.c
··· 2065 2065 spin_unlock_irq(&port->lock); 2066 2066 } else { 2067 2067 port->flags &= ~UPF_HARDPPS_CD; 2068 + if (!UART_ENABLE_MS(port, termios->c_cflag)) { 2069 + spin_lock_irq(&port->lock); 2070 + atmel_disable_ms(port); 2071 + spin_unlock_irq(&port->lock); 2072 + } 2068 2073 } 2069 2074 } 2070 2075