From d5f1f475797608a219fb3b458ed9935e03d0ed29 Mon Sep 17 00:00:00 2001 From: Naveen Kumar GADDIPATI Date: Wed, 28 Mar 2012 07:23:43 +0200 Subject: Revert "serial:pl011:Patch for resume and hibernation issue" This patch still the problem comes for cw1200. This reverts commit 77e19ebf618f63d3e71b16e94e7291bc0bd37e90. --- drivers/tty/serial/amba-pl011.c | 37 +++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index fc4cf2802c2..f36663af790 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -196,6 +196,7 @@ struct uart_amba_port { unsigned int ifls; /* vendor-specific */ unsigned int lcrh_tx; /* vendor-specific */ unsigned int lcrh_rx; /* vendor-specific */ + unsigned int old_cr; /* state during shutdown */ bool autorts; #ifdef CONFIG_SERIAL_AMBA_PL011_CLOCK_CONTROL enum pl011_clk_states clk_state; /* actual clock state */ @@ -1110,6 +1111,10 @@ static void pl011_lockup_wa(unsigned long data) int buf_empty_retries = 200; int loop; + /* Exit early if there is no tty */ + if (!tty) + return; + /* Stop HCI layer from submitting data for tx */ tty->hw_stopped = 1; while (!uart_circ_empty(xmit)) { @@ -1678,12 +1683,16 @@ static int pl011_startup(struct uart_port *port) unsigned int cr; int retval; + retval = clk_prepare(uap->clk); + if (retval) + goto out; + /* * Try to enable the clock producer and the regulator. */ retval = pl011_power_startup(uap); if (retval) - goto out; + goto clk_unprep; uap->port.uartclk = clk_get_rate(uap->clk); @@ -1696,7 +1705,9 @@ static int pl011_startup(struct uart_port *port) __pl011_startup(uap); - cr = UART01x_CR_UARTEN | UART011_CR_RXE | UART011_CR_TXE; + /* restore RTS and DTR */ + cr = uap->old_cr & (UART011_CR_RTS | UART011_CR_DTR); + cr |= UART01x_CR_UARTEN | UART011_CR_RXE | UART011_CR_TXE; writew(cr, uap->port.membase + UART011_CR); /* Clear pending error interrupts */ @@ -1736,6 +1747,8 @@ static int pl011_startup(struct uart_port *port) clk_dis: pl011_power_shutdown(uap); + clk_unprep: + clk_unprepare(uap->clk); out: return retval; } @@ -1773,10 +1786,16 @@ static void pl011_shutdown(struct uart_port *port) /* * disable the port + * disable the port. It should not disable RTS and DTR. + * Also RTS and DTR state should be preserved to restore + * it during startup(). */ uap->autorts = false; - writew(UART01x_CR_UARTEN | UART011_CR_TXE, - uap->port.membase + UART011_CR); + cr = readw(uap->port.membase + UART011_CR); + uap->old_cr = cr; + cr &= UART011_CR_RTS | UART011_CR_DTR; + cr |= UART01x_CR_UARTEN | UART011_CR_TXE; + writew(cr, uap->port.membase + UART011_CR); /* * disable break condition and fifos @@ -1797,7 +1816,7 @@ static void pl011_shutdown(struct uart_port *port) * Shut down the clock producer and the producer */ pl011_power_shutdown(uap); - + clk_unprepare(uap->clk); if (uap->port.dev->platform_data) { struct amba_pl011_data *plat; @@ -1955,7 +1974,7 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios, /* * ----------v----------v----------v----------v----- - * NOTE: lcrh_tx and lcrh_rx MUST BE WRITTEN AFTER + * NOTE: MUST BE WRITTEN AFTER UARTLCR_M & UARTLCR_L * ----------^----------^----------^----------^----- */ writew(lcr_h, port->membase + uap->lcrh_rx); @@ -2145,6 +2164,7 @@ static int __init pl011_console_setup(struct console *co, char *options) int bits = 8; int parity = 'n'; int flow = 'n'; + int ret; /* * Check whether an invalid uart number has been specified, and @@ -2157,6 +2177,10 @@ static int __init pl011_console_setup(struct console *co, char *options) if (!uap) return -ENODEV; + ret = clk_prepare(uap->clk); + if (ret) + return ret; + if (uap->port.dev->platform_data) { struct amba_pl011_data *plat; @@ -2251,6 +2275,7 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) uap->ifls = vendor->ifls; uap->lcrh_rx = vendor->lcrh_rx; uap->lcrh_tx = vendor->lcrh_tx; + uap->old_cr = 0; uap->fifosize = vendor->fifosize; uap->interrupt_may_hang = vendor->interrupt_may_hang; uap->port.dev = &dev->dev; -- cgit v1.2.3