aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAlex Williamson <alex.williamson@hp.com>2007-02-14 03:33:04 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-14 11:09:52 -0500
commit40b36daad0ac704e6d5c1b75789f371ef5b053c1 (patch)
tree2b47cdb0d51d191e08e28fde14853b608b8d94c8 /drivers
parented8b4d4d7a31923db32f4684535944d69eb43677 (diff)
[PATCH] 8250 UART backup timer
The patch below works around a minor bug found in the UART of the remote management card used in many HP ia64 and parisc servers (aka the Diva UARTs). The problem is that the UART does not reassert the THRE interrupt if it has been previously cleared and the IIR THRI bit is re-enabled. This can produce a very annoying failure mode when used as a serial console, allowing a boot/reboot to hang indefinitely until an RX interrupt kicks it into working again (ie. an unattended reboot could stall). To solve this problem, a backup timer is introduced that runs alongside the standard interrupt driven mechanism. This timer wakes up periodically, checks for a hang condition and gets characters moving again. This backup mechanism is only enabled if the UART is detected as having this problem, so systems without these UARTs will have no additional overhead. This version of the patch incorporates previous comments from Pavel and removes races in the bug detection code. The test is now done before the irq linking to prevent races with interrupt handler clearing the THRE interrupt. Short delays and syncs are also added to ensure the device is able to update register state before the result is tested. Aristeu says: this was tested on the following HP machines and solved the problem: rx2600, rx2620, rx1600 and rx1620s. hpa says: I have seen this same bug in soft UART IP from "a major vendor." Signed-off-by: Alex Williamson <alex.williamson@hp.com> Cc: "H. Peter Anvin" <hpa@zytor.com> Cc: Russell King <rmk@arm.linux.org.uk> Acked-by: Aristeu Sergio Rozanski Filho <aris@cathedrallabs.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/serial/8250.c178
1 files changed, 134 insertions, 44 deletions
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 2964ca9df5a0..98ec86185328 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -364,6 +364,23 @@ serial_out(struct uart_8250_port *up, int offset, int value)
364 } 364 }
365} 365}
366 366
367static void
368serial_out_sync(struct uart_8250_port *up, int offset, int value)
369{
370 switch (up->port.iotype) {
371 case UPIO_MEM:
372 case UPIO_MEM32:
373#ifdef CONFIG_SERIAL_8250_AU1X00
374 case UPIO_AU:
375#endif
376 serial_out(up, offset, value);
377 serial_in(up, UART_LCR); /* safe, no side-effects */
378 break;
379 default:
380 serial_out(up, offset, value);
381 }
382}
383
367/* 384/*
368 * We used to support using pause I/O for certain machines. We 385 * We used to support using pause I/O for certain machines. We
369 * haven't supported this for a while, but just in case it's badly 386 * haven't supported this for a while, but just in case it's badly
@@ -1045,7 +1062,7 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
1045#endif 1062#endif
1046 serial_outp(up, UART_MCR, save_mcr); 1063 serial_outp(up, UART_MCR, save_mcr);
1047 serial8250_clear_fifos(up); 1064 serial8250_clear_fifos(up);
1048 (void)serial_in(up, UART_RX); 1065 serial_in(up, UART_RX);
1049 if (up->capabilities & UART_CAP_UUE) 1066 if (up->capabilities & UART_CAP_UUE)
1050 serial_outp(up, UART_IER, UART_IER_UUE); 1067 serial_outp(up, UART_IER, UART_IER_UUE);
1051 else 1068 else
@@ -1451,6 +1468,12 @@ static void serial_unlink_irq_chain(struct uart_8250_port *up)
1451 serial_do_unlink(i, up); 1468 serial_do_unlink(i, up);
1452} 1469}
1453 1470
1471/* Base timer interval for polling */
1472static inline int poll_timeout(int timeout)
1473{
1474 return timeout > 6 ? (timeout / 2 - 2) : 1;
1475}
1476
1454/* 1477/*
1455 * This function is used to handle ports that do not have an 1478 * This function is used to handle ports that do not have an
1456 * interrupt. This doesn't work very well for 16450's, but gives 1479 * interrupt. This doesn't work very well for 16450's, but gives
@@ -1460,16 +1483,51 @@ static void serial_unlink_irq_chain(struct uart_8250_port *up)
1460static void serial8250_timeout(unsigned long data) 1483static void serial8250_timeout(unsigned long data)
1461{ 1484{
1462 struct uart_8250_port *up = (struct uart_8250_port *)data; 1485 struct uart_8250_port *up = (struct uart_8250_port *)data;
1463 unsigned int timeout;
1464 unsigned int iir; 1486 unsigned int iir;
1465 1487
1466 iir = serial_in(up, UART_IIR); 1488 iir = serial_in(up, UART_IIR);
1467 if (!(iir & UART_IIR_NO_INT)) 1489 if (!(iir & UART_IIR_NO_INT))
1468 serial8250_handle_port(up); 1490 serial8250_handle_port(up);
1491 mod_timer(&up->timer, jiffies + poll_timeout(up->port.timeout));
1492}
1493
1494static void serial8250_backup_timeout(unsigned long data)
1495{
1496 struct uart_8250_port *up = (struct uart_8250_port *)data;
1497 unsigned int iir, ier = 0;
1498
1499 /*
1500 * Must disable interrupts or else we risk racing with the interrupt
1501 * based handler.
1502 */
1503 if (is_real_interrupt(up->port.irq)) {
1504 ier = serial_in(up, UART_IER);
1505 serial_out(up, UART_IER, 0);
1506 }
1469 1507
1470 timeout = up->port.timeout; 1508 iir = serial_in(up, UART_IIR);
1471 timeout = timeout > 6 ? (timeout / 2 - 2) : 1; 1509
1472 mod_timer(&up->timer, jiffies + timeout); 1510 /*
1511 * This should be a safe test for anyone who doesn't trust the
1512 * IIR bits on their UART, but it's specifically designed for
1513 * the "Diva" UART used on the management processor on many HP
1514 * ia64 and parisc boxes.
1515 */
1516 if ((iir & UART_IIR_NO_INT) && (up->ier & UART_IER_THRI) &&
1517 (!uart_circ_empty(&up->port.info->xmit) || up->port.x_char) &&
1518 (serial_in(up, UART_LSR) & UART_LSR_THRE)) {
1519 iir &= ~(UART_IIR_ID | UART_IIR_NO_INT);
1520 iir |= UART_IIR_THRI;
1521 }
1522
1523 if (!(iir & UART_IIR_NO_INT))
1524 serial8250_handle_port(up);
1525
1526 if (is_real_interrupt(up->port.irq))
1527 serial_out(up, UART_IER, ier);
1528
1529 /* Standard timer interval plus 0.2s to keep the port running */
1530 mod_timer(&up->timer, jiffies + poll_timeout(up->port.timeout) + HZ/5);
1473} 1531}
1474 1532
1475static unsigned int serial8250_tx_empty(struct uart_port *port) 1533static unsigned int serial8250_tx_empty(struct uart_port *port)
@@ -1540,6 +1598,37 @@ static void serial8250_break_ctl(struct uart_port *port, int break_state)
1540 spin_unlock_irqrestore(&up->port.lock, flags); 1598 spin_unlock_irqrestore(&up->port.lock, flags);
1541} 1599}
1542 1600
1601#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
1602
1603/*
1604 * Wait for transmitter & holding register to empty
1605 */
1606static inline void wait_for_xmitr(struct uart_8250_port *up, int bits)
1607{
1608 unsigned int status, tmout = 10000;
1609
1610 /* Wait up to 10ms for the character(s) to be sent. */
1611 do {
1612 status = serial_in(up, UART_LSR);
1613
1614 if (status & UART_LSR_BI)
1615 up->lsr_break_flag = UART_LSR_BI;
1616
1617 if (--tmout == 0)
1618 break;
1619 udelay(1);
1620 } while ((status & bits) != bits);
1621
1622 /* Wait up to 1s for flow control if necessary */
1623 if (up->port.flags & UPF_CONS_FLOW) {
1624 tmout = 1000000;
1625 while (!(serial_in(up, UART_MSR) & UART_MSR_CTS) && --tmout) {
1626 udelay(1);
1627 touch_nmi_watchdog();
1628 }
1629 }
1630}
1631
1543static int serial8250_startup(struct uart_port *port) 1632static int serial8250_startup(struct uart_port *port)
1544{ 1633{
1545 struct uart_8250_port *up = (struct uart_8250_port *)port; 1634 struct uart_8250_port *up = (struct uart_8250_port *)port;
@@ -1613,18 +1702,50 @@ static int serial8250_startup(struct uart_port *port)
1613 serial_outp(up, UART_LCR, 0); 1702 serial_outp(up, UART_LCR, 0);
1614 } 1703 }
1615 1704
1705 if (is_real_interrupt(up->port.irq)) {
1706 /*
1707 * Test for UARTs that do not reassert THRE when the
1708 * transmitter is idle and the interrupt has already
1709 * been cleared. Real 16550s should always reassert
1710 * this interrupt whenever the transmitter is idle and
1711 * the interrupt is enabled. Delays are necessary to
1712 * allow register changes to become visible.
1713 */
1714 spin_lock_irqsave(&up->port.lock, flags);
1715
1716 wait_for_xmitr(up, UART_LSR_THRE);
1717 serial_out_sync(up, UART_IER, UART_IER_THRI);
1718 udelay(1); /* allow THRE to set */
1719 serial_in(up, UART_IIR);
1720 serial_out(up, UART_IER, 0);
1721 serial_out_sync(up, UART_IER, UART_IER_THRI);
1722 udelay(1); /* allow a working UART time to re-assert THRE */
1723 iir = serial_in(up, UART_IIR);
1724 serial_out(up, UART_IER, 0);
1725
1726 spin_unlock_irqrestore(&up->port.lock, flags);
1727
1728 /*
1729 * If the interrupt is not reasserted, setup a timer to
1730 * kick the UART on a regular basis.
1731 */
1732 if (iir & UART_IIR_NO_INT) {
1733 pr_debug("ttyS%d - using backup timer\n", port->line);
1734 up->timer.function = serial8250_backup_timeout;
1735 up->timer.data = (unsigned long)up;
1736 mod_timer(&up->timer, jiffies +
1737 poll_timeout(up->port.timeout) + HZ/5);
1738 }
1739 }
1740
1616 /* 1741 /*
1617 * If the "interrupt" for this port doesn't correspond with any 1742 * If the "interrupt" for this port doesn't correspond with any
1618 * hardware interrupt, we use a timer-based system. The original 1743 * hardware interrupt, we use a timer-based system. The original
1619 * driver used to do this with IRQ0. 1744 * driver used to do this with IRQ0.
1620 */ 1745 */
1621 if (!is_real_interrupt(up->port.irq)) { 1746 if (!is_real_interrupt(up->port.irq)) {
1622 unsigned int timeout = up->port.timeout;
1623
1624 timeout = timeout > 6 ? (timeout / 2 - 2) : 1;
1625
1626 up->timer.data = (unsigned long)up; 1747 up->timer.data = (unsigned long)up;
1627 mod_timer(&up->timer, jiffies + timeout); 1748 mod_timer(&up->timer, jiffies + poll_timeout(up->port.timeout));
1628 } else { 1749 } else {
1629 retval = serial_link_irq_chain(up); 1750 retval = serial_link_irq_chain(up);
1630 if (retval) 1751 if (retval)
@@ -1740,9 +1861,9 @@ static void serial8250_shutdown(struct uart_port *port)
1740 */ 1861 */
1741 (void) serial_in(up, UART_RX); 1862 (void) serial_in(up, UART_RX);
1742 1863
1743 if (!is_real_interrupt(up->port.irq)) 1864 del_timer_sync(&up->timer);
1744 del_timer_sync(&up->timer); 1865 up->timer.function = serial8250_timeout;
1745 else 1866 if (is_real_interrupt(up->port.irq))
1746 serial_unlink_irq_chain(up); 1867 serial_unlink_irq_chain(up);
1747} 1868}
1748 1869
@@ -2212,37 +2333,6 @@ serial8250_register_ports(struct uart_driver *drv, struct device *dev)
2212 2333
2213#ifdef CONFIG_SERIAL_8250_CONSOLE 2334#ifdef CONFIG_SERIAL_8250_CONSOLE
2214 2335
2215#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
2216
2217/*
2218 * Wait for transmitter & holding register to empty
2219 */
2220static inline void wait_for_xmitr(struct uart_8250_port *up, int bits)
2221{
2222 unsigned int status, tmout = 10000;
2223
2224 /* Wait up to 10ms for the character(s) to be sent. */
2225 do {
2226 status = serial_in(up, UART_LSR);
2227
2228 if (status & UART_LSR_BI)
2229 up->lsr_break_flag = UART_LSR_BI;
2230
2231 if (--tmout == 0)
2232 break;
2233 udelay(1);
2234 } while ((status & bits) != bits);
2235
2236 /* Wait up to 1s for flow control if necessary */
2237 if (up->port.flags & UPF_CONS_FLOW) {
2238 tmout = 1000000;
2239 while (!(serial_in(up, UART_MSR) & UART_MSR_CTS) && --tmout) {
2240 udelay(1);
2241 touch_nmi_watchdog();
2242 }
2243 }
2244}
2245
2246static void serial8250_console_putchar(struct uart_port *port, int ch) 2336static void serial8250_console_putchar(struct uart_port *port, int ch)
2247{ 2337{
2248 struct uart_8250_port *up = (struct uart_8250_port *)port; 2338 struct uart_8250_port *up = (struct uart_8250_port *)port;