X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fserial%2Famba-pl011.c;h=3d966cfc9a38cba524a5a13383f4c6bda4a62328;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=7db88ee18f75fb1f138f71921c05d833aa935a51;hpb=cee37fe97739d85991964371c1f3a745c00dd236;p=linux-2.6.git diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c index 7db88ee18..3d966cfc9 100644 --- a/drivers/serial/amba-pl011.c +++ b/drivers/serial/amba-pl011.c @@ -47,12 +47,12 @@ #include #include #include +#include +#include +#include #include -#include -#include -#include -#include +#include #define UART_NR 14 @@ -62,7 +62,8 @@ #define AMBA_ISR_PASS_LIMIT 256 -#define UART_DUMMY_RSR_RX 256 +#define UART_DR_ERROR (UART011_DR_OE|UART011_DR_BE|UART011_DR_PE|UART011_DR_FE) +#define UART_DUMMY_DR_RX (1 << 16) /* * We wrap our port structure around the generic uart_port. @@ -74,7 +75,7 @@ struct uart_amba_port { unsigned int old_status; }; -static void pl011_stop_tx(struct uart_port *port, unsigned int tty_stop) +static void pl011_stop_tx(struct uart_port *port) { struct uart_amba_port *uap = (struct uart_amba_port *)port; @@ -82,7 +83,7 @@ static void pl011_stop_tx(struct uart_port *port, unsigned int tty_stop) writew(uap->im, uap->port.membase + UART011_IMSC); } -static void pl011_start_tx(struct uart_port *port, unsigned int tty_start) +static void pl011_start_tx(struct uart_port *port) { struct uart_amba_port *uap = (struct uart_amba_port *)port; @@ -115,20 +116,11 @@ pl011_rx_chars(struct uart_amba_port *uap) #endif { struct tty_struct *tty = uap->port.info->tty; - unsigned int status, ch, flag, rsr, max_count = 256; + unsigned int status, ch, flag, max_count = 256; status = readw(uap->port.membase + UART01x_FR); while ((status & UART01x_FR_RXFE) == 0 && max_count--) { - if (tty->flip.count >= TTY_FLIPBUF_SIZE) { - if (tty->low_latency) - tty_flip_buffer_push(tty); - /* - * If this failed then we will throw away the - * bytes but must do so to clear interrupts - */ - } - - ch = readw(uap->port.membase + UART01x_DR); + ch = readw(uap->port.membase + UART01x_DR) | UART_DUMMY_DR_RX; flag = TTY_NORMAL; uap->port.icount.rx++; @@ -136,34 +128,33 @@ pl011_rx_chars(struct uart_amba_port *uap) * Note that the error handling code is * out of the main execution path */ - rsr = readw(uap->port.membase + UART01x_RSR) | UART_DUMMY_RSR_RX; - if (unlikely(rsr & UART01x_RSR_ANY)) { - if (rsr & UART01x_RSR_BE) { - rsr &= ~(UART01x_RSR_FE | UART01x_RSR_PE); + if (unlikely(ch & UART_DR_ERROR)) { + if (ch & UART011_DR_BE) { + ch &= ~(UART011_DR_FE | UART011_DR_PE); uap->port.icount.brk++; if (uart_handle_break(&uap->port)) goto ignore_char; - } else if (rsr & UART01x_RSR_PE) + } else if (ch & UART011_DR_PE) uap->port.icount.parity++; - else if (rsr & UART01x_RSR_FE) + else if (ch & UART011_DR_FE) uap->port.icount.frame++; - if (rsr & UART01x_RSR_OE) + if (ch & UART011_DR_OE) uap->port.icount.overrun++; - rsr &= uap->port.read_status_mask; + ch &= uap->port.read_status_mask; - if (rsr & UART01x_RSR_BE) + if (ch & UART011_DR_BE) flag = TTY_BREAK; - else if (rsr & UART01x_RSR_PE) + else if (ch & UART011_DR_PE) flag = TTY_PARITY; - else if (rsr & UART01x_RSR_FE) + else if (ch & UART011_DR_FE) flag = TTY_FRAME; } - if (uart_handle_sysrq_char(&uap->port, ch, regs)) + if (uart_handle_sysrq_char(&uap->port, ch & 255, regs)) goto ignore_char; - uart_insert_char(&uap->port, rsr, UART01x_RSR_OE, ch, flag); + uart_insert_char(&uap->port, ch, UART011_DR_OE, ch, flag); ignore_char: status = readw(uap->port.membase + UART01x_FR); @@ -184,7 +175,7 @@ static void pl011_tx_chars(struct uart_amba_port *uap) return; } if (uart_circ_empty(xmit) || uart_tx_stopped(&uap->port)) { - pl011_stop_tx(&uap->port, 0); + pl011_stop_tx(&uap->port); return; } @@ -201,7 +192,7 @@ static void pl011_tx_chars(struct uart_amba_port *uap) uart_write_wakeup(&uap->port); if (uart_circ_empty(xmit)) - pl011_stop_tx(&uap->port, 0); + pl011_stop_tx(&uap->port); } static void pl011_modem_status(struct uart_amba_port *uap) @@ -475,33 +466,33 @@ pl011_set_termios(struct uart_port *port, struct termios *termios, */ uart_update_timeout(port, termios->c_cflag, baud); - port->read_status_mask = UART01x_RSR_OE; + port->read_status_mask = UART011_DR_OE | 255; if (termios->c_iflag & INPCK) - port->read_status_mask |= UART01x_RSR_FE | UART01x_RSR_PE; + port->read_status_mask |= UART011_DR_FE | UART011_DR_PE; if (termios->c_iflag & (BRKINT | PARMRK)) - port->read_status_mask |= UART01x_RSR_BE; + port->read_status_mask |= UART011_DR_BE; /* * Characters to ignore */ port->ignore_status_mask = 0; if (termios->c_iflag & IGNPAR) - port->ignore_status_mask |= UART01x_RSR_FE | UART01x_RSR_PE; + port->ignore_status_mask |= UART011_DR_FE | UART011_DR_PE; if (termios->c_iflag & IGNBRK) { - port->ignore_status_mask |= UART01x_RSR_BE; + port->ignore_status_mask |= UART011_DR_BE; /* * If we're ignoring parity and break indicators, * ignore overruns too (for real raw support). */ if (termios->c_iflag & IGNPAR) - port->ignore_status_mask |= UART01x_RSR_OE; + port->ignore_status_mask |= UART011_DR_OE; } /* * Ignore all characters if CREAD is not set. */ if ((termios->c_cflag & CREAD) == 0) - port->ignore_status_mask |= UART_DUMMY_RSR_RX; + port->ignore_status_mask |= UART_DUMMY_DR_RX; if (UART_ENABLE_MS(port, termios->c_cflag)) pl011_enable_ms(port); @@ -596,14 +587,12 @@ static struct uart_amba_port *amba_ports[UART_NR]; #ifdef CONFIG_SERIAL_AMBA_PL011_CONSOLE -static inline void -pl011_console_write_char(struct uart_amba_port *uap, char ch) +static void pl011_console_putchar(struct uart_port *port, int ch) { - unsigned int status; + struct uart_amba_port *uap = (struct uart_amba_port *)port; - do { - status = readw(uap->port.membase + UART01x_FR); - } while (status & UART01x_FR_TXFF); + while (readw(uap->port.membase + UART01x_FR) & UART01x_FR_TXFF) + barrier(); writew(ch, uap->port.membase + UART01x_DR); } @@ -612,7 +601,6 @@ pl011_console_write(struct console *co, const char *s, unsigned int count) { struct uart_amba_port *uap = amba_ports[co->index]; unsigned int status, old_cr, new_cr; - int i; clk_enable(uap->clk); @@ -624,14 +612,7 @@ pl011_console_write(struct console *co, const char *s, unsigned int count) new_cr |= UART01x_CR_UARTEN | UART011_CR_TXE; writew(new_cr, uap->port.membase + UART011_CR); - /* - * Now, do each character - */ - for (i = 0; i < count; i++) { - pl011_console_write_char(uap, s[i]); - if (s[i] == '\n') - pl011_console_write_char(uap, '\r'); - } + uart_console_write(&uap->port, s, count, pl011_console_putchar); /* * Finally, wait for transmitter to become empty @@ -701,7 +682,7 @@ static int __init pl011_console_setup(struct console *co, char *options) return uart_set_options(&uap->port, co, baud, parity, bits, flow); } -extern struct uart_driver amba_reg; +static struct uart_driver amba_reg; static struct console amba_console = { .name = "ttyAMA", .write = pl011_console_write, @@ -761,10 +742,6 @@ static int pl011_probe(struct amba_device *dev, void *id) goto unmap; } - ret = clk_use(uap->clk); - if (ret) - goto putclk; - uap->port.dev = &dev->dev; uap->port.mapbase = dev->res.start; uap->port.membase = base; @@ -782,8 +759,6 @@ static int pl011_probe(struct amba_device *dev, void *id) if (ret) { amba_set_drvdata(dev, NULL); amba_ports[i] = NULL; - clk_unuse(uap->clk); - putclk: clk_put(uap->clk); unmap: iounmap(base); @@ -808,7 +783,6 @@ static int pl011_remove(struct amba_device *dev) amba_ports[i] = NULL; iounmap(uap->port.membase); - clk_unuse(uap->clk); clk_put(uap->clk); kfree(uap); return 0;