aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/serial')
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_core.c95
1 files changed, 94 insertions, 1 deletions
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c
index 93e407ee08b9..1ff80de177db 100644
--- a/drivers/serial/cpm_uart/cpm_uart_core.c
+++ b/drivers/serial/cpm_uart/cpm_uart_core.c
@@ -201,6 +201,10 @@ static void cpm_uart_int_tx(struct uart_port *port)
201 cpm_uart_tx_pump(port); 201 cpm_uart_tx_pump(port);
202} 202}
203 203
204#ifdef CONFIG_CONSOLE_POLL
205static int serial_polled;
206#endif
207
204/* 208/*
205 * Receive characters 209 * Receive characters
206 */ 210 */
@@ -222,6 +226,12 @@ static void cpm_uart_int_rx(struct uart_port *port)
222 */ 226 */
223 bdp = pinfo->rx_cur; 227 bdp = pinfo->rx_cur;
224 for (;;) { 228 for (;;) {
229#ifdef CONFIG_CONSOLE_POLL
230 if (unlikely(serial_polled)) {
231 serial_polled = 0;
232 return;
233 }
234#endif
225 /* get status */ 235 /* get status */
226 status = in_be16(&bdp->cbd_sc); 236 status = in_be16(&bdp->cbd_sc);
227 /* If this one is empty, return happy */ 237 /* If this one is empty, return happy */
@@ -253,7 +263,12 @@ static void cpm_uart_int_rx(struct uart_port *port)
253 goto handle_error; 263 goto handle_error;
254 if (uart_handle_sysrq_char(port, ch)) 264 if (uart_handle_sysrq_char(port, ch))
255 continue; 265 continue;
256 266#ifdef CONFIG_CONSOLE_POLL
267 if (unlikely(serial_polled)) {
268 serial_polled = 0;
269 return;
270 }
271#endif
257 error_return: 272 error_return:
258 tty_insert_flip_char(tty, ch, flg); 273 tty_insert_flip_char(tty, ch, flg);
259 274
@@ -865,6 +880,80 @@ static void cpm_uart_config_port(struct uart_port *port, int flags)
865 cpm_uart_request_port(port); 880 cpm_uart_request_port(port);
866 } 881 }
867} 882}
883
884#ifdef CONFIG_CONSOLE_POLL
885/* Serial polling routines for writing and reading from the uart while
886 * in an interrupt or debug context.
887 */
888
889#define GDB_BUF_SIZE 512 /* power of 2, please */
890
891static char poll_buf[GDB_BUF_SIZE];
892static char *pollp;
893static int poll_chars;
894
895static int poll_wait_key(char *obuf, struct uart_cpm_port *pinfo)
896{
897 u_char c, *cp;
898 volatile cbd_t *bdp;
899 int i;
900
901 /* Get the address of the host memory buffer.
902 */
903 bdp = pinfo->rx_cur;
904 while (bdp->cbd_sc & BD_SC_EMPTY)
905 ;
906
907 /* If the buffer address is in the CPM DPRAM, don't
908 * convert it.
909 */
910 cp = cpm2cpu_addr(bdp->cbd_bufaddr, pinfo);
911
912 if (obuf) {
913 i = c = bdp->cbd_datlen;
914 while (i-- > 0)
915 *obuf++ = *cp++;
916 } else
917 c = *cp;
918 bdp->cbd_sc &= ~(BD_SC_BR | BD_SC_FR | BD_SC_PR | BD_SC_OV | BD_SC_ID);
919 bdp->cbd_sc |= BD_SC_EMPTY;
920
921 if (bdp->cbd_sc & BD_SC_WRAP)
922 bdp = pinfo->rx_bd_base;
923 else
924 bdp++;
925 pinfo->rx_cur = (cbd_t *)bdp;
926
927 return (int)c;
928}
929
930static int cpm_get_poll_char(struct uart_port *port)
931{
932 struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
933
934 if (!serial_polled) {
935 serial_polled = 1;
936 poll_chars = 0;
937 }
938 if (poll_chars <= 0) {
939 poll_chars = poll_wait_key(poll_buf, pinfo);
940 pollp = poll_buf;
941 }
942 poll_chars--;
943 return *pollp++;
944}
945
946static void cpm_put_poll_char(struct uart_port *port,
947 unsigned char c)
948{
949 struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
950 static char ch[2];
951
952 ch[0] = (char)c;
953 cpm_uart_early_write(pinfo->port.line, ch, 1);
954}
955#endif /* CONFIG_CONSOLE_POLL */
956
868static struct uart_ops cpm_uart_pops = { 957static struct uart_ops cpm_uart_pops = {
869 .tx_empty = cpm_uart_tx_empty, 958 .tx_empty = cpm_uart_tx_empty,
870 .set_mctrl = cpm_uart_set_mctrl, 959 .set_mctrl = cpm_uart_set_mctrl,
@@ -882,6 +971,10 @@ static struct uart_ops cpm_uart_pops = {
882 .request_port = cpm_uart_request_port, 971 .request_port = cpm_uart_request_port,
883 .config_port = cpm_uart_config_port, 972 .config_port = cpm_uart_config_port,
884 .verify_port = cpm_uart_verify_port, 973 .verify_port = cpm_uart_verify_port,
974#ifdef CONFIG_CONSOLE_POLL
975 .poll_get_char = cpm_get_poll_char,
976 .poll_put_char = cpm_put_poll_char,
977#endif
885}; 978};
886 979
887struct uart_cpm_port cpm_uart_ports[UART_NR]; 980struct uart_cpm_port cpm_uart_ports[UART_NR];