aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty
diff options
context:
space:
mode:
authorMurali Karicheri <m-karicheri2@ti.com>2014-05-01 15:04:53 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-05-28 16:04:46 -0400
commit06aa82e498c144c7784a6f3d3b55458b272d6146 (patch)
tree0055d789f294f29287ec4386ef3b81ef9eb4a181 /drivers/tty
parentab5e4e4108ca5d8326cb6b4b3a21b096a002f68f (diff)
serial: uart: add hw flow control support configuration
8250 uart driver currently supports only software assisted hw flow control. The software assisted hw flow control maintains a hw_stopped flag in the tty structure to stop and start transmission and use modem status interrupt for the event to drive the handshake signals. This is not needed if hw has flow control capabilities. This patch adds a DT attribute for enabling hw flow control for a uart port. Also skip stop and start if this flag is present in flag field of the port structure. Signed-off-by: Murali Karicheri <m-karicheri2@ti.com> CC: Rob Herring <robh+dt@kernel.org> CC: Pawel Moll <pawel.moll@arm.com> CC: Mark Rutland <mark.rutland@arm.com> CC: Ian Campbell <ijc+devicetree@hellion.org.uk> CC: Kumar Gala <galak@codeaurora.org> CC: Randy Dunlap <rdunlap@infradead.org> CC: Jiri Slaby <jslaby@suse.cz> CC: Santosh Shilimkar <santosh.shilimkar@ti.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty')
-rw-r--r--drivers/tty/serial/8250/8250_core.c6
-rw-r--r--drivers/tty/serial/of_serial.c4
-rw-r--r--drivers/tty/serial/serial_core.c12
3 files changed, 17 insertions, 5 deletions
diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c
index 111ee8acb07e..65556fc57d56 100644
--- a/drivers/tty/serial/8250/8250_core.c
+++ b/drivers/tty/serial/8250/8250_core.c
@@ -2333,9 +2333,11 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
2333 * the trigger, or the MCR RTS bit is cleared. In the case where 2333 * the trigger, or the MCR RTS bit is cleared. In the case where
2334 * the remote UART is not using CTS auto flow control, we must 2334 * the remote UART is not using CTS auto flow control, we must
2335 * have sufficient FIFO entries for the latency of the remote 2335 * have sufficient FIFO entries for the latency of the remote
2336 * UART to respond. IOW, at least 32 bytes of FIFO. 2336 * UART to respond. IOW, at least 32 bytes of FIFO. Also enable
2337 * AFE if hw flow control is supported
2337 */ 2338 */
2338 if (up->capabilities & UART_CAP_AFE && port->fifosize >= 32) { 2339 if ((up->capabilities & UART_CAP_AFE && (port->fifosize >= 32)) ||
2340 (port->flags & UPF_HARD_FLOW)) {
2339 up->mcr &= ~UART_MCR_AFE; 2341 up->mcr &= ~UART_MCR_AFE;
2340 if (termios->c_cflag & CRTSCTS) 2342 if (termios->c_cflag & CRTSCTS)
2341 up->mcr |= UART_MCR_AFE; 2343 up->mcr |= UART_MCR_AFE;
diff --git a/drivers/tty/serial/of_serial.c b/drivers/tty/serial/of_serial.c
index 99246606a256..77ec6a147522 100644
--- a/drivers/tty/serial/of_serial.c
+++ b/drivers/tty/serial/of_serial.c
@@ -182,6 +182,10 @@ static int of_platform_serial_probe(struct platform_device *ofdev)
182 "auto-flow-control")) 182 "auto-flow-control"))
183 port8250.capabilities |= UART_CAP_AFE; 183 port8250.capabilities |= UART_CAP_AFE;
184 184
185 if (of_property_read_bool(ofdev->dev.of_node,
186 "has-hw-flow-control"))
187 port8250.port.flags |= UPF_HARD_FLOW;
188
185 ret = serial8250_register_8250_port(&port8250); 189 ret = serial8250_register_8250_port(&port8250);
186 break; 190 break;
187 } 191 }
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index 9a01ee4dda6d..fbf6c5ad222f 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -174,8 +174,12 @@ static int uart_port_startup(struct tty_struct *tty, struct uart_state *state,
174 if (tty->termios.c_cflag & CBAUD) 174 if (tty->termios.c_cflag & CBAUD)
175 uart_set_mctrl(uport, TIOCM_RTS | TIOCM_DTR); 175 uart_set_mctrl(uport, TIOCM_RTS | TIOCM_DTR);
176 } 176 }
177 177 /*
178 if (tty_port_cts_enabled(port)) { 178 * if hw support flow control without software intervention,
179 * then skip the below check
180 */
181 if (tty_port_cts_enabled(port) &&
182 !(uport->flags & UPF_HARD_FLOW)) {
179 spin_lock_irq(&uport->lock); 183 spin_lock_irq(&uport->lock);
180 if (!(uport->ops->get_mctrl(uport) & TIOCM_CTS)) 184 if (!(uport->ops->get_mctrl(uport) & TIOCM_CTS))
181 tty->hw_stopped = 1; 185 tty->hw_stopped = 1;
@@ -2775,7 +2779,9 @@ void uart_handle_cts_change(struct uart_port *uport, unsigned int status)
2775 2779
2776 uport->icount.cts++; 2780 uport->icount.cts++;
2777 2781
2778 if (tty_port_cts_enabled(port)) { 2782 /* skip below code if the hw flow control is supported */
2783 if (tty_port_cts_enabled(port) &&
2784 !(uport->flags & UPF_HARD_FLOW)) {
2779 if (tty->hw_stopped) { 2785 if (tty->hw_stopped) {
2780 if (status) { 2786 if (status) {
2781 tty->hw_stopped = 0; 2787 tty->hw_stopped = 0;