aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial
diff options
context:
space:
mode:
authorJason Wessel <jason.wessel@windriver.com>2010-05-20 22:04:23 -0400
committerJason Wessel <jason.wessel@windriver.com>2010-05-20 22:04:23 -0400
commit6d45a1aed34b0cd7b298967eb9cb72b77afcb33b (patch)
treeca6653d60f2c49e0a28d23c247d83c577cc04187 /drivers/serial
parent3f255eb37e97e97dfec7cb8d4c75d543de231812 (diff)
sparc,sunzilog: Add console polling support for sunzilog serial driver
Allow kgdboc to work on sparc hardware with the Zilog serial chips. Signed-off-by: Jason Wessel <jason.wessel@windriver.com> Acked-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/serial')
-rw-r--r--drivers/serial/sunzilog.c50
1 files changed, 50 insertions, 0 deletions
diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c
index 2c7a66af4f52..978b3cee02d7 100644
--- a/drivers/serial/sunzilog.c
+++ b/drivers/serial/sunzilog.c
@@ -102,6 +102,8 @@ struct uart_sunzilog_port {
102#endif 102#endif
103}; 103};
104 104
105static void sunzilog_putchar(struct uart_port *port, int ch);
106
105#define ZILOG_CHANNEL_FROM_PORT(PORT) ((struct zilog_channel __iomem *)((PORT)->membase)) 107#define ZILOG_CHANNEL_FROM_PORT(PORT) ((struct zilog_channel __iomem *)((PORT)->membase))
106#define UART_ZILOG(PORT) ((struct uart_sunzilog_port *)(PORT)) 108#define UART_ZILOG(PORT) ((struct uart_sunzilog_port *)(PORT))
107 109
@@ -996,6 +998,50 @@ static int sunzilog_verify_port(struct uart_port *port, struct serial_struct *se
996 return -EINVAL; 998 return -EINVAL;
997} 999}
998 1000
1001#ifdef CONFIG_CONSOLE_POLL
1002static int sunzilog_get_poll_char(struct uart_port *port)
1003{
1004 unsigned char ch, r1;
1005 struct uart_sunzilog_port *up = (struct uart_sunzilog_port *) port;
1006 struct zilog_channel __iomem *channel
1007 = ZILOG_CHANNEL_FROM_PORT(&up->port);
1008
1009
1010 r1 = read_zsreg(channel, R1);
1011 if (r1 & (PAR_ERR | Rx_OVR | CRC_ERR)) {
1012 writeb(ERR_RES, &channel->control);
1013 ZSDELAY();
1014 ZS_WSYNC(channel);
1015 }
1016
1017 ch = readb(&channel->control);
1018 ZSDELAY();
1019
1020 /* This funny hack depends upon BRK_ABRT not interfering
1021 * with the other bits we care about in R1.
1022 */
1023 if (ch & BRK_ABRT)
1024 r1 |= BRK_ABRT;
1025
1026 if (!(ch & Rx_CH_AV))
1027 return NO_POLL_CHAR;
1028
1029 ch = readb(&channel->data);
1030 ZSDELAY();
1031
1032 ch &= up->parity_mask;
1033 return ch;
1034}
1035
1036static void sunzilog_put_poll_char(struct uart_port *port,
1037 unsigned char ch)
1038{
1039 struct uart_sunzilog_port *up = (struct uart_sunzilog_port *)port;
1040
1041 sunzilog_putchar(&up->port, ch);
1042}
1043#endif /* CONFIG_CONSOLE_POLL */
1044
999static struct uart_ops sunzilog_pops = { 1045static struct uart_ops sunzilog_pops = {
1000 .tx_empty = sunzilog_tx_empty, 1046 .tx_empty = sunzilog_tx_empty,
1001 .set_mctrl = sunzilog_set_mctrl, 1047 .set_mctrl = sunzilog_set_mctrl,
@@ -1013,6 +1059,10 @@ static struct uart_ops sunzilog_pops = {
1013 .request_port = sunzilog_request_port, 1059 .request_port = sunzilog_request_port,
1014 .config_port = sunzilog_config_port, 1060 .config_port = sunzilog_config_port,
1015 .verify_port = sunzilog_verify_port, 1061 .verify_port = sunzilog_verify_port,
1062#ifdef CONFIG_CONSOLE_POLL
1063 .poll_get_char = sunzilog_get_poll_char,
1064 .poll_put_char = sunzilog_put_poll_char,
1065#endif
1016}; 1066};
1017 1067
1018static int uart_chip_count; 1068static int uart_chip_count;