summaryrefslogtreecommitdiffstats
path: root/drivers/tty/serial/amba-pl011.c
diff options
context:
space:
mode:
authorShreshtha Kumar Sahu <shreshthakumar.sahu@stericsson.com>2012-01-18 15:53:59 +0530
committerGreg Kroah-Hartman <gregkh@suse.de>2012-01-24 16:09:55 -0800
commitd8d8ffa477831b713ddfa2ad4d0ca545f3b567e5 (patch)
treee92a37aa1d8a0931aff920f30433d45c9271b93f /drivers/tty/serial/amba-pl011.c
parent43cf7c0bebf50d0b68aa42ae6d24cf08e3f24823 (diff)
downloadlinux-stable-d8d8ffa477831b713ddfa2ad4d0ca545f3b567e5.tar.gz
linux-stable-d8d8ffa477831b713ddfa2ad4d0ca545f3b567e5.tar.bz2
linux-stable-d8d8ffa477831b713ddfa2ad4d0ca545f3b567e5.zip
amba-pl011: do not disable RTS during shutdown
In present driver, shutdown clears RTS and DTR in CR register. But the documentation "Documentation/serial/driver" suggests not to disable RTS and DTR in shutdown(). Also RTS and DTR is preserved between shutdown and startup calls, i.e. these are restored in startup if they were enabled while doing shutdown. So that if RTS and DTR are set using pl011_set_mctrl then it should continue even after shutdown->startup sequence. For throttling/unthrottling user should call pl011_set_mctrl. Signed-off-by: Shreshtha Kumar Sahu <shreshthakumar.sahu@stericsson.com> Acked-by: Linus Walleij <linus.walleij@linaro.org> Acked-by: Russell King <rmk+kernel@arm.linux.org.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/tty/serial/amba-pl011.c')
-rw-r--r--drivers/tty/serial/amba-pl011.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
index 9ae024025ff3..ce843d058e02 100644
--- a/drivers/tty/serial/amba-pl011.c
+++ b/drivers/tty/serial/amba-pl011.c
@@ -159,6 +159,7 @@ struct uart_amba_port {
unsigned int fifosize; /* vendor-specific */
unsigned int lcrh_tx; /* vendor-specific */
unsigned int lcrh_rx; /* vendor-specific */
+ unsigned int old_cr; /* state during shutdown */
bool autorts;
char type[12];
bool interrupt_may_hang; /* vendor-specific */
@@ -1411,7 +1412,9 @@ static int pl011_startup(struct uart_port *port)
while (readw(uap->port.membase + UART01x_FR) & UART01x_FR_BUSY)
barrier();
- 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 */
@@ -1469,6 +1472,7 @@ static void pl011_shutdown_channel(struct uart_amba_port *uap,
static void pl011_shutdown(struct uart_port *port)
{
struct uart_amba_port *uap = (struct uart_amba_port *)port;
+ unsigned int cr;
/*
* disable all interrupts
@@ -1488,9 +1492,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
@@ -1905,6 +1916,7 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id)
uap->vendor = vendor;
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;