diff options
-rw-r--r-- | drivers/serial/8250.c | 85 | ||||
-rw-r--r-- | include/linux/serial_reg.h | 1 |
2 files changed, 57 insertions, 29 deletions
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index 301313002f6b..f94109cbb46e 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c | |||
@@ -129,7 +129,16 @@ struct uart_8250_port { | |||
129 | unsigned char mcr; | 129 | unsigned char mcr; |
130 | unsigned char mcr_mask; /* mask of user bits */ | 130 | unsigned char mcr_mask; /* mask of user bits */ |
131 | unsigned char mcr_force; /* mask of forced bits */ | 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 | * We provide a per-port pm hook. | 144 | * We provide a per-port pm hook. |
@@ -1238,6 +1247,7 @@ static void serial8250_start_tx(struct uart_port *port) | |||
1238 | if (up->bugs & UART_BUG_TXEN) { | 1247 | if (up->bugs & UART_BUG_TXEN) { |
1239 | unsigned char lsr, iir; | 1248 | unsigned char lsr, iir; |
1240 | lsr = serial_in(up, UART_LSR); | 1249 | lsr = serial_in(up, UART_LSR); |
1250 | up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; | ||
1241 | iir = serial_in(up, UART_IIR) & 0x0f; | 1251 | iir = serial_in(up, UART_IIR) & 0x0f; |
1242 | if ((up->port.type == PORT_RM9000) ? | 1252 | if ((up->port.type == PORT_RM9000) ? |
1243 | (lsr & UART_LSR_THRE && | 1253 | (lsr & UART_LSR_THRE && |
@@ -1290,18 +1300,10 @@ receive_chars(struct uart_8250_port *up, unsigned int *status) | |||
1290 | flag = TTY_NORMAL; | 1300 | flag = TTY_NORMAL; |
1291 | up->port.icount.rx++; | 1301 | up->port.icount.rx++; |
1292 | 1302 | ||
1293 | #ifdef CONFIG_SERIAL_8250_CONSOLE | 1303 | lsr |= up->lsr_saved_flags; |
1294 | /* | 1304 | up->lsr_saved_flags = 0; |
1295 | * Recover the break flag from console xmit | ||
1296 | */ | ||
1297 | if (up->port.line == up->port.cons->index) { | ||
1298 | lsr |= up->lsr_break_flag; | ||
1299 | up->lsr_break_flag = 0; | ||
1300 | } | ||
1301 | #endif | ||
1302 | 1305 | ||
1303 | if (unlikely(lsr & (UART_LSR_BI | UART_LSR_PE | | 1306 | if (unlikely(lsr & UART_LSR_BRK_ERROR_BITS)) { |
1304 | UART_LSR_FE | UART_LSR_OE))) { | ||
1305 | /* | 1307 | /* |
1306 | * For statistics only | 1308 | * For statistics only |
1307 | */ | 1309 | */ |
@@ -1392,6 +1394,8 @@ static unsigned int check_modem_status(struct uart_8250_port *up) | |||
1392 | { | 1394 | { |
1393 | unsigned int status = serial_in(up, UART_MSR); | 1395 | unsigned int status = serial_in(up, UART_MSR); |
1394 | 1396 | ||
1397 | status |= up->msr_saved_flags; | ||
1398 | up->msr_saved_flags = 0; | ||
1395 | if (status & UART_MSR_ANY_DELTA && up->ier & UART_IER_MSI && | 1399 | if (status & UART_MSR_ANY_DELTA && up->ier & UART_IER_MSI && |
1396 | up->port.info != NULL) { | 1400 | up->port.info != NULL) { |
1397 | if (status & UART_MSR_TERI) | 1401 | if (status & UART_MSR_TERI) |
@@ -1591,7 +1595,8 @@ static void serial8250_timeout(unsigned long data) | |||
1591 | static void serial8250_backup_timeout(unsigned long data) | 1595 | static void serial8250_backup_timeout(unsigned long data) |
1592 | { | 1596 | { |
1593 | struct uart_8250_port *up = (struct uart_8250_port *)data; | 1597 | struct uart_8250_port *up = (struct uart_8250_port *)data; |
1594 | unsigned int iir, ier = 0; | 1598 | unsigned int iir, ier = 0, lsr; |
1599 | unsigned long flags; | ||
1595 | 1600 | ||
1596 | /* | 1601 | /* |
1597 | * Must disable interrupts or else we risk racing with the interrupt | 1602 | * Must disable interrupts or else we risk racing with the interrupt |
@@ -1610,9 +1615,13 @@ static void serial8250_backup_timeout(unsigned long data) | |||
1610 | * the "Diva" UART used on the management processor on many HP | 1615 | * the "Diva" UART used on the management processor on many HP |
1611 | * ia64 and parisc boxes. | 1616 | * ia64 and parisc boxes. |
1612 | */ | 1617 | */ |
1618 | spin_lock_irqsave(&up->port.lock, flags); | ||
1619 | lsr = serial_in(up, UART_LSR); | ||
1620 | up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; | ||
1621 | spin_unlock_irqrestore(&up->port.lock, flags); | ||
1613 | if ((iir & UART_IIR_NO_INT) && (up->ier & UART_IER_THRI) && | 1622 | if ((iir & UART_IIR_NO_INT) && (up->ier & UART_IER_THRI) && |
1614 | (!uart_circ_empty(&up->port.info->xmit) || up->port.x_char) && | 1623 | (!uart_circ_empty(&up->port.info->xmit) || up->port.x_char) && |
1615 | (serial_in(up, UART_LSR) & UART_LSR_THRE)) { | 1624 | (lsr & UART_LSR_THRE)) { |
1616 | iir &= ~(UART_IIR_ID | UART_IIR_NO_INT); | 1625 | iir &= ~(UART_IIR_ID | UART_IIR_NO_INT); |
1617 | iir |= UART_IIR_THRI; | 1626 | iir |= UART_IIR_THRI; |
1618 | } | 1627 | } |
@@ -1631,13 +1640,14 @@ static unsigned int serial8250_tx_empty(struct uart_port *port) | |||
1631 | { | 1640 | { |
1632 | struct uart_8250_port *up = (struct uart_8250_port *)port; | 1641 | struct uart_8250_port *up = (struct uart_8250_port *)port; |
1633 | unsigned long flags; | 1642 | unsigned long flags; |
1634 | unsigned int ret; | 1643 | unsigned int lsr; |
1635 | 1644 | ||
1636 | spin_lock_irqsave(&up->port.lock, flags); | 1645 | spin_lock_irqsave(&up->port.lock, flags); |
1637 | ret = serial_in(up, UART_LSR) & UART_LSR_TEMT ? TIOCSER_TEMT : 0; | 1646 | lsr = serial_in(up, UART_LSR); |
1647 | up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; | ||
1638 | spin_unlock_irqrestore(&up->port.lock, flags); | 1648 | spin_unlock_irqrestore(&up->port.lock, flags); |
1639 | 1649 | ||
1640 | return ret; | 1650 | return lsr & UART_LSR_TEMT ? TIOCSER_TEMT : 0; |
1641 | } | 1651 | } |
1642 | 1652 | ||
1643 | static unsigned int serial8250_get_mctrl(struct uart_port *port) | 1653 | static unsigned int serial8250_get_mctrl(struct uart_port *port) |
@@ -1708,8 +1718,7 @@ static inline void wait_for_xmitr(struct uart_8250_port *up, int bits) | |||
1708 | do { | 1718 | do { |
1709 | status = serial_in(up, UART_LSR); | 1719 | status = serial_in(up, UART_LSR); |
1710 | 1720 | ||
1711 | if (status & UART_LSR_BI) | 1721 | up->lsr_saved_flags |= status & LSR_SAVE_FLAGS; |
1712 | up->lsr_break_flag = UART_LSR_BI; | ||
1713 | 1722 | ||
1714 | if (--tmout == 0) | 1723 | if (--tmout == 0) |
1715 | break; | 1724 | break; |
@@ -1718,8 +1727,12 @@ static inline void wait_for_xmitr(struct uart_8250_port *up, int bits) | |||
1718 | 1727 | ||
1719 | /* Wait up to 1s for flow control if necessary */ | 1728 | /* Wait up to 1s for flow control if necessary */ |
1720 | if (up->port.flags & UPF_CONS_FLOW) { | 1729 | if (up->port.flags & UPF_CONS_FLOW) { |
1721 | tmout = 1000000; | 1730 | unsigned int tmout; |
1722 | while (!(serial_in(up, UART_MSR) & UART_MSR_CTS) && --tmout) { | 1731 | for (tmout = 1000000; tmout; tmout--) { |
1732 | unsigned int msr = serial_in(up, UART_MSR); | ||
1733 | up->msr_saved_flags |= msr & MSR_SAVE_FLAGS; | ||
1734 | if (msr & UART_MSR_CTS) | ||
1735 | break; | ||
1723 | udelay(1); | 1736 | udelay(1); |
1724 | touch_nmi_watchdog(); | 1737 | touch_nmi_watchdog(); |
1725 | } | 1738 | } |
@@ -1889,6 +1902,18 @@ static int serial8250_startup(struct uart_port *port) | |||
1889 | spin_unlock_irqrestore(&up->port.lock, flags); | 1902 | spin_unlock_irqrestore(&up->port.lock, flags); |
1890 | 1903 | ||
1891 | /* | 1904 | /* |
1905 | * Clear the interrupt registers again for luck, and clear the | ||
1906 | * saved flags to avoid getting false values from polling | ||
1907 | * routines or the previous session. | ||
1908 | */ | ||
1909 | serial_inp(up, UART_LSR); | ||
1910 | serial_inp(up, UART_RX); | ||
1911 | serial_inp(up, UART_IIR); | ||
1912 | serial_inp(up, UART_MSR); | ||
1913 | up->lsr_saved_flags = 0; | ||
1914 | up->msr_saved_flags = 0; | ||
1915 | |||
1916 | /* | ||
1892 | * Finally, enable interrupts. Note: Modem status interrupts | 1917 | * Finally, enable interrupts. Note: Modem status interrupts |
1893 | * are set via set_termios(), which will be occurring imminently | 1918 | * are set via set_termios(), which will be occurring imminently |
1894 | * anyway, so we don't enable them here. | 1919 | * anyway, so we don't enable them here. |
@@ -1906,14 +1931,6 @@ static int serial8250_startup(struct uart_port *port) | |||
1906 | (void) inb_p(icp); | 1931 | (void) inb_p(icp); |
1907 | } | 1932 | } |
1908 | 1933 | ||
1909 | /* | ||
1910 | * And clear the interrupt registers again for luck. | ||
1911 | */ | ||
1912 | (void) serial_inp(up, UART_LSR); | ||
1913 | (void) serial_inp(up, UART_RX); | ||
1914 | (void) serial_inp(up, UART_IIR); | ||
1915 | (void) serial_inp(up, UART_MSR); | ||
1916 | |||
1917 | return 0; | 1934 | return 0; |
1918 | } | 1935 | } |
1919 | 1936 | ||
@@ -2484,6 +2501,16 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count) | |||
2484 | wait_for_xmitr(up, BOTH_EMPTY); | 2501 | wait_for_xmitr(up, BOTH_EMPTY); |
2485 | serial_out(up, UART_IER, ier); | 2502 | serial_out(up, UART_IER, ier); |
2486 | 2503 | ||
2504 | /* | ||
2505 | * The receive handling will happen properly because the | ||
2506 | * receive ready bit will still be set; it is not cleared | ||
2507 | * on read. However, modem control will not, we must | ||
2508 | * call it if we have saved something in the saved flags | ||
2509 | * while processing with interrupts off. | ||
2510 | */ | ||
2511 | if (up->msr_saved_flags) | ||
2512 | check_modem_status(up); | ||
2513 | |||
2487 | if (locked) | 2514 | if (locked) |
2488 | spin_unlock(&up->port.lock); | 2515 | spin_unlock(&up->port.lock); |
2489 | local_irq_restore(flags); | 2516 | local_irq_restore(flags); |
diff --git a/include/linux/serial_reg.h b/include/linux/serial_reg.h index 1c5ed7d92b0f..96c0d93fc2ca 100644 --- a/include/linux/serial_reg.h +++ b/include/linux/serial_reg.h | |||
@@ -118,6 +118,7 @@ | |||
118 | #define UART_LSR_PE 0x04 /* Parity error indicator */ | 118 | #define UART_LSR_PE 0x04 /* Parity error indicator */ |
119 | #define UART_LSR_OE 0x02 /* Overrun error indicator */ | 119 | #define UART_LSR_OE 0x02 /* Overrun error indicator */ |
120 | #define UART_LSR_DR 0x01 /* Receiver data ready */ | 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 | #define UART_MSR 6 /* In: Modem Status Register */ | 123 | #define UART_MSR 6 /* In: Modem Status Register */ |
123 | #define UART_MSR_DCD 0x80 /* Data Carrier Detect */ | 124 | #define UART_MSR_DCD 0x80 /* Data Carrier Detect */ |