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

Serial 8250: handle saving the clear-on-read bits from the LSR and MSR

Reading the LSR clears the break, parity, frame error, and overrun bits in
the 8250 chip, but these are not being saved in all places that read the
LSR. Same goes for the MSR delta bits. Save the LSR bits off whenever the
lsr is read so they can be handled later in the receive routine. Save the
MSR bits to be handled in the modem status routine.

Also, clear the stored bits and clear the interrupt registers before
enabling interrupts, to avoid handling old values of the stored bits in the
interrupt routines.

[akpm@linux-foundation.org: clean up pre-existing code]
Signed-off-by: Corey Minyard <minyard@acm.org>
Cc: Russell King <rmk+lkml@arm.linux.org.uk>
Cc: Yinghai Lu <yinghai.lu@sun.com>
Cc: Bjorn Helgaas <bjorn.helgaas@hp.com>
Acked-by: Alan Cox <alan@lxorguk.ukuu.org.uk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Corey Minyard and committed by
Linus Torvalds
ad4c2aa6 99999961

+57 -29
+56 -29
drivers/serial/8250.c
··· 129 129 unsigned char mcr; 130 130 unsigned char mcr_mask; /* mask of user bits */ 131 131 unsigned char mcr_force; /* mask of forced bits */ 132 - unsigned char lsr_break_flag; 132 + 133 + /* 134 + * Some bits in registers are cleared on a read, so they must 135 + * be saved whenever the register is read but the bits will not 136 + * be immediately processed. 137 + */ 138 + #define LSR_SAVE_FLAGS UART_LSR_BRK_ERROR_BITS 139 + unsigned char lsr_saved_flags; 140 + #define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA 141 + unsigned char msr_saved_flags; 133 142 134 143 /* 135 144 * We provide a per-port pm hook. ··· 1247 1238 if (up->bugs & UART_BUG_TXEN) { 1248 1239 unsigned char lsr, iir; 1249 1240 lsr = serial_in(up, UART_LSR); 1241 + up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; 1250 1242 iir = serial_in(up, UART_IIR) & 0x0f; 1251 1243 if ((up->port.type == PORT_RM9000) ? 1252 1244 (lsr & UART_LSR_THRE && ··· 1300 1290 flag = TTY_NORMAL; 1301 1291 up->port.icount.rx++; 1302 1292 1303 - #ifdef CONFIG_SERIAL_8250_CONSOLE 1304 - /* 1305 - * Recover the break flag from console xmit 1306 - */ 1307 - if (up->port.line == up->port.cons->index) { 1308 - lsr |= up->lsr_break_flag; 1309 - up->lsr_break_flag = 0; 1310 - } 1311 - #endif 1293 + lsr |= up->lsr_saved_flags; 1294 + up->lsr_saved_flags = 0; 1312 1295 1313 - if (unlikely(lsr & (UART_LSR_BI | UART_LSR_PE | 1314 - UART_LSR_FE | UART_LSR_OE))) { 1296 + if (unlikely(lsr & UART_LSR_BRK_ERROR_BITS)) { 1315 1297 /* 1316 1298 * For statistics only 1317 1299 */ ··· 1394 1392 { 1395 1393 unsigned int status = serial_in(up, UART_MSR); 1396 1394 1395 + status |= up->msr_saved_flags; 1396 + up->msr_saved_flags = 0; 1397 1397 if (status & UART_MSR_ANY_DELTA && up->ier & UART_IER_MSI && 1398 1398 up->port.info != NULL) { 1399 1399 if (status & UART_MSR_TERI) ··· 1595 1591 static void serial8250_backup_timeout(unsigned long data) 1596 1592 { 1597 1593 struct uart_8250_port *up = (struct uart_8250_port *)data; 1598 - unsigned int iir, ier = 0; 1594 + unsigned int iir, ier = 0, lsr; 1595 + unsigned long flags; 1599 1596 1600 1597 /* 1601 1598 * Must disable interrupts or else we risk racing with the interrupt ··· 1615 1610 * the "Diva" UART used on the management processor on many HP 1616 1611 * ia64 and parisc boxes. 1617 1612 */ 1613 + spin_lock_irqsave(&up->port.lock, flags); 1614 + lsr = serial_in(up, UART_LSR); 1615 + up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; 1616 + spin_unlock_irqrestore(&up->port.lock, flags); 1618 1617 if ((iir & UART_IIR_NO_INT) && (up->ier & UART_IER_THRI) && 1619 1618 (!uart_circ_empty(&up->port.info->xmit) || up->port.x_char) && 1620 - (serial_in(up, UART_LSR) & UART_LSR_THRE)) { 1619 + (lsr & UART_LSR_THRE)) { 1621 1620 iir &= ~(UART_IIR_ID | UART_IIR_NO_INT); 1622 1621 iir |= UART_IIR_THRI; 1623 1622 } ··· 1640 1631 { 1641 1632 struct uart_8250_port *up = (struct uart_8250_port *)port; 1642 1633 unsigned long flags; 1643 - unsigned int ret; 1634 + unsigned int lsr; 1644 1635 1645 1636 spin_lock_irqsave(&up->port.lock, flags); 1646 - ret = serial_in(up, UART_LSR) & UART_LSR_TEMT ? TIOCSER_TEMT : 0; 1637 + lsr = serial_in(up, UART_LSR); 1638 + up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; 1647 1639 spin_unlock_irqrestore(&up->port.lock, flags); 1648 1640 1649 - return ret; 1641 + return lsr & UART_LSR_TEMT ? TIOCSER_TEMT : 0; 1650 1642 } 1651 1643 1652 1644 static unsigned int serial8250_get_mctrl(struct uart_port *port) ··· 1718 1708 do { 1719 1709 status = serial_in(up, UART_LSR); 1720 1710 1721 - if (status & UART_LSR_BI) 1722 - up->lsr_break_flag = UART_LSR_BI; 1711 + up->lsr_saved_flags |= status & LSR_SAVE_FLAGS; 1723 1712 1724 1713 if (--tmout == 0) 1725 1714 break; ··· 1727 1718 1728 1719 /* Wait up to 1s for flow control if necessary */ 1729 1720 if (up->port.flags & UPF_CONS_FLOW) { 1730 - tmout = 1000000; 1731 - while (!(serial_in(up, UART_MSR) & UART_MSR_CTS) && --tmout) { 1721 + unsigned int tmout; 1722 + for (tmout = 1000000; tmout; tmout--) { 1723 + unsigned int msr = serial_in(up, UART_MSR); 1724 + up->msr_saved_flags |= msr & MSR_SAVE_FLAGS; 1725 + if (msr & UART_MSR_CTS) 1726 + break; 1732 1727 udelay(1); 1733 1728 touch_nmi_watchdog(); 1734 1729 } ··· 1902 1889 spin_unlock_irqrestore(&up->port.lock, flags); 1903 1890 1904 1891 /* 1892 + * Clear the interrupt registers again for luck, and clear the 1893 + * saved flags to avoid getting false values from polling 1894 + * routines or the previous session. 1895 + */ 1896 + serial_inp(up, UART_LSR); 1897 + serial_inp(up, UART_RX); 1898 + serial_inp(up, UART_IIR); 1899 + serial_inp(up, UART_MSR); 1900 + up->lsr_saved_flags = 0; 1901 + up->msr_saved_flags = 0; 1902 + 1903 + /* 1905 1904 * Finally, enable interrupts. Note: Modem status interrupts 1906 1905 * are set via set_termios(), which will be occurring imminently 1907 1906 * anyway, so we don't enable them here. ··· 1930 1905 outb_p(0x80, icp); 1931 1906 (void) inb_p(icp); 1932 1907 } 1933 - 1934 - /* 1935 - * And clear the interrupt registers again for luck. 1936 - */ 1937 - (void) serial_inp(up, UART_LSR); 1938 - (void) serial_inp(up, UART_RX); 1939 - (void) serial_inp(up, UART_IIR); 1940 - (void) serial_inp(up, UART_MSR); 1941 1908 1942 1909 return 0; 1943 1910 } ··· 2500 2483 */ 2501 2484 wait_for_xmitr(up, BOTH_EMPTY); 2502 2485 serial_out(up, UART_IER, ier); 2486 + 2487 + /* 2488 + * The receive handling will happen properly because the 2489 + * receive ready bit will still be set; it is not cleared 2490 + * on read. However, modem control will not, we must 2491 + * call it if we have saved something in the saved flags 2492 + * while processing with interrupts off. 2493 + */ 2494 + if (up->msr_saved_flags) 2495 + check_modem_status(up); 2503 2496 2504 2497 if (locked) 2505 2498 spin_unlock(&up->port.lock);
+1
include/linux/serial_reg.h
··· 118 118 #define UART_LSR_PE 0x04 /* Parity error indicator */ 119 119 #define UART_LSR_OE 0x02 /* Overrun error indicator */ 120 120 #define UART_LSR_DR 0x01 /* Receiver data ready */ 121 + #define UART_LSR_BRK_ERROR_BITS 0x1E /* BI, FE, PE, OE bits */ 121 122 122 123 #define UART_MSR 6 /* In: Modem Status Register */ 123 124 #define UART_MSR_DCD 0x80 /* Data Carrier Detect */