X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fserial%2Fclps711x.c;h=2691112c84adacc0c52724ff5319d3852eb6ea65;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=4aaef99d120b54c7e154e1ae7391f0b18c0ff298;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/drivers/serial/clps711x.c b/drivers/serial/clps711x.c index 4aaef99d1..2691112c8 100644 --- a/drivers/serial/clps711x.c +++ b/drivers/serial/clps711x.c @@ -26,26 +26,26 @@ * */ #include + +#if defined(CONFIG_SERIAL_CLPS711X_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) +#define SUPPORT_SYSRQ +#endif + #include -#include #include #include -#include #include #include #include #include +#include +#include +#include +#include #include #include #include - -#if defined(CONFIG_SERIAL_CLPS711X_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) -#define SUPPORT_SYSRQ -#endif - -#include - #include #define UART_NR 2 @@ -69,8 +69,7 @@ #define tx_enabled(port) ((port)->unused[0]) -static void -clps711xuart_stop_tx(struct uart_port *port, unsigned int tty_stop) +static void clps711xuart_stop_tx(struct uart_port *port) { if (tx_enabled(port)) { disable_irq(TX_IRQ(port)); @@ -78,8 +77,7 @@ clps711xuart_stop_tx(struct uart_port *port, unsigned int tty_stop) } } -static void -clps711xuart_start_tx(struct uart_port *port, unsigned int tty_start) +static void clps711xuart_start_tx(struct uart_port *port) { if (!tx_enabled(port)) { enable_irq(TX_IRQ(port)); @@ -100,14 +98,12 @@ static irqreturn_t clps711xuart_int_rx(int irq, void *dev_id, struct pt_regs *re { struct uart_port *port = dev_id; struct tty_struct *tty = port->info->tty; - unsigned int status, ch, flg, ignored = 0; + unsigned int status, ch, flg; status = clps_readl(SYSFLG(port)); while (!(status & SYSFLG_URXFE)) { ch = clps_readl(UARTDR(port)); - if (tty->flip.count >= TTY_FLIPBUF_SIZE) - goto ignore_char; port->icount.rx++; flg = TTY_NORMAL; @@ -116,60 +112,40 @@ static irqreturn_t clps711xuart_int_rx(int irq, void *dev_id, struct pt_regs *re * Note that the error handling code is * out of the main execution path */ - if (ch & UART_ANY_ERR) - goto handle_error; + if (unlikely(ch & UART_ANY_ERR)) { + if (ch & UARTDR_PARERR) + port->icount.parity++; + else if (ch & UARTDR_FRMERR) + port->icount.frame++; + if (ch & UARTDR_OVERR) + port->icount.overrun++; - if (uart_handle_sysrq_char(port, ch, regs)) - goto ignore_char; + ch &= port->read_status_mask; - error_return: - *tty->flip.flag_buf_ptr++ = flg; - *tty->flip.char_buf_ptr++ = ch; - tty->flip.count++; - ignore_char: - status = clps_readl(SYSFLG(port)); - } - out: - tty_flip_buffer_push(tty); - return IRQ_HANDLED; + if (ch & UARTDR_PARERR) + flg = TTY_PARITY; + else if (ch & UARTDR_FRMERR) + flg = TTY_FRAME; - handle_error: - if (ch & UARTDR_PARERR) - port->icount.parity++; - else if (ch & UARTDR_FRMERR) - port->icount.frame++; - if (ch & UARTDR_OVERR) - port->icount.overrun++; - - if (ch & port->ignore_status_mask) { - if (++ignored > 100) - goto out; - goto ignore_char; - } - ch &= port->read_status_mask; +#ifdef SUPPORT_SYSRQ + port->sysrq = 0; +#endif + } - if (ch & UARTDR_PARERR) - flg = TTY_PARITY; - else if (ch & UARTDR_FRMERR) - flg = TTY_FRAME; + if (uart_handle_sysrq_char(port, ch, regs)) + goto ignore_char; - if (ch & UARTDR_OVERR) { /* * CHECK: does overrun affect the current character? * ASSUMPTION: it does not. */ - *tty->flip.flag_buf_ptr++ = flg; - *tty->flip.char_buf_ptr++ = ch; - tty->flip.count++; - if (tty->flip.count >= TTY_FLIPBUF_SIZE) - goto ignore_char; - ch = 0; - flg = TTY_OVERRUN; + uart_insert_char(port, ch, UARTDR_OVERR, ch, flg); + + ignore_char: + status = clps_readl(SYSFLG(port)); } -#ifdef SUPPORT_SYSRQ - port->sysrq = 0; -#endif - goto error_return; + tty_flip_buffer_push(tty); + return IRQ_HANDLED; } static irqreturn_t clps711xuart_int_tx(int irq, void *dev_id, struct pt_regs *regs) @@ -185,7 +161,7 @@ static irqreturn_t clps711xuart_int_tx(int irq, void *dev_id, struct pt_regs *re return IRQ_HANDLED; } if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { - clps711xuart_stop_tx(port, 0); + clps711xuart_stop_tx(port); return IRQ_HANDLED; } @@ -202,7 +178,7 @@ static irqreturn_t clps711xuart_int_tx(int irq, void *dev_id, struct pt_regs *re uart_write_wakeup(port); if (uart_circ_empty(xmit)) - clps711xuart_stop_tx(port, 0); + clps711xuart_stop_tx(port); return IRQ_HANDLED; } @@ -434,7 +410,7 @@ static struct uart_port clps711x_ports[UART_NR] = { .fifosize = 16, .ops = &clps711x_pops, .line = 0, - .flags = ASYNC_BOOT_AUTOCONF, + .flags = UPF_BOOT_AUTOCONF, }, { .iobase = SYSCON2, @@ -443,11 +419,18 @@ static struct uart_port clps711x_ports[UART_NR] = { .fifosize = 16, .ops = &clps711x_pops, .line = 1, - .flags = ASYNC_BOOT_AUTOCONF, + .flags = UPF_BOOT_AUTOCONF, } }; #ifdef CONFIG_SERIAL_CLPS711X_CONSOLE +static void clps711xuart_console_putchar(struct uart_port *port, int ch) +{ + while (clps_readl(SYSFLG(port)) & SYSFLG_UTXFF) + barrier(); + clps_writel(ch, UARTDR(port)); +} + /* * Print a string to the serial port trying not to disturb * any possible real use of the port... @@ -462,7 +445,6 @@ clps711xuart_console_write(struct console *co, const char *s, { struct uart_port *port = clps711x_ports + co->index; unsigned int status, syscon; - int i; /* * Ensure that the port is enabled. @@ -470,21 +452,7 @@ clps711xuart_console_write(struct console *co, const char *s, syscon = clps_readl(SYSCON(port)); clps_writel(syscon | SYSCON_UARTEN, SYSCON(port)); - /* - * Now, do each character - */ - for (i = 0; i < count; i++) { - do { - status = clps_readl(SYSFLG(port)); - } while (status & SYSFLG_UTXFF); - clps_writel(s[i], UARTDR(port)); - if (s[i] == '\n') { - do { - status = clps_readl(SYSFLG(port)); - } while (status & SYSFLG_UTXFF); - clps_writel('\r', UARTDR(port)); - } - } + uart_console_write(port, s, count, clps711xuart_console_putchar); /* * Finally, wait for transmitter to become empty @@ -547,7 +515,7 @@ static int __init clps711xuart_console_setup(struct console *co, char *options) return uart_set_options(port, co, baud, parity, bits, flow); } -extern struct uart_driver clps711x_reg; +static struct uart_driver clps711x_reg; static struct console clps711x_console = { .name = "ttyCL", .write = clps711xuart_console_write,