diff options
author | Dongdong Deng <dongdong.deng@windriver.com> | 2010-06-16 23:13:40 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-06-30 11:15:17 -0400 |
commit | 8cd774ad30c22b9d89823f1f05d845f4cdaba9e8 (patch) | |
tree | d7fd2b83386a5763ebc8651b43afb797a4a6d2c0 /drivers/serial | |
parent | 93416253073511716f7e70c06e32c3810c3deac4 (diff) |
serial: cpm_uart: implement the cpm_uart_early_write() function for console poll
The cpm_uart_early_write() function which was used for console poll
isn't implemented in the cpm uart driver.
Implementing this function both fixes the build when CONFIG_CONSOLE_POLL
is set and allows kgdboc to work via the cpm uart.
Signed-off-by: Dongdong Deng <dongdong.deng@windriver.com>
Reviewed-by: Bruce Ashfield <bruce.ashfield@windriver.com>
Cc: stable <stable@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/serial')
-rw-r--r-- | drivers/serial/cpm_uart/cpm_uart_core.c | 143 |
1 files changed, 79 insertions, 64 deletions
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c index 9eb62a256e9a..cd6cf575902e 100644 --- a/drivers/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/serial/cpm_uart/cpm_uart_core.c | |||
@@ -930,6 +930,83 @@ static void cpm_uart_config_port(struct uart_port *port, int flags) | |||
930 | } | 930 | } |
931 | } | 931 | } |
932 | 932 | ||
933 | #if defined(CONFIG_CONSOLE_POLL) || defined(CONFIG_SERIAL_CPM_CONSOLE) | ||
934 | /* | ||
935 | * Write a string to the serial port | ||
936 | * Note that this is called with interrupts already disabled | ||
937 | */ | ||
938 | static void cpm_uart_early_write(struct uart_cpm_port *pinfo, | ||
939 | const char *string, u_int count) | ||
940 | { | ||
941 | unsigned int i; | ||
942 | cbd_t __iomem *bdp, *bdbase; | ||
943 | unsigned char *cpm_outp_addr; | ||
944 | |||
945 | /* Get the address of the host memory buffer. | ||
946 | */ | ||
947 | bdp = pinfo->tx_cur; | ||
948 | bdbase = pinfo->tx_bd_base; | ||
949 | |||
950 | /* | ||
951 | * Now, do each character. This is not as bad as it looks | ||
952 | * since this is a holding FIFO and not a transmitting FIFO. | ||
953 | * We could add the complexity of filling the entire transmit | ||
954 | * buffer, but we would just wait longer between accesses...... | ||
955 | */ | ||
956 | for (i = 0; i < count; i++, string++) { | ||
957 | /* Wait for transmitter fifo to empty. | ||
958 | * Ready indicates output is ready, and xmt is doing | ||
959 | * that, not that it is ready for us to send. | ||
960 | */ | ||
961 | while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) | ||
962 | ; | ||
963 | |||
964 | /* Send the character out. | ||
965 | * If the buffer address is in the CPM DPRAM, don't | ||
966 | * convert it. | ||
967 | */ | ||
968 | cpm_outp_addr = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), | ||
969 | pinfo); | ||
970 | *cpm_outp_addr = *string; | ||
971 | |||
972 | out_be16(&bdp->cbd_datlen, 1); | ||
973 | setbits16(&bdp->cbd_sc, BD_SC_READY); | ||
974 | |||
975 | if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) | ||
976 | bdp = bdbase; | ||
977 | else | ||
978 | bdp++; | ||
979 | |||
980 | /* if a LF, also do CR... */ | ||
981 | if (*string == 10) { | ||
982 | while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) | ||
983 | ; | ||
984 | |||
985 | cpm_outp_addr = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), | ||
986 | pinfo); | ||
987 | *cpm_outp_addr = 13; | ||
988 | |||
989 | out_be16(&bdp->cbd_datlen, 1); | ||
990 | setbits16(&bdp->cbd_sc, BD_SC_READY); | ||
991 | |||
992 | if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) | ||
993 | bdp = bdbase; | ||
994 | else | ||
995 | bdp++; | ||
996 | } | ||
997 | } | ||
998 | |||
999 | /* | ||
1000 | * Finally, Wait for transmitter & holding register to empty | ||
1001 | * and restore the IER | ||
1002 | */ | ||
1003 | while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) | ||
1004 | ; | ||
1005 | |||
1006 | pinfo->tx_cur = bdp; | ||
1007 | } | ||
1008 | #endif | ||
1009 | |||
933 | #ifdef CONFIG_CONSOLE_POLL | 1010 | #ifdef CONFIG_CONSOLE_POLL |
934 | /* Serial polling routines for writing and reading from the uart while | 1011 | /* Serial polling routines for writing and reading from the uart while |
935 | * in an interrupt or debug context. | 1012 | * in an interrupt or debug context. |
@@ -999,7 +1076,7 @@ static void cpm_put_poll_char(struct uart_port *port, | |||
999 | static char ch[2]; | 1076 | static char ch[2]; |
1000 | 1077 | ||
1001 | ch[0] = (char)c; | 1078 | ch[0] = (char)c; |
1002 | cpm_uart_early_write(pinfo->port.line, ch, 1); | 1079 | cpm_uart_early_write(pinfo, ch, 1); |
1003 | } | 1080 | } |
1004 | #endif /* CONFIG_CONSOLE_POLL */ | 1081 | #endif /* CONFIG_CONSOLE_POLL */ |
1005 | 1082 | ||
@@ -1130,9 +1207,6 @@ static void cpm_uart_console_write(struct console *co, const char *s, | |||
1130 | u_int count) | 1207 | u_int count) |
1131 | { | 1208 | { |
1132 | struct uart_cpm_port *pinfo = &cpm_uart_ports[co->index]; | 1209 | struct uart_cpm_port *pinfo = &cpm_uart_ports[co->index]; |
1133 | unsigned int i; | ||
1134 | cbd_t __iomem *bdp, *bdbase; | ||
1135 | unsigned char *cp; | ||
1136 | unsigned long flags; | 1210 | unsigned long flags; |
1137 | int nolock = oops_in_progress; | 1211 | int nolock = oops_in_progress; |
1138 | 1212 | ||
@@ -1142,66 +1216,7 @@ static void cpm_uart_console_write(struct console *co, const char *s, | |||
1142 | spin_lock_irqsave(&pinfo->port.lock, flags); | 1216 | spin_lock_irqsave(&pinfo->port.lock, flags); |
1143 | } | 1217 | } |
1144 | 1218 | ||
1145 | /* Get the address of the host memory buffer. | 1219 | cpm_uart_early_write(pinfo, s, count); |
1146 | */ | ||
1147 | bdp = pinfo->tx_cur; | ||
1148 | bdbase = pinfo->tx_bd_base; | ||
1149 | |||
1150 | /* | ||
1151 | * Now, do each character. This is not as bad as it looks | ||
1152 | * since this is a holding FIFO and not a transmitting FIFO. | ||
1153 | * We could add the complexity of filling the entire transmit | ||
1154 | * buffer, but we would just wait longer between accesses...... | ||
1155 | */ | ||
1156 | for (i = 0; i < count; i++, s++) { | ||
1157 | /* Wait for transmitter fifo to empty. | ||
1158 | * Ready indicates output is ready, and xmt is doing | ||
1159 | * that, not that it is ready for us to send. | ||
1160 | */ | ||
1161 | while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) | ||
1162 | ; | ||
1163 | |||
1164 | /* Send the character out. | ||
1165 | * If the buffer address is in the CPM DPRAM, don't | ||
1166 | * convert it. | ||
1167 | */ | ||
1168 | cp = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo); | ||
1169 | *cp = *s; | ||
1170 | |||
1171 | out_be16(&bdp->cbd_datlen, 1); | ||
1172 | setbits16(&bdp->cbd_sc, BD_SC_READY); | ||
1173 | |||
1174 | if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) | ||
1175 | bdp = bdbase; | ||
1176 | else | ||
1177 | bdp++; | ||
1178 | |||
1179 | /* if a LF, also do CR... */ | ||
1180 | if (*s == 10) { | ||
1181 | while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) | ||
1182 | ; | ||
1183 | |||
1184 | cp = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo); | ||
1185 | *cp = 13; | ||
1186 | |||
1187 | out_be16(&bdp->cbd_datlen, 1); | ||
1188 | setbits16(&bdp->cbd_sc, BD_SC_READY); | ||
1189 | |||
1190 | if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) | ||
1191 | bdp = bdbase; | ||
1192 | else | ||
1193 | bdp++; | ||
1194 | } | ||
1195 | } | ||
1196 | |||
1197 | /* | ||
1198 | * Finally, Wait for transmitter & holding register to empty | ||
1199 | * and restore the IER | ||
1200 | */ | ||
1201 | while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) | ||
1202 | ; | ||
1203 | |||
1204 | pinfo->tx_cur = bdp; | ||
1205 | 1220 | ||
1206 | if (unlikely(nolock)) { | 1221 | if (unlikely(nolock)) { |
1207 | local_irq_restore(flags); | 1222 | local_irq_restore(flags); |