summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNaveen Kumar GADDIPATI <naveen.gaddipati@stericsson.com>2012-03-28 07:23:43 +0200
committerPhilippe Langlais <philippe.langlais@stericsson.com>2012-03-28 10:08:28 +0200
commitd5f1f475797608a219fb3b458ed9935e03d0ed29 (patch)
tree12dd5cd53f6a71987aa6e49ac18f4508afa55be4
parent4e161e450eb210bd92392fcc77e1eaf3cb6ba659 (diff)
Revert "serial:pl011:Patch for resume and hibernation issue"
This patch still the problem comes for cw1200. This reverts commit 77e19ebf618f63d3e71b16e94e7291bc0bd37e90.
-rw-r--r--drivers/tty/serial/amba-pl011.c37
1 files 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;