diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-03-23 23:44:19 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-03-23 23:44:19 -0500 |
commit | 1ebbe2b20091d306453a5cf480a87e6cd28ae76f (patch) | |
tree | f5cd7a0fa69b8b1938cb5a0faed2e7b0628072a5 /drivers/serial | |
parent | ac58c9059da8886b5e8cde012a80266b18ca146e (diff) | |
parent | 674a396c6d2ba0341ebdd7c1c9950f32f018e2dd (diff) |
Merge branch 'linus'
Diffstat (limited to 'drivers/serial')
27 files changed, 289 insertions, 420 deletions
diff --git a/drivers/serial/21285.c b/drivers/serial/21285.c index 8c5c276c5577..7572665a8855 100644 --- a/drivers/serial/21285.c +++ b/drivers/serial/21285.c | |||
@@ -375,23 +375,18 @@ static void serial21285_setup_ports(void) | |||
375 | } | 375 | } |
376 | 376 | ||
377 | #ifdef CONFIG_SERIAL_21285_CONSOLE | 377 | #ifdef CONFIG_SERIAL_21285_CONSOLE |
378 | static void serial21285_console_putchar(struct uart_port *port, int ch) | ||
379 | { | ||
380 | while (*CSR_UARTFLG & 0x20) | ||
381 | barrier(); | ||
382 | *CSR_UARTDR = ch; | ||
383 | } | ||
378 | 384 | ||
379 | static void | 385 | static void |
380 | serial21285_console_write(struct console *co, const char *s, | 386 | serial21285_console_write(struct console *co, const char *s, |
381 | unsigned int count) | 387 | unsigned int count) |
382 | { | 388 | { |
383 | int i; | 389 | uart_console_write(&serial21285_port, s, count, serial21285_console_putchar); |
384 | |||
385 | for (i = 0; i < count; i++) { | ||
386 | while (*CSR_UARTFLG & 0x20) | ||
387 | barrier(); | ||
388 | *CSR_UARTDR = s[i]; | ||
389 | if (s[i] == '\n') { | ||
390 | while (*CSR_UARTFLG & 0x20) | ||
391 | barrier(); | ||
392 | *CSR_UARTDR = '\r'; | ||
393 | } | ||
394 | } | ||
395 | } | 390 | } |
396 | 391 | ||
397 | static void __init | 392 | static void __init |
diff --git a/drivers/serial/68328serial.c b/drivers/serial/68328serial.c index 7f0f35a05dca..b88a7c1158af 100644 --- a/drivers/serial/68328serial.c +++ b/drivers/serial/68328serial.c | |||
@@ -101,8 +101,6 @@ struct tty_driver *serial_driver; | |||
101 | 101 | ||
102 | #define RS_ISR_PASS_LIMIT 256 | 102 | #define RS_ISR_PASS_LIMIT 256 |
103 | 103 | ||
104 | #define _INLINE_ inline | ||
105 | |||
106 | static void change_speed(struct m68k_serial *info); | 104 | static void change_speed(struct m68k_serial *info); |
107 | 105 | ||
108 | /* | 106 | /* |
@@ -262,7 +260,7 @@ static void batten_down_hatches(void) | |||
262 | /* Drop into the debugger */ | 260 | /* Drop into the debugger */ |
263 | } | 261 | } |
264 | 262 | ||
265 | static _INLINE_ void status_handle(struct m68k_serial *info, unsigned short status) | 263 | static void status_handle(struct m68k_serial *info, unsigned short status) |
266 | { | 264 | { |
267 | #if 0 | 265 | #if 0 |
268 | if(status & DCD) { | 266 | if(status & DCD) { |
@@ -289,7 +287,8 @@ static _INLINE_ void status_handle(struct m68k_serial *info, unsigned short stat | |||
289 | return; | 287 | return; |
290 | } | 288 | } |
291 | 289 | ||
292 | static _INLINE_ void receive_chars(struct m68k_serial *info, struct pt_regs *regs, unsigned short rx) | 290 | static void receive_chars(struct m68k_serial *info, struct pt_regs *regs, |
291 | unsigned short rx) | ||
293 | { | 292 | { |
294 | struct tty_struct *tty = info->tty; | 293 | struct tty_struct *tty = info->tty; |
295 | m68328_uart *uart = &uart_addr[info->line]; | 294 | m68328_uart *uart = &uart_addr[info->line]; |
@@ -359,7 +358,7 @@ clear_and_exit: | |||
359 | return; | 358 | return; |
360 | } | 359 | } |
361 | 360 | ||
362 | static _INLINE_ void transmit_chars(struct m68k_serial *info) | 361 | static void transmit_chars(struct m68k_serial *info) |
363 | { | 362 | { |
364 | m68328_uart *uart = &uart_addr[info->line]; | 363 | m68328_uart *uart = &uart_addr[info->line]; |
365 | 364 | ||
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index 7aca22c9976d..5996d3cd0ed8 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c | |||
@@ -2182,6 +2182,14 @@ static inline void wait_for_xmitr(struct uart_8250_port *up, int bits) | |||
2182 | } | 2182 | } |
2183 | } | 2183 | } |
2184 | 2184 | ||
2185 | static void serial8250_console_putchar(struct uart_port *port, int ch) | ||
2186 | { | ||
2187 | struct uart_8250_port *up = (struct uart_8250_port *)port; | ||
2188 | |||
2189 | wait_for_xmitr(up, UART_LSR_THRE); | ||
2190 | serial_out(up, UART_TX, ch); | ||
2191 | } | ||
2192 | |||
2185 | /* | 2193 | /* |
2186 | * Print a string to the serial port trying not to disturb | 2194 | * Print a string to the serial port trying not to disturb |
2187 | * any possible real use of the port... | 2195 | * any possible real use of the port... |
@@ -2193,7 +2201,6 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count) | |||
2193 | { | 2201 | { |
2194 | struct uart_8250_port *up = &serial8250_ports[co->index]; | 2202 | struct uart_8250_port *up = &serial8250_ports[co->index]; |
2195 | unsigned int ier; | 2203 | unsigned int ier; |
2196 | int i; | ||
2197 | 2204 | ||
2198 | touch_nmi_watchdog(); | 2205 | touch_nmi_watchdog(); |
2199 | 2206 | ||
@@ -2207,22 +2214,7 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count) | |||
2207 | else | 2214 | else |
2208 | serial_out(up, UART_IER, 0); | 2215 | serial_out(up, UART_IER, 0); |
2209 | 2216 | ||
2210 | /* | 2217 | uart_console_write(&up->port, s, count, serial8250_console_putchar); |
2211 | * Now, do each character | ||
2212 | */ | ||
2213 | for (i = 0; i < count; i++, s++) { | ||
2214 | wait_for_xmitr(up, UART_LSR_THRE); | ||
2215 | |||
2216 | /* | ||
2217 | * Send the character out. | ||
2218 | * If a LF, also do CR... | ||
2219 | */ | ||
2220 | serial_out(up, UART_TX, *s); | ||
2221 | if (*s == 10) { | ||
2222 | wait_for_xmitr(up, UART_LSR_THRE); | ||
2223 | serial_out(up, UART_TX, 13); | ||
2224 | } | ||
2225 | } | ||
2226 | 2218 | ||
2227 | /* | 2219 | /* |
2228 | * Finally, wait for transmitter to become empty | 2220 | * Finally, wait for transmitter to become empty |
diff --git a/drivers/serial/8250_early.c b/drivers/serial/8250_early.c index 59ba5d993b4b..7e511199b4c5 100644 --- a/drivers/serial/8250_early.c +++ b/drivers/serial/8250_early.c | |||
@@ -74,7 +74,7 @@ static void __init wait_for_xmitr(struct uart_port *port) | |||
74 | } | 74 | } |
75 | } | 75 | } |
76 | 76 | ||
77 | static void __init putc(struct uart_port *port, unsigned char c) | 77 | static void __init putc(struct uart_port *port, int c) |
78 | { | 78 | { |
79 | wait_for_xmitr(port); | 79 | wait_for_xmitr(port); |
80 | serial_out(port, UART_TX, c); | 80 | serial_out(port, UART_TX, c); |
@@ -89,12 +89,7 @@ static void __init early_uart_write(struct console *console, const char *s, unsi | |||
89 | ier = serial_in(port, UART_IER); | 89 | ier = serial_in(port, UART_IER); |
90 | serial_out(port, UART_IER, 0); | 90 | serial_out(port, UART_IER, 0); |
91 | 91 | ||
92 | while (*s && count-- > 0) { | 92 | uart_console_write(port, s, count, putc); |
93 | putc(port, *s); | ||
94 | if (*s == '\n') | ||
95 | putc(port, '\r'); | ||
96 | s++; | ||
97 | } | ||
98 | 93 | ||
99 | /* Wait for transmitter to become empty and restore the IER */ | 94 | /* Wait for transmitter to become empty and restore the IER */ |
100 | wait_for_xmitr(port); | 95 | wait_for_xmitr(port); |
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 89e5413cc2a3..c66ef96c71b4 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig | |||
@@ -866,7 +866,7 @@ config SERIAL_M32R_PLDSIO | |||
866 | 866 | ||
867 | config SERIAL_TXX9 | 867 | config SERIAL_TXX9 |
868 | bool "TMPTX39XX/49XX SIO support" | 868 | bool "TMPTX39XX/49XX SIO support" |
869 | depends HAS_TXX9_SERIAL && BROKEN | 869 | depends HAS_TXX9_SERIAL |
870 | select SERIAL_CORE | 870 | select SERIAL_CORE |
871 | default y | 871 | default y |
872 | 872 | ||
diff --git a/drivers/serial/amba-pl010.c b/drivers/serial/amba-pl010.c index 321a3b3a5728..e04d5e82d9ae 100644 --- a/drivers/serial/amba-pl010.c +++ b/drivers/serial/amba-pl010.c | |||
@@ -591,12 +591,18 @@ static struct uart_amba_port amba_ports[UART_NR] = { | |||
591 | 591 | ||
592 | #ifdef CONFIG_SERIAL_AMBA_PL010_CONSOLE | 592 | #ifdef CONFIG_SERIAL_AMBA_PL010_CONSOLE |
593 | 593 | ||
594 | static void pl010_console_putchar(struct uart_port *port, int ch) | ||
595 | { | ||
596 | while (!UART_TX_READY(UART_GET_FR(port))) | ||
597 | barrier(); | ||
598 | UART_PUT_CHAR(port, ch); | ||
599 | } | ||
600 | |||
594 | static void | 601 | static void |
595 | pl010_console_write(struct console *co, const char *s, unsigned int count) | 602 | pl010_console_write(struct console *co, const char *s, unsigned int count) |
596 | { | 603 | { |
597 | struct uart_port *port = &amba_ports[co->index].port; | 604 | struct uart_port *port = &amba_ports[co->index].port; |
598 | unsigned int status, old_cr; | 605 | unsigned int status, old_cr; |
599 | int i; | ||
600 | 606 | ||
601 | /* | 607 | /* |
602 | * First save the CR then disable the interrupts | 608 | * First save the CR then disable the interrupts |
@@ -604,21 +610,7 @@ pl010_console_write(struct console *co, const char *s, unsigned int count) | |||
604 | old_cr = UART_GET_CR(port); | 610 | old_cr = UART_GET_CR(port); |
605 | UART_PUT_CR(port, UART01x_CR_UARTEN); | 611 | UART_PUT_CR(port, UART01x_CR_UARTEN); |
606 | 612 | ||
607 | /* | 613 | uart_console_write(port, s, count, pl010_console_putchar); |
608 | * Now, do each character | ||
609 | */ | ||
610 | for (i = 0; i < count; i++) { | ||
611 | do { | ||
612 | status = UART_GET_FR(port); | ||
613 | } while (!UART_TX_READY(status)); | ||
614 | UART_PUT_CHAR(port, s[i]); | ||
615 | if (s[i] == '\n') { | ||
616 | do { | ||
617 | status = UART_GET_FR(port); | ||
618 | } while (!UART_TX_READY(status)); | ||
619 | UART_PUT_CHAR(port, '\r'); | ||
620 | } | ||
621 | } | ||
622 | 614 | ||
623 | /* | 615 | /* |
624 | * Finally, wait for transmitter to become empty | 616 | * Finally, wait for transmitter to become empty |
diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c index 034a029e356e..3d966cfc9a38 100644 --- a/drivers/serial/amba-pl011.c +++ b/drivers/serial/amba-pl011.c | |||
@@ -587,14 +587,12 @@ static struct uart_amba_port *amba_ports[UART_NR]; | |||
587 | 587 | ||
588 | #ifdef CONFIG_SERIAL_AMBA_PL011_CONSOLE | 588 | #ifdef CONFIG_SERIAL_AMBA_PL011_CONSOLE |
589 | 589 | ||
590 | static inline void | 590 | static void pl011_console_putchar(struct uart_port *port, int ch) |
591 | pl011_console_write_char(struct uart_amba_port *uap, char ch) | ||
592 | { | 591 | { |
593 | unsigned int status; | 592 | struct uart_amba_port *uap = (struct uart_amba_port *)port; |
594 | 593 | ||
595 | do { | 594 | while (readw(uap->port.membase + UART01x_FR) & UART01x_FR_TXFF) |
596 | status = readw(uap->port.membase + UART01x_FR); | 595 | barrier(); |
597 | } while (status & UART01x_FR_TXFF); | ||
598 | writew(ch, uap->port.membase + UART01x_DR); | 596 | writew(ch, uap->port.membase + UART01x_DR); |
599 | } | 597 | } |
600 | 598 | ||
@@ -603,7 +601,6 @@ pl011_console_write(struct console *co, const char *s, unsigned int count) | |||
603 | { | 601 | { |
604 | struct uart_amba_port *uap = amba_ports[co->index]; | 602 | struct uart_amba_port *uap = amba_ports[co->index]; |
605 | unsigned int status, old_cr, new_cr; | 603 | unsigned int status, old_cr, new_cr; |
606 | int i; | ||
607 | 604 | ||
608 | clk_enable(uap->clk); | 605 | clk_enable(uap->clk); |
609 | 606 | ||
@@ -615,14 +612,7 @@ pl011_console_write(struct console *co, const char *s, unsigned int count) | |||
615 | new_cr |= UART01x_CR_UARTEN | UART011_CR_TXE; | 612 | new_cr |= UART01x_CR_UARTEN | UART011_CR_TXE; |
616 | writew(new_cr, uap->port.membase + UART011_CR); | 613 | writew(new_cr, uap->port.membase + UART011_CR); |
617 | 614 | ||
618 | /* | 615 | uart_console_write(&uap->port, s, count, pl011_console_putchar); |
619 | * Now, do each character | ||
620 | */ | ||
621 | for (i = 0; i < count; i++) { | ||
622 | pl011_console_write_char(uap, s[i]); | ||
623 | if (s[i] == '\n') | ||
624 | pl011_console_write_char(uap, '\r'); | ||
625 | } | ||
626 | 616 | ||
627 | /* | 617 | /* |
628 | * Finally, wait for transmitter to become empty | 618 | * Finally, wait for transmitter to become empty |
diff --git a/drivers/serial/at91_serial.c b/drivers/serial/at91_serial.c index 2113feb75c39..6547fe0cef96 100644 --- a/drivers/serial/at91_serial.c +++ b/drivers/serial/at91_serial.c | |||
@@ -711,6 +711,12 @@ void __init at91_register_uart(int idx, int port) | |||
711 | } | 711 | } |
712 | 712 | ||
713 | #ifdef CONFIG_SERIAL_AT91_CONSOLE | 713 | #ifdef CONFIG_SERIAL_AT91_CONSOLE |
714 | static void at91_console_putchar(struct uart_port *port, int ch) | ||
715 | { | ||
716 | while (!(UART_GET_CSR(port) & AT91_US_TXRDY)) | ||
717 | barrier(); | ||
718 | UART_PUT_CHAR(port, ch); | ||
719 | } | ||
714 | 720 | ||
715 | /* | 721 | /* |
716 | * Interrupts are disabled on entering | 722 | * Interrupts are disabled on entering |
@@ -718,7 +724,7 @@ void __init at91_register_uart(int idx, int port) | |||
718 | static void at91_console_write(struct console *co, const char *s, u_int count) | 724 | static void at91_console_write(struct console *co, const char *s, u_int count) |
719 | { | 725 | { |
720 | struct uart_port *port = at91_ports + co->index; | 726 | struct uart_port *port = at91_ports + co->index; |
721 | unsigned int status, i, imr; | 727 | unsigned int status, imr; |
722 | 728 | ||
723 | /* | 729 | /* |
724 | * First, save IMR and then disable interrupts | 730 | * First, save IMR and then disable interrupts |
@@ -726,21 +732,7 @@ static void at91_console_write(struct console *co, const char *s, u_int count) | |||
726 | imr = UART_GET_IMR(port); /* get interrupt mask */ | 732 | imr = UART_GET_IMR(port); /* get interrupt mask */ |
727 | UART_PUT_IDR(port, AT91_US_RXRDY | AT91_US_TXRDY); | 733 | UART_PUT_IDR(port, AT91_US_RXRDY | AT91_US_TXRDY); |
728 | 734 | ||
729 | /* | 735 | uart_console_write(port, s, count, at91_console_putchar); |
730 | * Now, do each character | ||
731 | */ | ||
732 | for (i = 0; i < count; i++) { | ||
733 | do { | ||
734 | status = UART_GET_CSR(port); | ||
735 | } while (!(status & AT91_US_TXRDY)); | ||
736 | UART_PUT_CHAR(port, s[i]); | ||
737 | if (s[i] == '\n') { | ||
738 | do { | ||
739 | status = UART_GET_CSR(port); | ||
740 | } while (!(status & AT91_US_TXRDY)); | ||
741 | UART_PUT_CHAR(port, '\r'); | ||
742 | } | ||
743 | } | ||
744 | 736 | ||
745 | /* | 737 | /* |
746 | * Finally, wait for transmitter to become empty | 738 | * Finally, wait for transmitter to become empty |
diff --git a/drivers/serial/au1x00_uart.c b/drivers/serial/au1x00_uart.c index 344022fe53ef..948880ac5878 100644 --- a/drivers/serial/au1x00_uart.c +++ b/drivers/serial/au1x00_uart.c | |||
@@ -133,13 +133,12 @@ static const struct serial_uart_config uart_config[PORT_MAX_8250+1] = { | |||
133 | { "AU1X00_UART",16, UART_CLEAR_FIFO | UART_USE_FIFO }, | 133 | { "AU1X00_UART",16, UART_CLEAR_FIFO | UART_USE_FIFO }, |
134 | }; | 134 | }; |
135 | 135 | ||
136 | static _INLINE_ unsigned int serial_in(struct uart_8250_port *up, int offset) | 136 | static unsigned int serial_in(struct uart_8250_port *up, int offset) |
137 | { | 137 | { |
138 | return au_readl((unsigned long)up->port.membase + offset); | 138 | return au_readl((unsigned long)up->port.membase + offset); |
139 | } | 139 | } |
140 | 140 | ||
141 | static _INLINE_ void | 141 | static void serial_out(struct uart_8250_port *up, int offset, int value) |
142 | serial_out(struct uart_8250_port *up, int offset, int value) | ||
143 | { | 142 | { |
144 | au_writel(value, (unsigned long)up->port.membase + offset); | 143 | au_writel(value, (unsigned long)up->port.membase + offset); |
145 | } | 144 | } |
@@ -237,7 +236,7 @@ static void serial8250_enable_ms(struct uart_port *port) | |||
237 | serial_out(up, UART_IER, up->ier); | 236 | serial_out(up, UART_IER, up->ier); |
238 | } | 237 | } |
239 | 238 | ||
240 | static _INLINE_ void | 239 | static void |
241 | receive_chars(struct uart_8250_port *up, int *status, struct pt_regs *regs) | 240 | receive_chars(struct uart_8250_port *up, int *status, struct pt_regs *regs) |
242 | { | 241 | { |
243 | struct tty_struct *tty = up->port.info->tty; | 242 | struct tty_struct *tty = up->port.info->tty; |
@@ -312,7 +311,7 @@ receive_chars(struct uart_8250_port *up, int *status, struct pt_regs *regs) | |||
312 | spin_lock(&up->port.lock); | 311 | spin_lock(&up->port.lock); |
313 | } | 312 | } |
314 | 313 | ||
315 | static _INLINE_ void transmit_chars(struct uart_8250_port *up) | 314 | static void transmit_chars(struct uart_8250_port *up) |
316 | { | 315 | { |
317 | struct circ_buf *xmit = &up->port.info->xmit; | 316 | struct circ_buf *xmit = &up->port.info->xmit; |
318 | int count; | 317 | int count; |
@@ -346,7 +345,7 @@ static _INLINE_ void transmit_chars(struct uart_8250_port *up) | |||
346 | serial8250_stop_tx(&up->port); | 345 | serial8250_stop_tx(&up->port); |
347 | } | 346 | } |
348 | 347 | ||
349 | static _INLINE_ void check_modem_status(struct uart_8250_port *up) | 348 | static void check_modem_status(struct uart_8250_port *up) |
350 | { | 349 | { |
351 | int status; | 350 | int status; |
352 | 351 | ||
@@ -1121,6 +1120,14 @@ static inline void wait_for_xmitr(struct uart_8250_port *up) | |||
1121 | } | 1120 | } |
1122 | } | 1121 | } |
1123 | 1122 | ||
1123 | static void au1x00_console_putchar(struct uart_port *port, int ch) | ||
1124 | { | ||
1125 | struct uart_8250_port *up = (struct uart_8250_port *)port; | ||
1126 | |||
1127 | wait_for_xmitr(up); | ||
1128 | serial_out(up, UART_TX, ch); | ||
1129 | } | ||
1130 | |||
1124 | /* | 1131 | /* |
1125 | * Print a string to the serial port trying not to disturb | 1132 | * Print a string to the serial port trying not to disturb |
1126 | * any possible real use of the port... | 1133 | * any possible real use of the port... |
@@ -1132,7 +1139,6 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count) | |||
1132 | { | 1139 | { |
1133 | struct uart_8250_port *up = &serial8250_ports[co->index]; | 1140 | struct uart_8250_port *up = &serial8250_ports[co->index]; |
1134 | unsigned int ier; | 1141 | unsigned int ier; |
1135 | int i; | ||
1136 | 1142 | ||
1137 | /* | 1143 | /* |
1138 | * First save the UER then disable the interrupts | 1144 | * First save the UER then disable the interrupts |
@@ -1140,22 +1146,7 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count) | |||
1140 | ier = serial_in(up, UART_IER); | 1146 | ier = serial_in(up, UART_IER); |
1141 | serial_out(up, UART_IER, 0); | 1147 | serial_out(up, UART_IER, 0); |
1142 | 1148 | ||
1143 | /* | 1149 | uart_console_write(&up->port, s, count, au1x00_console_putchar); |
1144 | * Now, do each character | ||
1145 | */ | ||
1146 | for (i = 0; i < count; i++, s++) { | ||
1147 | wait_for_xmitr(up); | ||
1148 | |||
1149 | /* | ||
1150 | * Send the character out. | ||
1151 | * If a LF, also do CR... | ||
1152 | */ | ||
1153 | serial_out(up, UART_TX, *s); | ||
1154 | if (*s == 10) { | ||
1155 | wait_for_xmitr(up); | ||
1156 | serial_out(up, UART_TX, 13); | ||
1157 | } | ||
1158 | } | ||
1159 | 1150 | ||
1160 | /* | 1151 | /* |
1161 | * Finally, wait for transmitter to become empty | 1152 | * Finally, wait for transmitter to become empty |
diff --git a/drivers/serial/clps711x.c b/drivers/serial/clps711x.c index ce7b2e4ecd17..2691112c84ad 100644 --- a/drivers/serial/clps711x.c +++ b/drivers/serial/clps711x.c | |||
@@ -424,6 +424,13 @@ static struct uart_port clps711x_ports[UART_NR] = { | |||
424 | }; | 424 | }; |
425 | 425 | ||
426 | #ifdef CONFIG_SERIAL_CLPS711X_CONSOLE | 426 | #ifdef CONFIG_SERIAL_CLPS711X_CONSOLE |
427 | static void clps711xuart_console_putchar(struct uart_port *port, int ch) | ||
428 | { | ||
429 | while (clps_readl(SYSFLG(port)) & SYSFLG_UTXFF) | ||
430 | barrier(); | ||
431 | clps_writel(ch, UARTDR(port)); | ||
432 | } | ||
433 | |||
427 | /* | 434 | /* |
428 | * Print a string to the serial port trying not to disturb | 435 | * Print a string to the serial port trying not to disturb |
429 | * any possible real use of the port... | 436 | * any possible real use of the port... |
@@ -438,7 +445,6 @@ clps711xuart_console_write(struct console *co, const char *s, | |||
438 | { | 445 | { |
439 | struct uart_port *port = clps711x_ports + co->index; | 446 | struct uart_port *port = clps711x_ports + co->index; |
440 | unsigned int status, syscon; | 447 | unsigned int status, syscon; |
441 | int i; | ||
442 | 448 | ||
443 | /* | 449 | /* |
444 | * Ensure that the port is enabled. | 450 | * Ensure that the port is enabled. |
@@ -446,21 +452,7 @@ clps711xuart_console_write(struct console *co, const char *s, | |||
446 | syscon = clps_readl(SYSCON(port)); | 452 | syscon = clps_readl(SYSCON(port)); |
447 | clps_writel(syscon | SYSCON_UARTEN, SYSCON(port)); | 453 | clps_writel(syscon | SYSCON_UARTEN, SYSCON(port)); |
448 | 454 | ||
449 | /* | 455 | uart_console_write(port, s, count, clps711xuart_console_putchar); |
450 | * Now, do each character | ||
451 | */ | ||
452 | for (i = 0; i < count; i++) { | ||
453 | do { | ||
454 | status = clps_readl(SYSFLG(port)); | ||
455 | } while (status & SYSFLG_UTXFF); | ||
456 | clps_writel(s[i], UARTDR(port)); | ||
457 | if (s[i] == '\n') { | ||
458 | do { | ||
459 | status = clps_readl(SYSFLG(port)); | ||
460 | } while (status & SYSFLG_UTXFF); | ||
461 | clps_writel('\r', UARTDR(port)); | ||
462 | } | ||
463 | } | ||
464 | 456 | ||
465 | /* | 457 | /* |
466 | * Finally, wait for transmitter to become empty | 458 | * Finally, wait for transmitter to become empty |
diff --git a/drivers/serial/crisv10.c b/drivers/serial/crisv10.c index be12623d8544..89700141f87e 100644 --- a/drivers/serial/crisv10.c +++ b/drivers/serial/crisv10.c | |||
@@ -481,8 +481,6 @@ static char *serial_version = "$Revision: 1.25 $"; | |||
481 | #include "serial_compat.h" | 481 | #include "serial_compat.h" |
482 | #endif | 482 | #endif |
483 | 483 | ||
484 | #define _INLINE_ inline | ||
485 | |||
486 | struct tty_driver *serial_driver; | 484 | struct tty_driver *serial_driver; |
487 | 485 | ||
488 | /* serial subtype definitions */ | 486 | /* serial subtype definitions */ |
@@ -591,8 +589,6 @@ static void rs_throttle(struct tty_struct * tty); | |||
591 | static void rs_wait_until_sent(struct tty_struct *tty, int timeout); | 589 | static void rs_wait_until_sent(struct tty_struct *tty, int timeout); |
592 | static int rs_write(struct tty_struct * tty, int from_user, | 590 | static int rs_write(struct tty_struct * tty, int from_user, |
593 | const unsigned char *buf, int count); | 591 | const unsigned char *buf, int count); |
594 | extern _INLINE_ int rs_raw_write(struct tty_struct * tty, int from_user, | ||
595 | const unsigned char *buf, int count); | ||
596 | #ifdef CONFIG_ETRAX_RS485 | 592 | #ifdef CONFIG_ETRAX_RS485 |
597 | static int e100_write_rs485(struct tty_struct * tty, int from_user, | 593 | static int e100_write_rs485(struct tty_struct * tty, int from_user, |
598 | const unsigned char *buf, int count); | 594 | const unsigned char *buf, int count); |
@@ -1538,8 +1534,7 @@ e100_enable_rxdma_irq(struct e100_serial *info) | |||
1538 | 1534 | ||
1539 | /* the tx DMA uses only dma_descr interrupt */ | 1535 | /* the tx DMA uses only dma_descr interrupt */ |
1540 | 1536 | ||
1541 | static _INLINE_ void | 1537 | static void e100_disable_txdma_irq(struct e100_serial *info) |
1542 | e100_disable_txdma_irq(struct e100_serial *info) | ||
1543 | { | 1538 | { |
1544 | #ifdef SERIAL_DEBUG_INTR | 1539 | #ifdef SERIAL_DEBUG_INTR |
1545 | printk("txdma_irq(%d): 0\n",info->line); | 1540 | printk("txdma_irq(%d): 0\n",info->line); |
@@ -1548,8 +1543,7 @@ e100_disable_txdma_irq(struct e100_serial *info) | |||
1548 | *R_IRQ_MASK2_CLR = info->irq; | 1543 | *R_IRQ_MASK2_CLR = info->irq; |
1549 | } | 1544 | } |
1550 | 1545 | ||
1551 | static _INLINE_ void | 1546 | static void e100_enable_txdma_irq(struct e100_serial *info) |
1552 | e100_enable_txdma_irq(struct e100_serial *info) | ||
1553 | { | 1547 | { |
1554 | #ifdef SERIAL_DEBUG_INTR | 1548 | #ifdef SERIAL_DEBUG_INTR |
1555 | printk("txdma_irq(%d): 1\n",info->line); | 1549 | printk("txdma_irq(%d): 1\n",info->line); |
@@ -1558,8 +1552,7 @@ e100_enable_txdma_irq(struct e100_serial *info) | |||
1558 | *R_IRQ_MASK2_SET = info->irq; | 1552 | *R_IRQ_MASK2_SET = info->irq; |
1559 | } | 1553 | } |
1560 | 1554 | ||
1561 | static _INLINE_ void | 1555 | static void e100_disable_txdma_channel(struct e100_serial *info) |
1562 | e100_disable_txdma_channel(struct e100_serial *info) | ||
1563 | { | 1556 | { |
1564 | unsigned long flags; | 1557 | unsigned long flags; |
1565 | 1558 | ||
@@ -1599,8 +1592,7 @@ e100_disable_txdma_channel(struct e100_serial *info) | |||
1599 | } | 1592 | } |
1600 | 1593 | ||
1601 | 1594 | ||
1602 | static _INLINE_ void | 1595 | static void e100_enable_txdma_channel(struct e100_serial *info) |
1603 | e100_enable_txdma_channel(struct e100_serial *info) | ||
1604 | { | 1596 | { |
1605 | unsigned long flags; | 1597 | unsigned long flags; |
1606 | 1598 | ||
@@ -1625,8 +1617,7 @@ e100_enable_txdma_channel(struct e100_serial *info) | |||
1625 | restore_flags(flags); | 1617 | restore_flags(flags); |
1626 | } | 1618 | } |
1627 | 1619 | ||
1628 | static _INLINE_ void | 1620 | static void e100_disable_rxdma_channel(struct e100_serial *info) |
1629 | e100_disable_rxdma_channel(struct e100_serial *info) | ||
1630 | { | 1621 | { |
1631 | unsigned long flags; | 1622 | unsigned long flags; |
1632 | 1623 | ||
@@ -1665,8 +1656,7 @@ e100_disable_rxdma_channel(struct e100_serial *info) | |||
1665 | } | 1656 | } |
1666 | 1657 | ||
1667 | 1658 | ||
1668 | static _INLINE_ void | 1659 | static void e100_enable_rxdma_channel(struct e100_serial *info) |
1669 | e100_enable_rxdma_channel(struct e100_serial *info) | ||
1670 | { | 1660 | { |
1671 | unsigned long flags; | 1661 | unsigned long flags; |
1672 | 1662 | ||
@@ -1913,9 +1903,7 @@ rs_start(struct tty_struct *tty) | |||
1913 | * This routine is used by the interrupt handler to schedule | 1903 | * This routine is used by the interrupt handler to schedule |
1914 | * processing in the software interrupt portion of the driver. | 1904 | * processing in the software interrupt portion of the driver. |
1915 | */ | 1905 | */ |
1916 | static _INLINE_ void | 1906 | static void rs_sched_event(struct e100_serial *info, int event) |
1917 | rs_sched_event(struct e100_serial *info, | ||
1918 | int event) | ||
1919 | { | 1907 | { |
1920 | if (info->event & (1 << event)) | 1908 | if (info->event & (1 << event)) |
1921 | return; | 1909 | return; |
@@ -2155,8 +2143,9 @@ add_char_and_flag(struct e100_serial *info, unsigned char data, unsigned char fl | |||
2155 | return 1; | 2143 | return 1; |
2156 | } | 2144 | } |
2157 | 2145 | ||
2158 | extern _INLINE_ unsigned int | 2146 | static unsigned int handle_descr_data(struct e100_serial *info, |
2159 | handle_descr_data(struct e100_serial *info, struct etrax_dma_descr *descr, unsigned int recvl) | 2147 | struct etrax_dma_descr *descr, |
2148 | unsigned int recvl) | ||
2160 | { | 2149 | { |
2161 | struct etrax_recv_buffer *buffer = phys_to_virt(descr->buf) - sizeof *buffer; | 2150 | struct etrax_recv_buffer *buffer = phys_to_virt(descr->buf) - sizeof *buffer; |
2162 | 2151 | ||
@@ -2182,8 +2171,7 @@ handle_descr_data(struct e100_serial *info, struct etrax_dma_descr *descr, unsig | |||
2182 | return recvl; | 2171 | return recvl; |
2183 | } | 2172 | } |
2184 | 2173 | ||
2185 | static _INLINE_ unsigned int | 2174 | static unsigned int handle_all_descr_data(struct e100_serial *info) |
2186 | handle_all_descr_data(struct e100_serial *info) | ||
2187 | { | 2175 | { |
2188 | struct etrax_dma_descr *descr; | 2176 | struct etrax_dma_descr *descr; |
2189 | unsigned int recvl; | 2177 | unsigned int recvl; |
@@ -2230,8 +2218,7 @@ handle_all_descr_data(struct e100_serial *info) | |||
2230 | return ret; | 2218 | return ret; |
2231 | } | 2219 | } |
2232 | 2220 | ||
2233 | static _INLINE_ void | 2221 | static void receive_chars_dma(struct e100_serial *info) |
2234 | receive_chars_dma(struct e100_serial *info) | ||
2235 | { | 2222 | { |
2236 | struct tty_struct *tty; | 2223 | struct tty_struct *tty; |
2237 | unsigned char rstat; | 2224 | unsigned char rstat; |
@@ -2292,8 +2279,7 @@ receive_chars_dma(struct e100_serial *info) | |||
2292 | *info->icmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, restart); | 2279 | *info->icmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, restart); |
2293 | } | 2280 | } |
2294 | 2281 | ||
2295 | static _INLINE_ int | 2282 | static int start_recv_dma(struct e100_serial *info) |
2296 | start_recv_dma(struct e100_serial *info) | ||
2297 | { | 2283 | { |
2298 | struct etrax_dma_descr *descr = info->rec_descr; | 2284 | struct etrax_dma_descr *descr = info->rec_descr; |
2299 | struct etrax_recv_buffer *buffer; | 2285 | struct etrax_recv_buffer *buffer; |
@@ -2348,11 +2334,6 @@ start_receive(struct e100_serial *info) | |||
2348 | } | 2334 | } |
2349 | 2335 | ||
2350 | 2336 | ||
2351 | static _INLINE_ void | ||
2352 | status_handle(struct e100_serial *info, unsigned short status) | ||
2353 | { | ||
2354 | } | ||
2355 | |||
2356 | /* the bits in the MASK2 register are laid out like this: | 2337 | /* the bits in the MASK2 register are laid out like this: |
2357 | DMAI_EOP DMAI_DESCR DMAO_EOP DMAO_DESCR | 2338 | DMAI_EOP DMAI_DESCR DMAO_EOP DMAO_DESCR |
2358 | where I is the input channel and O is the output channel for the port. | 2339 | where I is the input channel and O is the output channel for the port. |
@@ -2454,8 +2435,7 @@ rec_interrupt(int irq, void *dev_id, struct pt_regs * regs) | |||
2454 | return IRQ_RETVAL(handled); | 2435 | return IRQ_RETVAL(handled); |
2455 | } /* rec_interrupt */ | 2436 | } /* rec_interrupt */ |
2456 | 2437 | ||
2457 | static _INLINE_ int | 2438 | static int force_eop_if_needed(struct e100_serial *info) |
2458 | force_eop_if_needed(struct e100_serial *info) | ||
2459 | { | 2439 | { |
2460 | /* We check data_avail bit to determine if data has | 2440 | /* We check data_avail bit to determine if data has |
2461 | * arrived since last time | 2441 | * arrived since last time |
@@ -2499,8 +2479,7 @@ force_eop_if_needed(struct e100_serial *info) | |||
2499 | return 1; | 2479 | return 1; |
2500 | } | 2480 | } |
2501 | 2481 | ||
2502 | extern _INLINE_ void | 2482 | static void flush_to_flip_buffer(struct e100_serial *info) |
2503 | flush_to_flip_buffer(struct e100_serial *info) | ||
2504 | { | 2483 | { |
2505 | struct tty_struct *tty; | 2484 | struct tty_struct *tty; |
2506 | struct etrax_recv_buffer *buffer; | 2485 | struct etrax_recv_buffer *buffer; |
@@ -2611,8 +2590,7 @@ flush_to_flip_buffer(struct e100_serial *info) | |||
2611 | tty_flip_buffer_push(tty); | 2590 | tty_flip_buffer_push(tty); |
2612 | } | 2591 | } |
2613 | 2592 | ||
2614 | static _INLINE_ void | 2593 | static void check_flush_timeout(struct e100_serial *info) |
2615 | check_flush_timeout(struct e100_serial *info) | ||
2616 | { | 2594 | { |
2617 | /* Flip what we've got (if we can) */ | 2595 | /* Flip what we've got (if we can) */ |
2618 | flush_to_flip_buffer(info); | 2596 | flush_to_flip_buffer(info); |
@@ -2741,7 +2719,7 @@ TODO: The break will be delayed until an F or V character is received. | |||
2741 | 2719 | ||
2742 | */ | 2720 | */ |
2743 | 2721 | ||
2744 | extern _INLINE_ | 2722 | static |
2745 | struct e100_serial * handle_ser_rx_interrupt_no_dma(struct e100_serial *info) | 2723 | struct e100_serial * handle_ser_rx_interrupt_no_dma(struct e100_serial *info) |
2746 | { | 2724 | { |
2747 | unsigned long data_read; | 2725 | unsigned long data_read; |
@@ -2875,8 +2853,7 @@ more_data: | |||
2875 | return info; | 2853 | return info; |
2876 | } | 2854 | } |
2877 | 2855 | ||
2878 | extern _INLINE_ | 2856 | static struct e100_serial* handle_ser_rx_interrupt(struct e100_serial *info) |
2879 | struct e100_serial* handle_ser_rx_interrupt(struct e100_serial *info) | ||
2880 | { | 2857 | { |
2881 | unsigned char rstat; | 2858 | unsigned char rstat; |
2882 | 2859 | ||
@@ -2995,7 +2972,7 @@ struct e100_serial* handle_ser_rx_interrupt(struct e100_serial *info) | |||
2995 | return info; | 2972 | return info; |
2996 | } /* handle_ser_rx_interrupt */ | 2973 | } /* handle_ser_rx_interrupt */ |
2997 | 2974 | ||
2998 | extern _INLINE_ void handle_ser_tx_interrupt(struct e100_serial *info) | 2975 | static void handle_ser_tx_interrupt(struct e100_serial *info) |
2999 | { | 2976 | { |
3000 | unsigned long flags; | 2977 | unsigned long flags; |
3001 | 2978 | ||
@@ -3621,9 +3598,8 @@ rs_flush_chars(struct tty_struct *tty) | |||
3621 | restore_flags(flags); | 3598 | restore_flags(flags); |
3622 | } | 3599 | } |
3623 | 3600 | ||
3624 | extern _INLINE_ int | 3601 | static int rs_raw_write(struct tty_struct * tty, int from_user, |
3625 | rs_raw_write(struct tty_struct * tty, int from_user, | 3602 | const unsigned char *buf, int count) |
3626 | const unsigned char *buf, int count) | ||
3627 | { | 3603 | { |
3628 | int c, ret = 0; | 3604 | int c, ret = 0; |
3629 | struct e100_serial *info = (struct e100_serial *)tty->driver_data; | 3605 | struct e100_serial *info = (struct e100_serial *)tty->driver_data; |
@@ -4710,7 +4686,7 @@ rs_open(struct tty_struct *tty, struct file * filp) | |||
4710 | * /proc fs routines.... | 4686 | * /proc fs routines.... |
4711 | */ | 4687 | */ |
4712 | 4688 | ||
4713 | extern _INLINE_ int line_info(char *buf, struct e100_serial *info) | 4689 | static int line_info(char *buf, struct e100_serial *info) |
4714 | { | 4690 | { |
4715 | char stat_buf[30]; | 4691 | char stat_buf[30]; |
4716 | int ret; | 4692 | int ret; |
diff --git a/drivers/serial/dz.c b/drivers/serial/dz.c index ba5541de673b..bf71bad5c34f 100644 --- a/drivers/serial/dz.c +++ b/drivers/serial/dz.c | |||
@@ -674,11 +674,12 @@ static void dz_reset(struct dz_port *dport) | |||
674 | } | 674 | } |
675 | 675 | ||
676 | #ifdef CONFIG_SERIAL_DZ_CONSOLE | 676 | #ifdef CONFIG_SERIAL_DZ_CONSOLE |
677 | static void dz_console_put_char(struct dz_port *dport, unsigned char ch) | 677 | static void dz_console_putchar(struct uart_port *port, int ch) |
678 | { | 678 | { |
679 | struct dz_port *dport = (struct dz_port *)uport; | ||
679 | unsigned long flags; | 680 | unsigned long flags; |
680 | int loops = 2500; | 681 | int loops = 2500; |
681 | unsigned short tmp = ch; | 682 | unsigned short tmp = (unsigned char)ch; |
682 | /* this code sends stuff out to serial device - spinning its | 683 | /* this code sends stuff out to serial device - spinning its |
683 | wheels and waiting. */ | 684 | wheels and waiting. */ |
684 | 685 | ||
@@ -694,6 +695,7 @@ static void dz_console_put_char(struct dz_port *dport, unsigned char ch) | |||
694 | 695 | ||
695 | spin_unlock_irqrestore(&dport->port.lock, flags); | 696 | spin_unlock_irqrestore(&dport->port.lock, flags); |
696 | } | 697 | } |
698 | |||
697 | /* | 699 | /* |
698 | * ------------------------------------------------------------------- | 700 | * ------------------------------------------------------------------- |
699 | * dz_console_print () | 701 | * dz_console_print () |
@@ -710,11 +712,7 @@ static void dz_console_print(struct console *cons, | |||
710 | #ifdef DEBUG_DZ | 712 | #ifdef DEBUG_DZ |
711 | prom_printf((char *) str); | 713 | prom_printf((char *) str); |
712 | #endif | 714 | #endif |
713 | while (count--) { | 715 | uart_console_write(&dport->port, str, count, dz_console_putchar); |
714 | if (*str == '\n') | ||
715 | dz_console_put_char(dport, '\r'); | ||
716 | dz_console_put_char(dport, *str++); | ||
717 | } | ||
718 | } | 716 | } |
719 | 717 | ||
720 | static int __init dz_console_setup(struct console *co, char *options) | 718 | static int __init dz_console_setup(struct console *co, char *options) |
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c index 4d53fb5ca87b..c3b7a6673e9c 100644 --- a/drivers/serial/imx.c +++ b/drivers/serial/imx.c | |||
@@ -743,6 +743,13 @@ static void __init imx_init_ports(void) | |||
743 | } | 743 | } |
744 | 744 | ||
745 | #ifdef CONFIG_SERIAL_IMX_CONSOLE | 745 | #ifdef CONFIG_SERIAL_IMX_CONSOLE |
746 | static void imx_console_putchar(struct uart_port *port, int ch) | ||
747 | { | ||
748 | struct imx_port *sport = (struct imx_port *)port; | ||
749 | while ((UTS((u32)sport->port.membase) & UTS_TXFULL)) | ||
750 | barrier(); | ||
751 | URTX0((u32)sport->port.membase) = ch; | ||
752 | } | ||
746 | 753 | ||
747 | /* | 754 | /* |
748 | * Interrupts are disabled on entering | 755 | * Interrupts are disabled on entering |
@@ -751,7 +758,7 @@ static void | |||
751 | imx_console_write(struct console *co, const char *s, unsigned int count) | 758 | imx_console_write(struct console *co, const char *s, unsigned int count) |
752 | { | 759 | { |
753 | struct imx_port *sport = &imx_ports[co->index]; | 760 | struct imx_port *sport = &imx_ports[co->index]; |
754 | unsigned int old_ucr1, old_ucr2, i; | 761 | unsigned int old_ucr1, old_ucr2; |
755 | 762 | ||
756 | /* | 763 | /* |
757 | * First, save UCR1/2 and then disable interrupts | 764 | * First, save UCR1/2 and then disable interrupts |
@@ -764,22 +771,7 @@ imx_console_write(struct console *co, const char *s, unsigned int count) | |||
764 | & ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN); | 771 | & ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN); |
765 | UCR2((u32)sport->port.membase) = old_ucr2 | UCR2_TXEN; | 772 | UCR2((u32)sport->port.membase) = old_ucr2 | UCR2_TXEN; |
766 | 773 | ||
767 | /* | 774 | uart_console_write(&sport->port, s, count, imx_console_putchar); |
768 | * Now, do each character | ||
769 | */ | ||
770 | for (i = 0; i < count; i++) { | ||
771 | |||
772 | while ((UTS((u32)sport->port.membase) & UTS_TXFULL)) | ||
773 | barrier(); | ||
774 | |||
775 | URTX0((u32)sport->port.membase) = s[i]; | ||
776 | |||
777 | if (s[i] == '\n') { | ||
778 | while ((UTS((u32)sport->port.membase) & UTS_TXFULL)) | ||
779 | barrier(); | ||
780 | URTX0((u32)sport->port.membase) = '\r'; | ||
781 | } | ||
782 | } | ||
783 | 775 | ||
784 | /* | 776 | /* |
785 | * Finally, wait for transmitter to become empty | 777 | * Finally, wait for transmitter to become empty |
diff --git a/drivers/serial/ip22zilog.c b/drivers/serial/ip22zilog.c index 193722d680cf..651772474ac1 100644 --- a/drivers/serial/ip22zilog.c +++ b/drivers/serial/ip22zilog.c | |||
@@ -967,8 +967,9 @@ static struct zilog_layout * __init get_zs(int chip) | |||
967 | #define ZS_PUT_CHAR_MAX_DELAY 2000 /* 10 ms */ | 967 | #define ZS_PUT_CHAR_MAX_DELAY 2000 /* 10 ms */ |
968 | 968 | ||
969 | #ifdef CONFIG_SERIAL_IP22_ZILOG_CONSOLE | 969 | #ifdef CONFIG_SERIAL_IP22_ZILOG_CONSOLE |
970 | static void ip22zilog_put_char(struct zilog_channel *channel, unsigned char ch) | 970 | static void ip22zilog_put_char(struct uart_port *port, int ch) |
971 | { | 971 | { |
972 | struct zilog_channel *channel = ZILOG_CHANNEL_FROM_PORT(port); | ||
972 | int loops = ZS_PUT_CHAR_MAX_DELAY; | 973 | int loops = ZS_PUT_CHAR_MAX_DELAY; |
973 | 974 | ||
974 | /* This is a timed polling loop so do not switch the explicit | 975 | /* This is a timed polling loop so do not switch the explicit |
@@ -992,16 +993,10 @@ static void | |||
992 | ip22zilog_console_write(struct console *con, const char *s, unsigned int count) | 993 | ip22zilog_console_write(struct console *con, const char *s, unsigned int count) |
993 | { | 994 | { |
994 | struct uart_ip22zilog_port *up = &ip22zilog_port_table[con->index]; | 995 | struct uart_ip22zilog_port *up = &ip22zilog_port_table[con->index]; |
995 | struct zilog_channel *channel = ZILOG_CHANNEL_FROM_PORT(&up->port); | ||
996 | unsigned long flags; | 996 | unsigned long flags; |
997 | int i; | ||
998 | 997 | ||
999 | spin_lock_irqsave(&up->port.lock, flags); | 998 | spin_lock_irqsave(&up->port.lock, flags); |
1000 | for (i = 0; i < count; i++, s++) { | 999 | uart_console_write(&up->port, s, count, ip22zilog_put_char); |
1001 | ip22zilog_put_char(channel, *s); | ||
1002 | if (*s == 10) | ||
1003 | ip22zilog_put_char(channel, 13); | ||
1004 | } | ||
1005 | udelay(2); | 1000 | udelay(2); |
1006 | spin_unlock_irqrestore(&up->port.lock, flags); | 1001 | spin_unlock_irqrestore(&up->port.lock, flags); |
1007 | } | 1002 | } |
diff --git a/drivers/serial/m32r_sio.c b/drivers/serial/m32r_sio.c index 242a04104393..e9c10c0a30fc 100644 --- a/drivers/serial/m32r_sio.c +++ b/drivers/serial/m32r_sio.c | |||
@@ -248,17 +248,17 @@ static void sio_error(int *status) | |||
248 | 248 | ||
249 | #endif /* CONFIG_SERIAL_M32R_PLDSIO */ | 249 | #endif /* CONFIG_SERIAL_M32R_PLDSIO */ |
250 | 250 | ||
251 | static _INLINE_ unsigned int sio_in(struct uart_sio_port *up, int offset) | 251 | static unsigned int sio_in(struct uart_sio_port *up, int offset) |
252 | { | 252 | { |
253 | return __sio_in(up->port.iobase + offset); | 253 | return __sio_in(up->port.iobase + offset); |
254 | } | 254 | } |
255 | 255 | ||
256 | static _INLINE_ void sio_out(struct uart_sio_port *up, int offset, int value) | 256 | static void sio_out(struct uart_sio_port *up, int offset, int value) |
257 | { | 257 | { |
258 | __sio_out(value, up->port.iobase + offset); | 258 | __sio_out(value, up->port.iobase + offset); |
259 | } | 259 | } |
260 | 260 | ||
261 | static _INLINE_ unsigned int serial_in(struct uart_sio_port *up, int offset) | 261 | static unsigned int serial_in(struct uart_sio_port *up, int offset) |
262 | { | 262 | { |
263 | if (!offset) | 263 | if (!offset) |
264 | return 0; | 264 | return 0; |
@@ -266,8 +266,7 @@ static _INLINE_ unsigned int serial_in(struct uart_sio_port *up, int offset) | |||
266 | return __sio_in(offset); | 266 | return __sio_in(offset); |
267 | } | 267 | } |
268 | 268 | ||
269 | static _INLINE_ void | 269 | static void serial_out(struct uart_sio_port *up, int offset, int value) |
270 | serial_out(struct uart_sio_port *up, int offset, int value) | ||
271 | { | 270 | { |
272 | if (!offset) | 271 | if (!offset) |
273 | return; | 272 | return; |
@@ -326,8 +325,8 @@ static void m32r_sio_enable_ms(struct uart_port *port) | |||
326 | serial_out(up, UART_IER, up->ier); | 325 | serial_out(up, UART_IER, up->ier); |
327 | } | 326 | } |
328 | 327 | ||
329 | static _INLINE_ void receive_chars(struct uart_sio_port *up, int *status, | 328 | static void receive_chars(struct uart_sio_port *up, int *status, |
330 | struct pt_regs *regs) | 329 | struct pt_regs *regs) |
331 | { | 330 | { |
332 | struct tty_struct *tty = up->port.info->tty; | 331 | struct tty_struct *tty = up->port.info->tty; |
333 | unsigned char ch; | 332 | unsigned char ch; |
@@ -400,7 +399,7 @@ static _INLINE_ void receive_chars(struct uart_sio_port *up, int *status, | |||
400 | tty_flip_buffer_push(tty); | 399 | tty_flip_buffer_push(tty); |
401 | } | 400 | } |
402 | 401 | ||
403 | static _INLINE_ void transmit_chars(struct uart_sio_port *up) | 402 | static void transmit_chars(struct uart_sio_port *up) |
404 | { | 403 | { |
405 | struct circ_buf *xmit = &up->port.info->xmit; | 404 | struct circ_buf *xmit = &up->port.info->xmit; |
406 | int count; | 405 | int count; |
@@ -1039,6 +1038,14 @@ static inline void wait_for_xmitr(struct uart_sio_port *up) | |||
1039 | } | 1038 | } |
1040 | } | 1039 | } |
1041 | 1040 | ||
1041 | static void m32r_sio_console_putchar(struct uart_port *port, int ch) | ||
1042 | { | ||
1043 | struct uart_sio_port *up = (struct uart_sio_port *)port; | ||
1044 | |||
1045 | wait_for_xmitr(up); | ||
1046 | sio_out(up, SIOTXB, ch); | ||
1047 | } | ||
1048 | |||
1042 | /* | 1049 | /* |
1043 | * Print a string to the serial port trying not to disturb | 1050 | * Print a string to the serial port trying not to disturb |
1044 | * any possible real use of the port... | 1051 | * any possible real use of the port... |
@@ -1058,23 +1065,7 @@ static void m32r_sio_console_write(struct console *co, const char *s, | |||
1058 | ier = sio_in(up, SIOTRCR); | 1065 | ier = sio_in(up, SIOTRCR); |
1059 | sio_out(up, SIOTRCR, 0); | 1066 | sio_out(up, SIOTRCR, 0); |
1060 | 1067 | ||
1061 | /* | 1068 | uart_console_write(&up->port, s, count, m32r_sio_console_putchar); |
1062 | * Now, do each character | ||
1063 | */ | ||
1064 | for (i = 0; i < count; i++, s++) { | ||
1065 | wait_for_xmitr(up); | ||
1066 | |||
1067 | /* | ||
1068 | * Send the character out. | ||
1069 | * If a LF, also do CR... | ||
1070 | */ | ||
1071 | sio_out(up, SIOTXB, *s); | ||
1072 | |||
1073 | if (*s == 10) { | ||
1074 | wait_for_xmitr(up); | ||
1075 | sio_out(up, SIOTXB, 13); | ||
1076 | } | ||
1077 | } | ||
1078 | 1069 | ||
1079 | /* | 1070 | /* |
1080 | * Finally, wait for transmitter to become empty | 1071 | * Finally, wait for transmitter to become empty |
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c index 61dd17d7bace..928e6cf12dca 100644 --- a/drivers/serial/mpc52xx_uart.c +++ b/drivers/serial/mpc52xx_uart.c | |||
@@ -603,15 +603,14 @@ mpc52xx_console_write(struct console *co, const char *s, unsigned int count) | |||
603 | udelay(1); | 603 | udelay(1); |
604 | 604 | ||
605 | /* Write all the chars */ | 605 | /* Write all the chars */ |
606 | for ( i=0 ; i<count ; i++ ) { | 606 | for (i = 0; i < count; i++, s++) { |
607 | |||
608 | /* Send the char */ | ||
609 | out_8(&psc->mpc52xx_psc_buffer_8, *s); | ||
610 | |||
611 | /* Line return handling */ | 607 | /* Line return handling */ |
612 | if ( *s++ == '\n' ) | 608 | if (*s == '\n') |
613 | out_8(&psc->mpc52xx_psc_buffer_8, '\r'); | 609 | out_8(&psc->mpc52xx_psc_buffer_8, '\r'); |
614 | 610 | ||
611 | /* Send the char */ | ||
612 | out_8(&psc->mpc52xx_psc_buffer_8, *s); | ||
613 | |||
615 | /* Wait the TX buffer to be empty */ | 614 | /* Wait the TX buffer to be empty */ |
616 | j = 20000; /* Maximum wait */ | 615 | j = 20000; /* Maximum wait */ |
617 | while (!(in_be16(&psc->mpc52xx_psc_status) & | 616 | while (!(in_be16(&psc->mpc52xx_psc_status) & |
diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c index 9b7ed58cb53b..513ff8597707 100644 --- a/drivers/serial/pmac_zilog.c +++ b/drivers/serial/pmac_zilog.c | |||
@@ -1916,6 +1916,16 @@ static void __exit exit_pmz(void) | |||
1916 | 1916 | ||
1917 | #ifdef CONFIG_SERIAL_PMACZILOG_CONSOLE | 1917 | #ifdef CONFIG_SERIAL_PMACZILOG_CONSOLE |
1918 | 1918 | ||
1919 | static void pmz_console_putchar(struct uart_port *port, int ch) | ||
1920 | { | ||
1921 | struct uart_pmac_port *uap = (struct uart_pmac_port *)port; | ||
1922 | |||
1923 | /* Wait for the transmit buffer to empty. */ | ||
1924 | while ((read_zsreg(uap, R0) & Tx_BUF_EMP) == 0) | ||
1925 | udelay(5); | ||
1926 | write_zsdata(uap, ch); | ||
1927 | } | ||
1928 | |||
1919 | /* | 1929 | /* |
1920 | * Print a string to the serial port trying not to disturb | 1930 | * Print a string to the serial port trying not to disturb |
1921 | * any possible real use of the port... | 1931 | * any possible real use of the port... |
@@ -1924,7 +1934,6 @@ static void pmz_console_write(struct console *con, const char *s, unsigned int c | |||
1924 | { | 1934 | { |
1925 | struct uart_pmac_port *uap = &pmz_ports[con->index]; | 1935 | struct uart_pmac_port *uap = &pmz_ports[con->index]; |
1926 | unsigned long flags; | 1936 | unsigned long flags; |
1927 | int i; | ||
1928 | 1937 | ||
1929 | if (ZS_IS_ASLEEP(uap)) | 1938 | if (ZS_IS_ASLEEP(uap)) |
1930 | return; | 1939 | return; |
@@ -1934,17 +1943,7 @@ static void pmz_console_write(struct console *con, const char *s, unsigned int c | |||
1934 | write_zsreg(uap, R1, uap->curregs[1] & ~TxINT_ENAB); | 1943 | write_zsreg(uap, R1, uap->curregs[1] & ~TxINT_ENAB); |
1935 | write_zsreg(uap, R5, uap->curregs[5] | TxENABLE | RTS | DTR); | 1944 | write_zsreg(uap, R5, uap->curregs[5] | TxENABLE | RTS | DTR); |
1936 | 1945 | ||
1937 | for (i = 0; i < count; i++) { | 1946 | uart_console_write(&uap->port, s, count, pmz_console_putchar); |
1938 | /* Wait for the transmit buffer to empty. */ | ||
1939 | while ((read_zsreg(uap, R0) & Tx_BUF_EMP) == 0) | ||
1940 | udelay(5); | ||
1941 | write_zsdata(uap, s[i]); | ||
1942 | if (s[i] == 10) { | ||
1943 | while ((read_zsreg(uap, R0) & Tx_BUF_EMP) == 0) | ||
1944 | udelay(5); | ||
1945 | write_zsdata(uap, R13); | ||
1946 | } | ||
1947 | } | ||
1948 | 1947 | ||
1949 | /* Restore the values in the registers. */ | 1948 | /* Restore the values in the registers. */ |
1950 | write_zsreg(uap, R1, uap->curregs[1]); | 1949 | write_zsreg(uap, R1, uap->curregs[1]); |
diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c index 10535f00301f..77d4568ccc3a 100644 --- a/drivers/serial/pxa.c +++ b/drivers/serial/pxa.c | |||
@@ -619,6 +619,14 @@ static inline void wait_for_xmitr(struct uart_pxa_port *up) | |||
619 | } | 619 | } |
620 | } | 620 | } |
621 | 621 | ||
622 | static void serial_pxa_console_putchar(struct uart_port *port, int ch) | ||
623 | { | ||
624 | struct uart_pxa_port *up = (struct uart_pxa_port *)port; | ||
625 | |||
626 | wait_for_xmitr(up); | ||
627 | serial_out(up, UART_TX, ch); | ||
628 | } | ||
629 | |||
622 | /* | 630 | /* |
623 | * Print a string to the serial port trying not to disturb | 631 | * Print a string to the serial port trying not to disturb |
624 | * any possible real use of the port... | 632 | * any possible real use of the port... |
@@ -630,7 +638,6 @@ serial_pxa_console_write(struct console *co, const char *s, unsigned int count) | |||
630 | { | 638 | { |
631 | struct uart_pxa_port *up = &serial_pxa_ports[co->index]; | 639 | struct uart_pxa_port *up = &serial_pxa_ports[co->index]; |
632 | unsigned int ier; | 640 | unsigned int ier; |
633 | int i; | ||
634 | 641 | ||
635 | /* | 642 | /* |
636 | * First save the IER then disable the interrupts | 643 | * First save the IER then disable the interrupts |
@@ -638,22 +645,7 @@ serial_pxa_console_write(struct console *co, const char *s, unsigned int count) | |||
638 | ier = serial_in(up, UART_IER); | 645 | ier = serial_in(up, UART_IER); |
639 | serial_out(up, UART_IER, UART_IER_UUE); | 646 | serial_out(up, UART_IER, UART_IER_UUE); |
640 | 647 | ||
641 | /* | 648 | uart_console_write(&up->port, s, count, serial_pxa_console_putchar); |
642 | * Now, do each character | ||
643 | */ | ||
644 | for (i = 0; i < count; i++, s++) { | ||
645 | wait_for_xmitr(up); | ||
646 | |||
647 | /* | ||
648 | * Send the character out. | ||
649 | * If a LF, also do CR... | ||
650 | */ | ||
651 | serial_out(up, UART_TX, *s); | ||
652 | if (*s == 10) { | ||
653 | wait_for_xmitr(up); | ||
654 | serial_out(up, UART_TX, 13); | ||
655 | } | ||
656 | } | ||
657 | 649 | ||
658 | /* | 650 | /* |
659 | * Finally, wait for transmitter to become empty | 651 | * Finally, wait for transmitter to become empty |
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c index 7410e093a6b9..f5aac92fb798 100644 --- a/drivers/serial/s3c2410.c +++ b/drivers/serial/s3c2410.c | |||
@@ -1066,6 +1066,8 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport, | |||
1066 | port->mapbase = res->start; | 1066 | port->mapbase = res->start; |
1067 | port->membase = S3C24XX_VA_UART + (res->start - S3C24XX_PA_UART); | 1067 | port->membase = S3C24XX_VA_UART + (res->start - S3C24XX_PA_UART); |
1068 | port->irq = platform_get_irq(platdev, 0); | 1068 | port->irq = platform_get_irq(platdev, 0); |
1069 | if (port->irq < 0) | ||
1070 | port->irq = 0; | ||
1069 | 1071 | ||
1070 | ourport->clk = clk_get(&platdev->dev, "uart"); | 1072 | ourport->clk = clk_get(&platdev->dev, "uart"); |
1071 | 1073 | ||
@@ -1584,25 +1586,19 @@ s3c24xx_serial_console_txrdy(struct uart_port *port, unsigned int ufcon) | |||
1584 | } | 1586 | } |
1585 | 1587 | ||
1586 | static void | 1588 | static void |
1587 | s3c24xx_serial_console_write(struct console *co, const char *s, | 1589 | s3c24xx_serial_console_putchar(struct uart_port *port, int ch) |
1588 | unsigned int count) | ||
1589 | { | 1590 | { |
1590 | int i; | ||
1591 | unsigned int ufcon = rd_regl(cons_uart, S3C2410_UFCON); | 1591 | unsigned int ufcon = rd_regl(cons_uart, S3C2410_UFCON); |
1592 | while (!s3c24xx_serial_console_txrdy(port, ufcon)) | ||
1593 | barrier(); | ||
1594 | wr_regb(cons_uart, S3C2410_UTXH, ch); | ||
1595 | } | ||
1592 | 1596 | ||
1593 | for (i = 0; i < count; i++) { | 1597 | static void |
1594 | while (!s3c24xx_serial_console_txrdy(cons_uart, ufcon)) | 1598 | s3c24xx_serial_console_write(struct console *co, const char *s, |
1595 | barrier(); | 1599 | unsigned int count) |
1596 | 1600 | { | |
1597 | wr_regb(cons_uart, S3C2410_UTXH, s[i]); | 1601 | uart_console_write(cons_uart, s, count, s3c24xx_serial_console_putchar); |
1598 | |||
1599 | if (s[i] == '\n') { | ||
1600 | while (!s3c24xx_serial_console_txrdy(cons_uart, ufcon)) | ||
1601 | barrier(); | ||
1602 | |||
1603 | wr_regb(cons_uart, S3C2410_UTXH, '\r'); | ||
1604 | } | ||
1605 | } | ||
1606 | } | 1602 | } |
1607 | 1603 | ||
1608 | static void __init | 1604 | static void __init |
diff --git a/drivers/serial/sa1100.c b/drivers/serial/sa1100.c index 2c00b8625852..c2d9068b491d 100644 --- a/drivers/serial/sa1100.c +++ b/drivers/serial/sa1100.c | |||
@@ -689,6 +689,14 @@ void __init sa1100_register_uart(int idx, int port) | |||
689 | 689 | ||
690 | 690 | ||
691 | #ifdef CONFIG_SERIAL_SA1100_CONSOLE | 691 | #ifdef CONFIG_SERIAL_SA1100_CONSOLE |
692 | static void sa1100_console_putchar(struct uart_port *port, int ch) | ||
693 | { | ||
694 | struct sa1100_port *sport = (struct sa1100_port *)port; | ||
695 | |||
696 | while (!(UART_GET_UTSR1(sport) & UTSR1_TNF)) | ||
697 | barrier(); | ||
698 | UART_PUT_CHAR(sport, ch); | ||
699 | } | ||
692 | 700 | ||
693 | /* | 701 | /* |
694 | * Interrupts are disabled on entering | 702 | * Interrupts are disabled on entering |
@@ -697,7 +705,7 @@ static void | |||
697 | sa1100_console_write(struct console *co, const char *s, unsigned int count) | 705 | sa1100_console_write(struct console *co, const char *s, unsigned int count) |
698 | { | 706 | { |
699 | struct sa1100_port *sport = &sa1100_ports[co->index]; | 707 | struct sa1100_port *sport = &sa1100_ports[co->index]; |
700 | unsigned int old_utcr3, status, i; | 708 | unsigned int old_utcr3, status; |
701 | 709 | ||
702 | /* | 710 | /* |
703 | * First, save UTCR3 and then disable interrupts | 711 | * First, save UTCR3 and then disable interrupts |
@@ -706,21 +714,7 @@ sa1100_console_write(struct console *co, const char *s, unsigned int count) | |||
706 | UART_PUT_UTCR3(sport, (old_utcr3 & ~(UTCR3_RIE | UTCR3_TIE)) | | 714 | UART_PUT_UTCR3(sport, (old_utcr3 & ~(UTCR3_RIE | UTCR3_TIE)) | |
707 | UTCR3_TXE); | 715 | UTCR3_TXE); |
708 | 716 | ||
709 | /* | 717 | uart_console_write(&sport->port, s, count, sa1100_console_putchar); |
710 | * Now, do each character | ||
711 | */ | ||
712 | for (i = 0; i < count; i++) { | ||
713 | do { | ||
714 | status = UART_GET_UTSR1(sport); | ||
715 | } while (!(status & UTSR1_TNF)); | ||
716 | UART_PUT_CHAR(sport, s[i]); | ||
717 | if (s[i] == '\n') { | ||
718 | do { | ||
719 | status = UART_GET_UTSR1(sport); | ||
720 | } while (!(status & UTSR1_TNF)); | ||
721 | UART_PUT_CHAR(sport, '\r'); | ||
722 | } | ||
723 | } | ||
724 | 718 | ||
725 | /* | 719 | /* |
726 | * Finally, wait for transmitter to become empty | 720 | * Finally, wait for transmitter to become empty |
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c index cc1faa31d124..fcd7744c4253 100644 --- a/drivers/serial/serial_core.c +++ b/drivers/serial/serial_core.c | |||
@@ -1755,6 +1755,27 @@ static int uart_read_proc(char *page, char **start, off_t off, | |||
1755 | 1755 | ||
1756 | #ifdef CONFIG_SERIAL_CORE_CONSOLE | 1756 | #ifdef CONFIG_SERIAL_CORE_CONSOLE |
1757 | /* | 1757 | /* |
1758 | * uart_console_write - write a console message to a serial port | ||
1759 | * @port: the port to write the message | ||
1760 | * @s: array of characters | ||
1761 | * @count: number of characters in string to write | ||
1762 | * @write: function to write character to port | ||
1763 | */ | ||
1764 | void uart_console_write(struct uart_port *port, const char *s, | ||
1765 | unsigned int count, | ||
1766 | void (*putchar)(struct uart_port *, int)) | ||
1767 | { | ||
1768 | unsigned int i; | ||
1769 | |||
1770 | for (i = 0; i < count; i++, s++) { | ||
1771 | if (*s == '\n') | ||
1772 | putchar(port, '\r'); | ||
1773 | putchar(port, *s); | ||
1774 | } | ||
1775 | } | ||
1776 | EXPORT_SYMBOL_GPL(uart_console_write); | ||
1777 | |||
1778 | /* | ||
1758 | * Check whether an invalid uart number has been specified, and | 1779 | * Check whether an invalid uart number has been specified, and |
1759 | * if so, search for the first available port that does have | 1780 | * if so, search for the first available port that does have |
1760 | * console support. | 1781 | * console support. |
diff --git a/drivers/serial/serial_lh7a40x.c b/drivers/serial/serial_lh7a40x.c index 04186eaae227..aa521b8e0d4e 100644 --- a/drivers/serial/serial_lh7a40x.c +++ b/drivers/serial/serial_lh7a40x.c | |||
@@ -543,6 +543,12 @@ static struct uart_port_lh7a40x lh7a40x_ports[DEV_NR] = { | |||
543 | #else | 543 | #else |
544 | # define LH7A40X_CONSOLE &lh7a40x_console | 544 | # define LH7A40X_CONSOLE &lh7a40x_console |
545 | 545 | ||
546 | static void lh7a40xuart_console_putchar(struct uart_port *port, int ch) | ||
547 | { | ||
548 | while (UR(port, UART_R_STATUS) & nTxRdy) | ||
549 | ; | ||
550 | UR(port, UART_R_DATA) = ch; | ||
551 | } | ||
546 | 552 | ||
547 | static void lh7a40xuart_console_write (struct console* co, | 553 | static void lh7a40xuart_console_write (struct console* co, |
548 | const char* s, | 554 | const char* s, |
@@ -556,16 +562,7 @@ static void lh7a40xuart_console_write (struct console* co, | |||
556 | UR (port, UART_R_INTEN) = 0; /* Disable all interrupts */ | 562 | UR (port, UART_R_INTEN) = 0; /* Disable all interrupts */ |
557 | BIT_SET (port, UART_R_CON, UARTEN | SIRDIS); /* Enable UART */ | 563 | BIT_SET (port, UART_R_CON, UARTEN | SIRDIS); /* Enable UART */ |
558 | 564 | ||
559 | for (; count-- > 0; ++s) { | 565 | uart_console_write(port, s, count, lh7a40xuart_console_putchar); |
560 | while (UR (port, UART_R_STATUS) & nTxRdy) | ||
561 | ; | ||
562 | UR (port, UART_R_DATA) = *s; | ||
563 | if (*s == '\n') { | ||
564 | while ((UR (port, UART_R_STATUS) & TxBusy)) | ||
565 | ; | ||
566 | UR (port, UART_R_DATA) = '\r'; | ||
567 | } | ||
568 | } | ||
569 | 566 | ||
570 | /* Wait until all characters are sent */ | 567 | /* Wait until all characters are sent */ |
571 | while (UR (port, UART_R_STATUS) & TxBusy) | 568 | while (UR (port, UART_R_STATUS) & TxBusy) |
diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c index ee98a867bc6d..b848b7d94412 100644 --- a/drivers/serial/serial_txx9.c +++ b/drivers/serial/serial_txx9.c | |||
@@ -33,6 +33,10 @@ | |||
33 | * 1.02 Cleanup. (import 8250.c changes) | 33 | * 1.02 Cleanup. (import 8250.c changes) |
34 | * 1.03 Fix low-latency mode. (import 8250.c changes) | 34 | * 1.03 Fix low-latency mode. (import 8250.c changes) |
35 | * 1.04 Remove usage of deprecated functions, cleanup. | 35 | * 1.04 Remove usage of deprecated functions, cleanup. |
36 | * 1.05 More strict check in verify_port. Cleanup. | ||
37 | * 1.06 Do not insert a char caused previous overrun. | ||
38 | * Fix some spin_locks. | ||
39 | * Do not call uart_add_one_port for absent ports. | ||
36 | */ | 40 | */ |
37 | #include <linux/config.h> | 41 | #include <linux/config.h> |
38 | 42 | ||
@@ -57,7 +61,7 @@ | |||
57 | #include <asm/io.h> | 61 | #include <asm/io.h> |
58 | #include <asm/irq.h> | 62 | #include <asm/irq.h> |
59 | 63 | ||
60 | static char *serial_version = "1.04"; | 64 | static char *serial_version = "1.06"; |
61 | static char *serial_name = "TX39/49 Serial driver"; | 65 | static char *serial_name = "TX39/49 Serial driver"; |
62 | 66 | ||
63 | #define PASS_LIMIT 256 | 67 | #define PASS_LIMIT 256 |
@@ -94,6 +98,8 @@ static char *serial_name = "TX39/49 Serial driver"; | |||
94 | #define UART_NR 4 | 98 | #define UART_NR 4 |
95 | #endif | 99 | #endif |
96 | 100 | ||
101 | #define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8) | ||
102 | |||
97 | struct uart_txx9_port { | 103 | struct uart_txx9_port { |
98 | struct uart_port port; | 104 | struct uart_port port; |
99 | 105 | ||
@@ -210,7 +216,7 @@ static inline unsigned int sio_in(struct uart_txx9_port *up, int offset) | |||
210 | { | 216 | { |
211 | switch (up->port.iotype) { | 217 | switch (up->port.iotype) { |
212 | default: | 218 | default: |
213 | return *(volatile u32 *)(up->port.membase + offset); | 219 | return __raw_readl(up->port.membase + offset); |
214 | case UPIO_PORT: | 220 | case UPIO_PORT: |
215 | return inl(up->port.iobase + offset); | 221 | return inl(up->port.iobase + offset); |
216 | } | 222 | } |
@@ -221,7 +227,7 @@ sio_out(struct uart_txx9_port *up, int offset, int value) | |||
221 | { | 227 | { |
222 | switch (up->port.iotype) { | 228 | switch (up->port.iotype) { |
223 | default: | 229 | default: |
224 | *(volatile u32 *)(up->port.membase + offset) = value; | 230 | __raw_writel(value, up->port.membase + offset); |
225 | break; | 231 | break; |
226 | case UPIO_PORT: | 232 | case UPIO_PORT: |
227 | outl(value, up->port.iobase + offset); | 233 | outl(value, up->port.iobase + offset); |
@@ -259,34 +265,19 @@ sio_quot_set(struct uart_txx9_port *up, int quot) | |||
259 | static void serial_txx9_stop_tx(struct uart_port *port) | 265 | static void serial_txx9_stop_tx(struct uart_port *port) |
260 | { | 266 | { |
261 | struct uart_txx9_port *up = (struct uart_txx9_port *)port; | 267 | struct uart_txx9_port *up = (struct uart_txx9_port *)port; |
262 | unsigned long flags; | ||
263 | |||
264 | spin_lock_irqsave(&up->port.lock, flags); | ||
265 | sio_mask(up, TXX9_SIDICR, TXX9_SIDICR_TIE); | 268 | sio_mask(up, TXX9_SIDICR, TXX9_SIDICR_TIE); |
266 | spin_unlock_irqrestore(&up->port.lock, flags); | ||
267 | } | 269 | } |
268 | 270 | ||
269 | static void serial_txx9_start_tx(struct uart_port *port) | 271 | static void serial_txx9_start_tx(struct uart_port *port) |
270 | { | 272 | { |
271 | struct uart_txx9_port *up = (struct uart_txx9_port *)port; | 273 | struct uart_txx9_port *up = (struct uart_txx9_port *)port; |
272 | unsigned long flags; | ||
273 | |||
274 | spin_lock_irqsave(&up->port.lock, flags); | ||
275 | sio_set(up, TXX9_SIDICR, TXX9_SIDICR_TIE); | 274 | sio_set(up, TXX9_SIDICR, TXX9_SIDICR_TIE); |
276 | spin_unlock_irqrestore(&up->port.lock, flags); | ||
277 | } | 275 | } |
278 | 276 | ||
279 | static void serial_txx9_stop_rx(struct uart_port *port) | 277 | static void serial_txx9_stop_rx(struct uart_port *port) |
280 | { | 278 | { |
281 | struct uart_txx9_port *up = (struct uart_txx9_port *)port; | 279 | struct uart_txx9_port *up = (struct uart_txx9_port *)port; |
282 | unsigned long flags; | ||
283 | |||
284 | spin_lock_irqsave(&up->port.lock, flags); | ||
285 | up->port.read_status_mask &= ~TXX9_SIDISR_RDIS; | 280 | up->port.read_status_mask &= ~TXX9_SIDISR_RDIS; |
286 | #if 0 | ||
287 | sio_mask(up, TXX9_SIDICR, TXX9_SIDICR_RIE); | ||
288 | #endif | ||
289 | spin_unlock_irqrestore(&up->port.lock, flags); | ||
290 | } | 281 | } |
291 | 282 | ||
292 | static void serial_txx9_enable_ms(struct uart_port *port) | 283 | static void serial_txx9_enable_ms(struct uart_port *port) |
@@ -302,12 +293,16 @@ receive_chars(struct uart_txx9_port *up, unsigned int *status, struct pt_regs *r | |||
302 | unsigned int disr = *status; | 293 | unsigned int disr = *status; |
303 | int max_count = 256; | 294 | int max_count = 256; |
304 | char flag; | 295 | char flag; |
296 | unsigned int next_ignore_status_mask; | ||
305 | 297 | ||
306 | do { | 298 | do { |
307 | ch = sio_in(up, TXX9_SIRFIFO); | 299 | ch = sio_in(up, TXX9_SIRFIFO); |
308 | flag = TTY_NORMAL; | 300 | flag = TTY_NORMAL; |
309 | up->port.icount.rx++; | 301 | up->port.icount.rx++; |
310 | 302 | ||
303 | /* mask out RFDN_MASK bit added by previous overrun */ | ||
304 | next_ignore_status_mask = | ||
305 | up->port.ignore_status_mask & ~TXX9_SIDISR_RFDN_MASK; | ||
311 | if (unlikely(disr & (TXX9_SIDISR_UBRK | TXX9_SIDISR_UPER | | 306 | if (unlikely(disr & (TXX9_SIDISR_UBRK | TXX9_SIDISR_UPER | |
312 | TXX9_SIDISR_UFER | TXX9_SIDISR_UOER))) { | 307 | TXX9_SIDISR_UFER | TXX9_SIDISR_UOER))) { |
313 | /* | 308 | /* |
@@ -328,8 +323,17 @@ receive_chars(struct uart_txx9_port *up, unsigned int *status, struct pt_regs *r | |||
328 | up->port.icount.parity++; | 323 | up->port.icount.parity++; |
329 | else if (disr & TXX9_SIDISR_UFER) | 324 | else if (disr & TXX9_SIDISR_UFER) |
330 | up->port.icount.frame++; | 325 | up->port.icount.frame++; |
331 | if (disr & TXX9_SIDISR_UOER) | 326 | if (disr & TXX9_SIDISR_UOER) { |
332 | up->port.icount.overrun++; | 327 | up->port.icount.overrun++; |
328 | /* | ||
329 | * The receiver read buffer still hold | ||
330 | * a char which caused overrun. | ||
331 | * Ignore next char by adding RFDN_MASK | ||
332 | * to ignore_status_mask temporarily. | ||
333 | */ | ||
334 | next_ignore_status_mask |= | ||
335 | TXX9_SIDISR_RFDN_MASK; | ||
336 | } | ||
333 | 337 | ||
334 | /* | 338 | /* |
335 | * Mask off conditions which should be ingored. | 339 | * Mask off conditions which should be ingored. |
@@ -349,6 +353,7 @@ receive_chars(struct uart_txx9_port *up, unsigned int *status, struct pt_regs *r | |||
349 | uart_insert_char(&up->port, disr, TXX9_SIDISR_UOER, ch, flag); | 353 | uart_insert_char(&up->port, disr, TXX9_SIDISR_UOER, ch, flag); |
350 | 354 | ||
351 | ignore_char: | 355 | ignore_char: |
356 | up->port.ignore_status_mask = next_ignore_status_mask; | ||
352 | disr = sio_in(up, TXX9_SIDISR); | 357 | disr = sio_in(up, TXX9_SIDISR); |
353 | } while (!(disr & TXX9_SIDISR_UVALID) && (max_count-- > 0)); | 358 | } while (!(disr & TXX9_SIDISR_UVALID) && (max_count-- > 0)); |
354 | spin_unlock(&up->port.lock); | 359 | spin_unlock(&up->port.lock); |
@@ -450,14 +455,11 @@ static unsigned int serial_txx9_get_mctrl(struct uart_port *port) | |||
450 | static void serial_txx9_set_mctrl(struct uart_port *port, unsigned int mctrl) | 455 | static void serial_txx9_set_mctrl(struct uart_port *port, unsigned int mctrl) |
451 | { | 456 | { |
452 | struct uart_txx9_port *up = (struct uart_txx9_port *)port; | 457 | struct uart_txx9_port *up = (struct uart_txx9_port *)port; |
453 | unsigned long flags; | ||
454 | 458 | ||
455 | spin_lock_irqsave(&up->port.lock, flags); | ||
456 | if (mctrl & TIOCM_RTS) | 459 | if (mctrl & TIOCM_RTS) |
457 | sio_mask(up, TXX9_SIFLCR, TXX9_SIFLCR_RTSSC); | 460 | sio_mask(up, TXX9_SIFLCR, TXX9_SIFLCR_RTSSC); |
458 | else | 461 | else |
459 | sio_set(up, TXX9_SIFLCR, TXX9_SIFLCR_RTSSC); | 462 | sio_set(up, TXX9_SIFLCR, TXX9_SIFLCR_RTSSC); |
460 | spin_unlock_irqrestore(&up->port.lock, flags); | ||
461 | } | 463 | } |
462 | 464 | ||
463 | static void serial_txx9_break_ctl(struct uart_port *port, int break_state) | 465 | static void serial_txx9_break_ctl(struct uart_port *port, int break_state) |
@@ -784,8 +786,14 @@ static void serial_txx9_config_port(struct uart_port *port, int uflags) | |||
784 | static int | 786 | static int |
785 | serial_txx9_verify_port(struct uart_port *port, struct serial_struct *ser) | 787 | serial_txx9_verify_port(struct uart_port *port, struct serial_struct *ser) |
786 | { | 788 | { |
787 | if (ser->irq < 0 || | 789 | unsigned long new_port = ser->port; |
788 | ser->baud_base < 9600 || ser->type != PORT_TXX9) | 790 | if (HIGH_BITS_OFFSET) |
791 | new_port += (unsigned long)ser->port_high << HIGH_BITS_OFFSET; | ||
792 | if (ser->type != port->type || | ||
793 | ser->irq != port->irq || | ||
794 | ser->io_type != port->iotype || | ||
795 | new_port != port->iobase || | ||
796 | (unsigned long)ser->iomem_base != port->mapbase) | ||
789 | return -EINVAL; | 797 | return -EINVAL; |
790 | return 0; | 798 | return 0; |
791 | } | 799 | } |
@@ -827,7 +835,8 @@ static void __init serial_txx9_register_ports(struct uart_driver *drv) | |||
827 | 835 | ||
828 | up->port.line = i; | 836 | up->port.line = i; |
829 | up->port.ops = &serial_txx9_pops; | 837 | up->port.ops = &serial_txx9_pops; |
830 | uart_add_one_port(drv, &up->port); | 838 | if (up->port.iobase || up->port.mapbase) |
839 | uart_add_one_port(drv, &up->port); | ||
831 | } | 840 | } |
832 | } | 841 | } |
833 | 842 | ||
@@ -854,6 +863,14 @@ static inline void wait_for_xmitr(struct uart_txx9_port *up) | |||
854 | } | 863 | } |
855 | } | 864 | } |
856 | 865 | ||
866 | static void serial_txx9_console_putchar(struct uart_port *port, int ch) | ||
867 | { | ||
868 | struct uart_txx9_port *up = (struct uart_txx9_port *)port; | ||
869 | |||
870 | wait_for_xmitr(up); | ||
871 | sio_out(up, TXX9_SITFIFO, ch); | ||
872 | } | ||
873 | |||
857 | /* | 874 | /* |
858 | * Print a string to the serial port trying not to disturb | 875 | * Print a string to the serial port trying not to disturb |
859 | * any possible real use of the port... | 876 | * any possible real use of the port... |
@@ -865,7 +882,6 @@ serial_txx9_console_write(struct console *co, const char *s, unsigned int count) | |||
865 | { | 882 | { |
866 | struct uart_txx9_port *up = &serial_txx9_ports[co->index]; | 883 | struct uart_txx9_port *up = &serial_txx9_ports[co->index]; |
867 | unsigned int ier, flcr; | 884 | unsigned int ier, flcr; |
868 | int i; | ||
869 | 885 | ||
870 | /* | 886 | /* |
871 | * First save the UER then disable the interrupts | 887 | * First save the UER then disable the interrupts |
@@ -879,22 +895,7 @@ serial_txx9_console_write(struct console *co, const char *s, unsigned int count) | |||
879 | if (!(up->port.flags & UPF_CONS_FLOW) && (flcr & TXX9_SIFLCR_TES)) | 895 | if (!(up->port.flags & UPF_CONS_FLOW) && (flcr & TXX9_SIFLCR_TES)) |
880 | sio_out(up, TXX9_SIFLCR, flcr & ~TXX9_SIFLCR_TES); | 896 | sio_out(up, TXX9_SIFLCR, flcr & ~TXX9_SIFLCR_TES); |
881 | 897 | ||
882 | /* | 898 | uart_console_write(&up->port, s, count, serial_txx9_console_putchar); |
883 | * Now, do each character | ||
884 | */ | ||
885 | for (i = 0; i < count; i++, s++) { | ||
886 | wait_for_xmitr(up); | ||
887 | |||
888 | /* | ||
889 | * Send the character out. | ||
890 | * If a LF, also do CR... | ||
891 | */ | ||
892 | sio_out(up, TXX9_SITFIFO, *s); | ||
893 | if (*s == 10) { | ||
894 | wait_for_xmitr(up); | ||
895 | sio_out(up, TXX9_SITFIFO, 13); | ||
896 | } | ||
897 | } | ||
898 | 899 | ||
899 | /* | 900 | /* |
900 | * Finally, wait for transmitter to become empty | 901 | * Finally, wait for transmitter to become empty |
@@ -927,11 +928,6 @@ static int serial_txx9_console_setup(struct console *co, char *options) | |||
927 | return -ENODEV; | 928 | return -ENODEV; |
928 | 929 | ||
929 | /* | 930 | /* |
930 | * Temporary fix. | ||
931 | */ | ||
932 | spin_lock_init(&port->lock); | ||
933 | |||
934 | /* | ||
935 | * Disable UART interrupts, set DTR and RTS high | 931 | * Disable UART interrupts, set DTR and RTS high |
936 | * and set speed. | 932 | * and set speed. |
937 | */ | 933 | */ |
@@ -1041,11 +1037,10 @@ static int __devinit serial_txx9_register_port(struct uart_port *port) | |||
1041 | mutex_lock(&serial_txx9_mutex); | 1037 | mutex_lock(&serial_txx9_mutex); |
1042 | for (i = 0; i < UART_NR; i++) { | 1038 | for (i = 0; i < UART_NR; i++) { |
1043 | uart = &serial_txx9_ports[i]; | 1039 | uart = &serial_txx9_ports[i]; |
1044 | if (uart->port.type == PORT_UNKNOWN) | 1040 | if (!(uart->port.iobase || uart->port.mapbase)) |
1045 | break; | 1041 | break; |
1046 | } | 1042 | } |
1047 | if (i < UART_NR) { | 1043 | if (i < UART_NR) { |
1048 | uart_remove_one_port(&serial_txx9_reg, &uart->port); | ||
1049 | uart->port.iobase = port->iobase; | 1044 | uart->port.iobase = port->iobase; |
1050 | uart->port.membase = port->membase; | 1045 | uart->port.membase = port->membase; |
1051 | uart->port.irq = port->irq; | 1046 | uart->port.irq = port->irq; |
@@ -1080,9 +1075,8 @@ static void __devexit serial_txx9_unregister_port(int line) | |||
1080 | uart->port.type = PORT_UNKNOWN; | 1075 | uart->port.type = PORT_UNKNOWN; |
1081 | uart->port.iobase = 0; | 1076 | uart->port.iobase = 0; |
1082 | uart->port.mapbase = 0; | 1077 | uart->port.mapbase = 0; |
1083 | uart->port.membase = 0; | 1078 | uart->port.membase = NULL; |
1084 | uart->port.dev = NULL; | 1079 | uart->port.dev = NULL; |
1085 | uart_add_one_port(&serial_txx9_reg, &uart->port); | ||
1086 | mutex_unlock(&serial_txx9_mutex); | 1080 | mutex_unlock(&serial_txx9_mutex); |
1087 | } | 1081 | } |
1088 | 1082 | ||
@@ -1198,8 +1192,11 @@ static void __exit serial_txx9_exit(void) | |||
1198 | #ifdef ENABLE_SERIAL_TXX9_PCI | 1192 | #ifdef ENABLE_SERIAL_TXX9_PCI |
1199 | pci_unregister_driver(&serial_txx9_pci_driver); | 1193 | pci_unregister_driver(&serial_txx9_pci_driver); |
1200 | #endif | 1194 | #endif |
1201 | for (i = 0; i < UART_NR; i++) | 1195 | for (i = 0; i < UART_NR; i++) { |
1202 | uart_remove_one_port(&serial_txx9_reg, &serial_txx9_ports[i].port); | 1196 | struct uart_txx9_port *up = &serial_txx9_ports[i]; |
1197 | if (up->port.iobase || up->port.mapbase) | ||
1198 | uart_remove_one_port(&serial_txx9_reg, &up->port); | ||
1199 | } | ||
1203 | 1200 | ||
1204 | uart_unregister_driver(&serial_txx9_reg); | 1201 | uart_unregister_driver(&serial_txx9_reg); |
1205 | } | 1202 | } |
diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c index a2fb0c2fb121..bfbe9dc90cca 100644 --- a/drivers/serial/sunsab.c +++ b/drivers/serial/sunsab.c | |||
@@ -861,8 +861,9 @@ static int num_channels; | |||
861 | 861 | ||
862 | #ifdef CONFIG_SERIAL_SUNSAB_CONSOLE | 862 | #ifdef CONFIG_SERIAL_SUNSAB_CONSOLE |
863 | 863 | ||
864 | static __inline__ void sunsab_console_putchar(struct uart_sunsab_port *up, char c) | 864 | static void sunsab_console_putchar(struct uart_port *port, int c) |
865 | { | 865 | { |
866 | struct uart_sunsab_port *up = (struct uart_sunsab_port *)port; | ||
866 | unsigned long flags; | 867 | unsigned long flags; |
867 | 868 | ||
868 | spin_lock_irqsave(&up->port.lock, flags); | 869 | spin_lock_irqsave(&up->port.lock, flags); |
@@ -876,13 +877,8 @@ static __inline__ void sunsab_console_putchar(struct uart_sunsab_port *up, char | |||
876 | static void sunsab_console_write(struct console *con, const char *s, unsigned n) | 877 | static void sunsab_console_write(struct console *con, const char *s, unsigned n) |
877 | { | 878 | { |
878 | struct uart_sunsab_port *up = &sunsab_ports[con->index]; | 879 | struct uart_sunsab_port *up = &sunsab_ports[con->index]; |
879 | int i; | ||
880 | 880 | ||
881 | for (i = 0; i < n; i++) { | 881 | uart_console_write(&up->port, s, n, sunsab_console_putchar); |
882 | if (*s == '\n') | ||
883 | sunsab_console_putchar(up, '\r'); | ||
884 | sunsab_console_putchar(up, *s++); | ||
885 | } | ||
886 | sunsab_tec_wait(up); | 882 | sunsab_tec_wait(up); |
887 | } | 883 | } |
888 | 884 | ||
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c index 46c44b83f57c..9fe2283d91e5 100644 --- a/drivers/serial/sunsu.c +++ b/drivers/serial/sunsu.c | |||
@@ -102,9 +102,7 @@ struct uart_sunsu_port { | |||
102 | #endif | 102 | #endif |
103 | }; | 103 | }; |
104 | 104 | ||
105 | #define _INLINE_ | 105 | static unsigned int serial_in(struct uart_sunsu_port *up, int offset) |
106 | |||
107 | static _INLINE_ unsigned int serial_in(struct uart_sunsu_port *up, int offset) | ||
108 | { | 106 | { |
109 | offset <<= up->port.regshift; | 107 | offset <<= up->port.regshift; |
110 | 108 | ||
@@ -121,8 +119,7 @@ static _INLINE_ unsigned int serial_in(struct uart_sunsu_port *up, int offset) | |||
121 | } | 119 | } |
122 | } | 120 | } |
123 | 121 | ||
124 | static _INLINE_ void | 122 | static void serial_out(struct uart_sunsu_port *up, int offset, int value) |
125 | serial_out(struct uart_sunsu_port *up, int offset, int value) | ||
126 | { | 123 | { |
127 | #ifndef CONFIG_SPARC64 | 124 | #ifndef CONFIG_SPARC64 |
128 | /* | 125 | /* |
@@ -316,7 +313,7 @@ static void sunsu_enable_ms(struct uart_port *port) | |||
316 | spin_unlock_irqrestore(&up->port.lock, flags); | 313 | spin_unlock_irqrestore(&up->port.lock, flags); |
317 | } | 314 | } |
318 | 315 | ||
319 | static _INLINE_ struct tty_struct * | 316 | static struct tty_struct * |
320 | receive_chars(struct uart_sunsu_port *up, unsigned char *status, struct pt_regs *regs) | 317 | receive_chars(struct uart_sunsu_port *up, unsigned char *status, struct pt_regs *regs) |
321 | { | 318 | { |
322 | struct tty_struct *tty = up->port.info->tty; | 319 | struct tty_struct *tty = up->port.info->tty; |
@@ -395,7 +392,7 @@ receive_chars(struct uart_sunsu_port *up, unsigned char *status, struct pt_regs | |||
395 | return tty; | 392 | return tty; |
396 | } | 393 | } |
397 | 394 | ||
398 | static _INLINE_ void transmit_chars(struct uart_sunsu_port *up) | 395 | static void transmit_chars(struct uart_sunsu_port *up) |
399 | { | 396 | { |
400 | struct circ_buf *xmit = &up->port.info->xmit; | 397 | struct circ_buf *xmit = &up->port.info->xmit; |
401 | int count; | 398 | int count; |
@@ -431,7 +428,7 @@ static _INLINE_ void transmit_chars(struct uart_sunsu_port *up) | |||
431 | __stop_tx(up); | 428 | __stop_tx(up); |
432 | } | 429 | } |
433 | 430 | ||
434 | static _INLINE_ void check_modem_status(struct uart_sunsu_port *up) | 431 | static void check_modem_status(struct uart_sunsu_port *up) |
435 | { | 432 | { |
436 | int status; | 433 | int status; |
437 | 434 | ||
@@ -1377,6 +1374,14 @@ static __inline__ void wait_for_xmitr(struct uart_sunsu_port *up) | |||
1377 | } | 1374 | } |
1378 | } | 1375 | } |
1379 | 1376 | ||
1377 | static void sunsu_console_putchar(struct uart_port *port, int ch) | ||
1378 | { | ||
1379 | struct uart_sunsu_port *up = (struct uart_sunsu_port *)port; | ||
1380 | |||
1381 | wait_for_xmitr(up); | ||
1382 | serial_out(up, UART_TX, ch); | ||
1383 | } | ||
1384 | |||
1380 | /* | 1385 | /* |
1381 | * Print a string to the serial port trying not to disturb | 1386 | * Print a string to the serial port trying not to disturb |
1382 | * any possible real use of the port... | 1387 | * any possible real use of the port... |
@@ -1386,7 +1391,6 @@ static void sunsu_console_write(struct console *co, const char *s, | |||
1386 | { | 1391 | { |
1387 | struct uart_sunsu_port *up = &sunsu_ports[co->index]; | 1392 | struct uart_sunsu_port *up = &sunsu_ports[co->index]; |
1388 | unsigned int ier; | 1393 | unsigned int ier; |
1389 | int i; | ||
1390 | 1394 | ||
1391 | /* | 1395 | /* |
1392 | * First save the UER then disable the interrupts | 1396 | * First save the UER then disable the interrupts |
@@ -1394,22 +1398,7 @@ static void sunsu_console_write(struct console *co, const char *s, | |||
1394 | ier = serial_in(up, UART_IER); | 1398 | ier = serial_in(up, UART_IER); |
1395 | serial_out(up, UART_IER, 0); | 1399 | serial_out(up, UART_IER, 0); |
1396 | 1400 | ||
1397 | /* | 1401 | uart_console_write(&up->port, s, count, sunsu_console_putchar); |
1398 | * Now, do each character | ||
1399 | */ | ||
1400 | for (i = 0; i < count; i++, s++) { | ||
1401 | wait_for_xmitr(up); | ||
1402 | |||
1403 | /* | ||
1404 | * Send the character out. | ||
1405 | * If a LF, also do CR... | ||
1406 | */ | ||
1407 | serial_out(up, UART_TX, *s); | ||
1408 | if (*s == 10) { | ||
1409 | wait_for_xmitr(up); | ||
1410 | serial_out(up, UART_TX, 13); | ||
1411 | } | ||
1412 | } | ||
1413 | 1402 | ||
1414 | /* | 1403 | /* |
1415 | * Finally, wait for transmitter to become empty | 1404 | * Finally, wait for transmitter to become empty |
diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c index 10b35c6f287d..cd49ebbf4a45 100644 --- a/drivers/serial/sunzilog.c +++ b/drivers/serial/sunzilog.c | |||
@@ -1252,8 +1252,9 @@ static struct zilog_layout __iomem * __init get_zs(int chip, int node) | |||
1252 | 1252 | ||
1253 | #define ZS_PUT_CHAR_MAX_DELAY 2000 /* 10 ms */ | 1253 | #define ZS_PUT_CHAR_MAX_DELAY 2000 /* 10 ms */ |
1254 | 1254 | ||
1255 | static void sunzilog_put_char(struct zilog_channel __iomem *channel, unsigned char ch) | 1255 | static void sunzilog_putchar(struct uart_port *port, int ch) |
1256 | { | 1256 | { |
1257 | struct zilog_channel *channel = ZILOG_CHANNEL_FROM_PORT(port); | ||
1257 | int loops = ZS_PUT_CHAR_MAX_DELAY; | 1258 | int loops = ZS_PUT_CHAR_MAX_DELAY; |
1258 | 1259 | ||
1259 | /* This is a timed polling loop so do not switch the explicit | 1260 | /* This is a timed polling loop so do not switch the explicit |
@@ -1284,7 +1285,7 @@ static int sunzilog_serio_write(struct serio *serio, unsigned char ch) | |||
1284 | 1285 | ||
1285 | spin_lock_irqsave(&sunzilog_serio_lock, flags); | 1286 | spin_lock_irqsave(&sunzilog_serio_lock, flags); |
1286 | 1287 | ||
1287 | sunzilog_put_char(ZILOG_CHANNEL_FROM_PORT(&up->port), ch); | 1288 | sunzilog_putchar(&up->port, ch); |
1288 | 1289 | ||
1289 | spin_unlock_irqrestore(&sunzilog_serio_lock, flags); | 1290 | spin_unlock_irqrestore(&sunzilog_serio_lock, flags); |
1290 | 1291 | ||
@@ -1325,16 +1326,10 @@ static void | |||
1325 | sunzilog_console_write(struct console *con, const char *s, unsigned int count) | 1326 | sunzilog_console_write(struct console *con, const char *s, unsigned int count) |
1326 | { | 1327 | { |
1327 | struct uart_sunzilog_port *up = &sunzilog_port_table[con->index]; | 1328 | struct uart_sunzilog_port *up = &sunzilog_port_table[con->index]; |
1328 | struct zilog_channel *channel = ZILOG_CHANNEL_FROM_PORT(&up->port); | ||
1329 | unsigned long flags; | 1329 | unsigned long flags; |
1330 | int i; | ||
1331 | 1330 | ||
1332 | spin_lock_irqsave(&up->port.lock, flags); | 1331 | spin_lock_irqsave(&up->port.lock, flags); |
1333 | for (i = 0; i < count; i++, s++) { | 1332 | uart_console_write(&up->port, s, count, sunzilog_putchar); |
1334 | sunzilog_put_char(channel, *s); | ||
1335 | if (*s == 10) | ||
1336 | sunzilog_put_char(channel, 13); | ||
1337 | } | ||
1338 | udelay(2); | 1333 | udelay(2); |
1339 | spin_unlock_irqrestore(&up->port.lock, flags); | 1334 | spin_unlock_irqrestore(&up->port.lock, flags); |
1340 | } | 1335 | } |
diff --git a/drivers/serial/vr41xx_siu.c b/drivers/serial/vr41xx_siu.c index d61494d185cd..df5e8713fa31 100644 --- a/drivers/serial/vr41xx_siu.c +++ b/drivers/serial/vr41xx_siu.c | |||
@@ -821,25 +821,23 @@ static void wait_for_xmitr(struct uart_port *port) | |||
821 | } | 821 | } |
822 | } | 822 | } |
823 | 823 | ||
824 | static void siu_console_putchar(struct uart_port *port, int ch) | ||
825 | { | ||
826 | wait_for_xmitr(port); | ||
827 | siu_write(port, UART_TX, ch); | ||
828 | } | ||
829 | |||
824 | static void siu_console_write(struct console *con, const char *s, unsigned count) | 830 | static void siu_console_write(struct console *con, const char *s, unsigned count) |
825 | { | 831 | { |
826 | struct uart_port *port; | 832 | struct uart_port *port; |
827 | uint8_t ier; | 833 | uint8_t ier; |
828 | unsigned i; | ||
829 | 834 | ||
830 | port = &siu_uart_ports[con->index]; | 835 | port = &siu_uart_ports[con->index]; |
831 | 836 | ||
832 | ier = siu_read(port, UART_IER); | 837 | ier = siu_read(port, UART_IER); |
833 | siu_write(port, UART_IER, 0); | 838 | siu_write(port, UART_IER, 0); |
834 | 839 | ||
835 | for (i = 0; i < count && *s != '\0'; i++, s++) { | 840 | uart_console_write(port, s, count, siu_console_putchar); |
836 | wait_for_xmitr(port); | ||
837 | siu_write(port, UART_TX, *s); | ||
838 | if (*s == '\n') { | ||
839 | wait_for_xmitr(port); | ||
840 | siu_write(port, UART_TX, '\r'); | ||
841 | } | ||
842 | } | ||
843 | 841 | ||
844 | wait_for_xmitr(port); | 842 | wait_for_xmitr(port); |
845 | siu_write(port, UART_IER, ier); | 843 | siu_write(port, UART_IER, ier); |
@@ -919,7 +917,7 @@ static struct uart_driver siu_uart_driver = { | |||
919 | .cons = SERIAL_VR41XX_CONSOLE, | 917 | .cons = SERIAL_VR41XX_CONSOLE, |
920 | }; | 918 | }; |
921 | 919 | ||
922 | static int siu_probe(struct platform_device *dev) | 920 | static int __devinit siu_probe(struct platform_device *dev) |
923 | { | 921 | { |
924 | struct uart_port *port; | 922 | struct uart_port *port; |
925 | int num, i, retval; | 923 | int num, i, retval; |
@@ -953,7 +951,7 @@ static int siu_probe(struct platform_device *dev) | |||
953 | return 0; | 951 | return 0; |
954 | } | 952 | } |
955 | 953 | ||
956 | static int siu_remove(struct platform_device *dev) | 954 | static int __devexit siu_remove(struct platform_device *dev) |
957 | { | 955 | { |
958 | struct uart_port *port; | 956 | struct uart_port *port; |
959 | int i; | 957 | int i; |
@@ -1006,21 +1004,28 @@ static struct platform_device *siu_platform_device; | |||
1006 | 1004 | ||
1007 | static struct platform_driver siu_device_driver = { | 1005 | static struct platform_driver siu_device_driver = { |
1008 | .probe = siu_probe, | 1006 | .probe = siu_probe, |
1009 | .remove = siu_remove, | 1007 | .remove = __devexit_p(siu_remove), |
1010 | .suspend = siu_suspend, | 1008 | .suspend = siu_suspend, |
1011 | .resume = siu_resume, | 1009 | .resume = siu_resume, |
1012 | .driver = { | 1010 | .driver = { |
1013 | .name = "SIU", | 1011 | .name = "SIU", |
1012 | .owner = THIS_MODULE, | ||
1014 | }, | 1013 | }, |
1015 | }; | 1014 | }; |
1016 | 1015 | ||
1017 | static int __devinit vr41xx_siu_init(void) | 1016 | static int __init vr41xx_siu_init(void) |
1018 | { | 1017 | { |
1019 | int retval; | 1018 | int retval; |
1020 | 1019 | ||
1021 | siu_platform_device = platform_device_register_simple("SIU", -1, NULL, 0); | 1020 | siu_platform_device = platform_device_alloc("SIU", -1); |
1022 | if (IS_ERR(siu_platform_device)) | 1021 | if (!siu_platform_device) |
1023 | return PTR_ERR(siu_platform_device); | 1022 | return -ENOMEM; |
1023 | |||
1024 | retval = platform_device_add(siu_platform_device); | ||
1025 | if (retval < 0) { | ||
1026 | platform_device_put(siu_platform_device); | ||
1027 | return retval; | ||
1028 | } | ||
1024 | 1029 | ||
1025 | retval = platform_driver_register(&siu_device_driver); | 1030 | retval = platform_driver_register(&siu_device_driver); |
1026 | if (retval < 0) | 1031 | if (retval < 0) |
@@ -1029,10 +1034,9 @@ static int __devinit vr41xx_siu_init(void) | |||
1029 | return retval; | 1034 | return retval; |
1030 | } | 1035 | } |
1031 | 1036 | ||
1032 | static void __devexit vr41xx_siu_exit(void) | 1037 | static void __exit vr41xx_siu_exit(void) |
1033 | { | 1038 | { |
1034 | platform_driver_unregister(&siu_device_driver); | 1039 | platform_driver_unregister(&siu_device_driver); |
1035 | |||
1036 | platform_device_unregister(siu_platform_device); | 1040 | platform_device_unregister(siu_platform_device); |
1037 | } | 1041 | } |
1038 | 1042 | ||