aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial/amba-pl011.c
diff options
context:
space:
mode:
authorRabin Vincent <rabin.vincent@stericsson.com>2010-02-12 00:43:11 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2010-02-18 12:29:42 -0500
commit3b43816f685fc6c2531f43514662f796f4601ffc (patch)
tree3e7e484a8ce9c3ba1c8cedd195d0a6cc2346ab65 /drivers/serial/amba-pl011.c
parent18fe1cad889fe6c1acbf4dfc576e82a13cf1a30c (diff)
ARM: 5933/1: amba-pl011: support hardware flow control
Enable/disable automatic hardware flow control as requested by the termios. The controller does not allow us to control the RTS line when auto-RTS is enabled, so we enable auto-RTS only if the kernel has not disabled RTS. Acked-by: Linus Walleij <linus.walleij@stericsson.com> Signed-off-by: Rabin Vincent <rabin.vincent@stericsson.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'drivers/serial/amba-pl011.c')
-rw-r--r--drivers/serial/amba-pl011.c19
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
456pl011_set_termios(struct uart_port *port, struct ktermios *termios, 463pl011_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);