diff options
author | Jason Wessel <jason.wessel@windriver.com> | 2010-05-20 22:04:23 -0400 |
---|---|---|
committer | Jason Wessel <jason.wessel@windriver.com> | 2010-05-20 22:04:23 -0400 |
commit | 6d45a1aed34b0cd7b298967eb9cb72b77afcb33b (patch) | |
tree | ca6653d60f2c49e0a28d23c247d83c577cc04187 /drivers/serial/sunzilog.c | |
parent | 3f255eb37e97e97dfec7cb8d4c75d543de231812 (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/sunzilog.c')
-rw-r--r-- | drivers/serial/sunzilog.c | 50 |
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 | ||
105 | static 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 | ||
1002 | static 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 | |||
1036 | static 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 | |||
999 | static struct uart_ops sunzilog_pops = { | 1045 | static 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 | ||
1018 | static int uart_chip_count; | 1068 | static int uart_chip_count; |