aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial/8250.c
diff options
context:
space:
mode:
authorJason Wessel <jason.wessel@windriver.com>2008-04-17 14:05:37 -0400
committerIngo Molnar <mingo@elte.hu>2008-04-17 14:05:37 -0400
commitf2d937f3bf00665ccf048b3b6616ef95859b0945 (patch)
tree6136ded0706be0d39a09a0a912e8f79a4ab63322 /drivers/serial/8250.c
parentdc7d552705215ac50a0617fcf51bb9c736255b8e (diff)
consoles: polling support, kgdboc
polled console handling support, to access a console in an irq-less way while in debug or irq context. absolutely zero impact as long as CONFIG_CONSOLE_POLL is disabled. (which is the default) [ jan.kiszka@siemens.com: lots of cleanups ] [ mingo@elte.hu: redesign, splitups, cleanups. ] Signed-off-by: Jason Wessel <jason.wessel@windriver.com> Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Jan Kiszka <jan.kiszka@web.de> Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'drivers/serial/8250.c')
-rw-r--r--drivers/serial/8250.c58
1 files changed, 58 insertions, 0 deletions
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 77f7a7f0646..96a585e1cee 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -1740,6 +1740,60 @@ static inline void wait_for_xmitr(struct uart_8250_port *up, int bits)
1740 } 1740 }
1741} 1741}
1742 1742
1743#ifdef CONFIG_CONSOLE_POLL
1744/*
1745 * Console polling routines for writing and reading from the uart while
1746 * in an interrupt or debug context.
1747 */
1748
1749static int serial8250_get_poll_char(struct uart_port *port)
1750{
1751 struct uart_8250_port *up = (struct uart_8250_port *)port;
1752 unsigned char lsr = serial_inp(up, UART_LSR);
1753
1754 while (!(lsr & UART_LSR_DR))
1755 lsr = serial_inp(up, UART_LSR);
1756
1757 return serial_inp(up, UART_RX);
1758}
1759
1760
1761static void serial8250_put_poll_char(struct uart_port *port,
1762 unsigned char c)
1763{
1764 unsigned int ier;
1765 struct uart_8250_port *up = (struct uart_8250_port *)port;
1766
1767 /*
1768 * First save the IER then disable the interrupts
1769 */
1770 ier = serial_in(up, UART_IER);
1771 if (up->capabilities & UART_CAP_UUE)
1772 serial_out(up, UART_IER, UART_IER_UUE);
1773 else
1774 serial_out(up, UART_IER, 0);
1775
1776 wait_for_xmitr(up, BOTH_EMPTY);
1777 /*
1778 * Send the character out.
1779 * If a LF, also do CR...
1780 */
1781 serial_out(up, UART_TX, c);
1782 if (c == 10) {
1783 wait_for_xmitr(up, BOTH_EMPTY);
1784 serial_out(up, UART_TX, 13);
1785 }
1786
1787 /*
1788 * Finally, wait for transmitter to become empty
1789 * and restore the IER
1790 */
1791 wait_for_xmitr(up, BOTH_EMPTY);
1792 serial_out(up, UART_IER, ier);
1793}
1794
1795#endif /* CONFIG_CONSOLE_POLL */
1796
1743static int serial8250_startup(struct uart_port *port) 1797static int serial8250_startup(struct uart_port *port)
1744{ 1798{
1745 struct uart_8250_port *up = (struct uart_8250_port *)port; 1799 struct uart_8250_port *up = (struct uart_8250_port *)port;
@@ -2386,6 +2440,10 @@ static struct uart_ops serial8250_pops = {
2386 .request_port = serial8250_request_port, 2440 .request_port = serial8250_request_port,
2387 .config_port = serial8250_config_port, 2441 .config_port = serial8250_config_port,
2388 .verify_port = serial8250_verify_port, 2442 .verify_port = serial8250_verify_port,
2443#ifdef CONFIG_CONSOLE_POLL
2444 .poll_get_char = serial8250_get_poll_char,
2445 .poll_put_char = serial8250_put_poll_char,
2446#endif
2389}; 2447};
2390 2448
2391static struct uart_8250_port serial8250_ports[UART_NR]; 2449static struct uart_8250_port serial8250_ports[UART_NR];