|
@@ -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;
|