X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fserial%2Famba-pl011.c;h=954073c6ce3a4e5cccb7df1806575fc1778cbc2c;hb=a88487c79bfefb715030c5baa68fbedc1b8732e8;hp=9a3b374b2a08d89399b91d75cd613351b83978bf;hpb=463e7c7cf9aaf95dd05e97e1a47854fdf5454cdc;p=linux-2.6-omap-h63xx.git diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c index 9a3b374b2a0..9d08f27208a 100644 --- a/drivers/serial/amba-pl011.c +++ b/drivers/serial/amba-pl011.c @@ -22,8 +22,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id: amba.c,v 1.41 2002/07/28 10:03:27 rmk Exp $ - * * This is a generic driver for ARM AMBA-type serial ports. They * have a lot of 16550-like features, but are not register compatible. * Note that although they do have CTS, DCD and DSR inputs, they do @@ -109,7 +107,7 @@ static void pl011_enable_ms(struct uart_port *port) static void pl011_rx_chars(struct uart_amba_port *uap) { - struct tty_struct *tty = uap->port.info->tty; + struct tty_struct *tty = uap->port.info->port.tty; unsigned int status, ch, flag, max_count = 256; status = readw(uap->port.membase + UART01x_FR); @@ -153,8 +151,9 @@ static void pl011_rx_chars(struct uart_amba_port *uap) ignore_char: status = readw(uap->port.membase + UART01x_FR); } + spin_unlock(&uap->port.lock); tty_flip_buffer_push(tty); - return; + spin_lock(&uap->port.lock); } static void pl011_tx_chars(struct uart_amba_port *uap) @@ -262,15 +261,15 @@ static unsigned int pl01x_get_mctrl(struct uart_port *port) unsigned int result = 0; unsigned int status = readw(uap->port.membase + UART01x_FR); -#define BIT(uartbit, tiocmbit) \ +#define TIOCMBIT(uartbit, tiocmbit) \ if (status & uartbit) \ result |= tiocmbit - BIT(UART01x_FR_DCD, TIOCM_CAR); - BIT(UART01x_FR_DSR, TIOCM_DSR); - BIT(UART01x_FR_CTS, TIOCM_CTS); - BIT(UART011_FR_RI, TIOCM_RNG); -#undef BIT + TIOCMBIT(UART01x_FR_DCD, TIOCM_CAR); + TIOCMBIT(UART01x_FR_DSR, TIOCM_DSR); + TIOCMBIT(UART01x_FR_CTS, TIOCM_CTS); + TIOCMBIT(UART011_FR_RI, TIOCM_RNG); +#undef TIOCMBIT return result; } @@ -281,18 +280,18 @@ static void pl011_set_mctrl(struct uart_port *port, unsigned int mctrl) cr = readw(uap->port.membase + UART011_CR); -#define BIT(tiocmbit, uartbit) \ +#define TIOCMBIT(tiocmbit, uartbit) \ if (mctrl & tiocmbit) \ cr |= uartbit; \ else \ cr &= ~uartbit - BIT(TIOCM_RTS, UART011_CR_RTS); - BIT(TIOCM_DTR, UART011_CR_DTR); - BIT(TIOCM_OUT1, UART011_CR_OUT1); - BIT(TIOCM_OUT2, UART011_CR_OUT2); - BIT(TIOCM_LOOP, UART011_CR_LBE); -#undef BIT + TIOCMBIT(TIOCM_RTS, UART011_CR_RTS); + TIOCMBIT(TIOCM_DTR, UART011_CR_DTR); + TIOCMBIT(TIOCM_OUT1, UART011_CR_OUT1); + TIOCMBIT(TIOCM_OUT2, UART011_CR_OUT2); + TIOCMBIT(TIOCM_LOOP, UART011_CR_LBE); +#undef TIOCMBIT writew(cr, uap->port.membase + UART011_CR); } @@ -313,6 +312,32 @@ static void pl011_break_ctl(struct uart_port *port, int break_state) spin_unlock_irqrestore(&uap->port.lock, flags); } +#ifdef CONFIG_CONSOLE_POLL +static int pl010_get_poll_char(struct uart_port *port) +{ + struct uart_amba_port *uap = (struct uart_amba_port *)port; + unsigned int status; + + do { + status = readw(uap->port.membase + UART01x_FR); + } while (status & UART01x_FR_RXFE); + + return readw(uap->port.membase + UART01x_DR); +} + +static void pl010_put_poll_char(struct uart_port *port, + unsigned char ch) +{ + struct uart_amba_port *uap = (struct uart_amba_port *)port; + + while (readw(uap->port.membase + UART01x_FR) & UART01x_FR_TXFF) + barrier(); + + writew(ch, uap->port.membase + UART01x_DR); +} + +#endif /* CONFIG_CONSOLE_POLL */ + static int pl011_startup(struct uart_port *port) { struct uart_amba_port *uap = (struct uart_amba_port *)port; @@ -571,6 +596,10 @@ static struct uart_ops amba_pl011_pops = { .request_port = pl010_request_port, .config_port = pl010_config_port, .verify_port = pl010_verify_port, +#ifdef CONFIG_CONSOLE_POLL + .poll_get_char = pl010_get_poll_char, + .poll_put_char = pl010_put_poll_char, +#endif }; static struct uart_amba_port *amba_ports[UART_NR]; @@ -661,6 +690,8 @@ static int __init pl011_console_setup(struct console *co, char *options) if (co->index >= UART_NR) co->index = 0; uap = amba_ports[co->index]; + if (!uap) + return -ENODEV; uap->port.uartclk = clk_get_rate(uap->clk); @@ -713,7 +744,7 @@ static int pl011_probe(struct amba_device *dev, void *id) goto out; } - uap = kmalloc(sizeof(struct uart_amba_port), GFP_KERNEL); + uap = kzalloc(sizeof(struct uart_amba_port), GFP_KERNEL); if (uap == NULL) { ret = -ENOMEM; goto out; @@ -725,7 +756,6 @@ static int pl011_probe(struct amba_device *dev, void *id) goto free; } - memset(uap, 0, sizeof(struct uart_amba_port)); uap->clk = clk_get(&dev->dev, "UARTCLK"); if (IS_ERR(uap->clk)) { ret = PTR_ERR(uap->clk);