diff options
| -rw-r--r-- | drivers/serial/amba-pl011.c | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c index ef7adc8135dd..ce6c35333ff7 100644 --- a/drivers/serial/amba-pl011.c +++ b/drivers/serial/amba-pl011.c | |||
| @@ -71,6 +71,7 @@ struct uart_amba_port { | |||
| 71 | unsigned int im; /* interrupt mask */ | 71 | unsigned int im; /* interrupt mask */ |
| 72 | unsigned int old_status; | 72 | unsigned int old_status; |
| 73 | unsigned int ifls; /* vendor-specific */ | 73 | unsigned int ifls; /* vendor-specific */ |
| 74 | bool autorts; | ||
| 74 | }; | 75 | }; |
| 75 | 76 | ||
| 76 | /* There is by now at least one vendor with differing details, so handle it */ | 77 | /* There is by now at least one vendor with differing details, so handle it */ |
| @@ -308,6 +309,11 @@ static void pl011_set_mctrl(struct uart_port *port, unsigned int mctrl) | |||
| 308 | TIOCMBIT(TIOCM_OUT1, UART011_CR_OUT1); | 309 | TIOCMBIT(TIOCM_OUT1, UART011_CR_OUT1); |
| 309 | TIOCMBIT(TIOCM_OUT2, UART011_CR_OUT2); | 310 | TIOCMBIT(TIOCM_OUT2, UART011_CR_OUT2); |
| 310 | TIOCMBIT(TIOCM_LOOP, UART011_CR_LBE); | 311 | TIOCMBIT(TIOCM_LOOP, UART011_CR_LBE); |
| 312 | |||
| 313 | if (uap->autorts) { | ||
| 314 | /* We need to disable auto-RTS if we want to turn RTS off */ | ||
| 315 | TIOCMBIT(TIOCM_RTS, UART011_CR_RTSEN); | ||
| 316 | } | ||
| 311 | #undef TIOCMBIT | 317 | #undef TIOCMBIT |
| 312 | 318 | ||
| 313 | writew(cr, uap->port.membase + UART011_CR); | 319 | writew(cr, uap->port.membase + UART011_CR); |
| @@ -437,6 +443,7 @@ static void pl011_shutdown(struct uart_port *port) | |||
| 437 | /* | 443 | /* |
| 438 | * disable the port | 444 | * disable the port |
| 439 | */ | 445 | */ |
| 446 | uap->autorts = false; | ||
| 440 | writew(UART01x_CR_UARTEN | UART011_CR_TXE, uap->port.membase + UART011_CR); | 447 | writew(UART01x_CR_UARTEN | UART011_CR_TXE, uap->port.membase + UART011_CR); |
| 441 | 448 | ||
| 442 | /* | 449 | /* |
| @@ -456,6 +463,7 @@ static void | |||
| 456 | pl011_set_termios(struct uart_port *port, struct ktermios *termios, | 463 | pl011_set_termios(struct uart_port *port, struct ktermios *termios, |
| 457 | struct ktermios *old) | 464 | struct ktermios *old) |
| 458 | { | 465 | { |
| 466 | struct uart_amba_port *uap = (struct uart_amba_port *)port; | ||
| 459 | unsigned int lcr_h, old_cr; | 467 | unsigned int lcr_h, old_cr; |
| 460 | unsigned long flags; | 468 | unsigned long flags; |
| 461 | unsigned int baud, quot; | 469 | unsigned int baud, quot; |
| @@ -532,6 +540,17 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios, | |||
| 532 | old_cr = readw(port->membase + UART011_CR); | 540 | old_cr = readw(port->membase + UART011_CR); |
| 533 | writew(0, port->membase + UART011_CR); | 541 | writew(0, port->membase + UART011_CR); |
| 534 | 542 | ||
| 543 | if (termios->c_cflag & CRTSCTS) { | ||
| 544 | if (old_cr & UART011_CR_RTS) | ||
| 545 | old_cr |= UART011_CR_RTSEN; | ||
| 546 | |||
| 547 | old_cr |= UART011_CR_CTSEN; | ||
| 548 | uap->autorts = true; | ||
| 549 | } else { | ||
| 550 | old_cr &= ~(UART011_CR_CTSEN | UART011_CR_RTSEN); | ||
| 551 | uap->autorts = false; | ||
| 552 | } | ||
| 553 | |||
| 535 | /* Set baud rate */ | 554 | /* Set baud rate */ |
| 536 | writew(quot & 0x3f, port->membase + UART011_FBRD); | 555 | writew(quot & 0x3f, port->membase + UART011_FBRD); |
| 537 | writew(quot >> 6, port->membase + UART011_IBRD); | 556 | writew(quot >> 6, port->membase + UART011_IBRD); |
