diff options
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 | ||
