aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLiang Li <liang.li@windriver.com>2013-03-05 09:30:38 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-03-15 16:55:23 -0400
commitef44d28c4fd94166ec6be054359ae26ba73b0291 (patch)
treed803dfdeb1884e71b860b44e071c2d43a3bcc6fe
parentfec6bee367357d9dd3ab3a7c56293214e49c371c (diff)
serial: pch_uart: add console poll support
Implement console poll for pch_uart, this could enable KGDBoC when on pch-uart console. Signed-off-by: Liang Li <liang.li@windriver.com> Acked-by: Jason Wessel <jason.wessel@windriver.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/tty/serial/pch_uart.c103
1 files changed, 79 insertions, 24 deletions
diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c
index 7a6c989924b3..21a7e179edf3 100644
--- a/drivers/tty/serial/pch_uart.c
+++ b/drivers/tty/serial/pch_uart.c
@@ -1493,29 +1493,6 @@ static int pch_uart_verify_port(struct uart_port *port,
1493 return 0; 1493 return 0;
1494} 1494}
1495 1495
1496static struct uart_ops pch_uart_ops = {
1497 .tx_empty = pch_uart_tx_empty,
1498 .set_mctrl = pch_uart_set_mctrl,
1499 .get_mctrl = pch_uart_get_mctrl,
1500 .stop_tx = pch_uart_stop_tx,
1501 .start_tx = pch_uart_start_tx,
1502 .stop_rx = pch_uart_stop_rx,
1503 .enable_ms = pch_uart_enable_ms,
1504 .break_ctl = pch_uart_break_ctl,
1505 .startup = pch_uart_startup,
1506 .shutdown = pch_uart_shutdown,
1507 .set_termios = pch_uart_set_termios,
1508/* .pm = pch_uart_pm, Not supported yet */
1509/* .set_wake = pch_uart_set_wake, Not supported yet */
1510 .type = pch_uart_type,
1511 .release_port = pch_uart_release_port,
1512 .request_port = pch_uart_request_port,
1513 .config_port = pch_uart_config_port,
1514 .verify_port = pch_uart_verify_port
1515};
1516
1517#ifdef CONFIG_SERIAL_PCH_UART_CONSOLE
1518
1519/* 1496/*
1520 * Wait for transmitter & holding register to empty 1497 * Wait for transmitter & holding register to empty
1521 */ 1498 */
@@ -1547,6 +1524,84 @@ static void wait_for_xmitr(struct eg20t_port *up, int bits)
1547 } 1524 }
1548} 1525}
1549 1526
1527#ifdef CONFIG_CONSOLE_POLL
1528/*
1529 * Console polling routines for communicate via uart while
1530 * in an interrupt or debug context.
1531 */
1532static int pch_uart_get_poll_char(struct uart_port *port)
1533{
1534 struct eg20t_port *priv =
1535 container_of(port, struct eg20t_port, port);
1536 u8 lsr = ioread8(priv->membase + UART_LSR);
1537
1538 if (!(lsr & UART_LSR_DR))
1539 return NO_POLL_CHAR;
1540
1541 return ioread8(priv->membase + PCH_UART_RBR);
1542}
1543
1544
1545static void pch_uart_put_poll_char(struct uart_port *port,
1546 unsigned char c)
1547{
1548 unsigned int ier;
1549 struct eg20t_port *priv =
1550 container_of(port, struct eg20t_port, port);
1551
1552 /*
1553 * First save the IER then disable the interrupts
1554 */
1555 ier = ioread8(priv->membase + UART_IER);
1556 pch_uart_hal_disable_interrupt(priv, PCH_UART_HAL_ALL_INT);
1557
1558 wait_for_xmitr(priv, UART_LSR_THRE);
1559 /*
1560 * Send the character out.
1561 * If a LF, also do CR...
1562 */
1563 iowrite8(c, priv->membase + PCH_UART_THR);
1564 if (c == 10) {
1565 wait_for_xmitr(priv, UART_LSR_THRE);
1566 iowrite8(13, priv->membase + PCH_UART_THR);
1567 }
1568
1569 /*
1570 * Finally, wait for transmitter to become empty
1571 * and restore the IER
1572 */
1573 wait_for_xmitr(priv, BOTH_EMPTY);
1574 iowrite8(ier, priv->membase + UART_IER);
1575}
1576#endif /* CONFIG_CONSOLE_POLL */
1577
1578static struct uart_ops pch_uart_ops = {
1579 .tx_empty = pch_uart_tx_empty,
1580 .set_mctrl = pch_uart_set_mctrl,
1581 .get_mctrl = pch_uart_get_mctrl,
1582 .stop_tx = pch_uart_stop_tx,
1583 .start_tx = pch_uart_start_tx,
1584 .stop_rx = pch_uart_stop_rx,
1585 .enable_ms = pch_uart_enable_ms,
1586 .break_ctl = pch_uart_break_ctl,
1587 .startup = pch_uart_startup,
1588 .shutdown = pch_uart_shutdown,
1589 .set_termios = pch_uart_set_termios,
1590/* .pm = pch_uart_pm, Not supported yet */
1591/* .set_wake = pch_uart_set_wake, Not supported yet */
1592 .type = pch_uart_type,
1593 .release_port = pch_uart_release_port,
1594 .request_port = pch_uart_request_port,
1595 .config_port = pch_uart_config_port,
1596 .verify_port = pch_uart_verify_port,
1597#ifdef CONFIG_CONSOLE_POLL
1598 .poll_get_char = pch_uart_get_poll_char,
1599 .poll_put_char = pch_uart_put_poll_char,
1600#endif
1601};
1602
1603#ifdef CONFIG_SERIAL_PCH_UART_CONSOLE
1604
1550static void pch_console_putchar(struct uart_port *port, int ch) 1605static void pch_console_putchar(struct uart_port *port, int ch)
1551{ 1606{
1552 struct eg20t_port *priv = 1607 struct eg20t_port *priv =
@@ -1655,7 +1710,7 @@ static struct console pch_console = {
1655#define PCH_CONSOLE (&pch_console) 1710#define PCH_CONSOLE (&pch_console)
1656#else 1711#else
1657#define PCH_CONSOLE NULL 1712#define PCH_CONSOLE NULL
1658#endif 1713#endif /* CONFIG_SERIAL_PCH_UART_CONSOLE */
1659 1714
1660static struct uart_driver pch_uart_driver = { 1715static struct uart_driver pch_uart_driver = {
1661 .owner = THIS_MODULE, 1716 .owner = THIS_MODULE,