aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/serial/of-serial.txt1
-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
4 files changed, 18 insertions, 5 deletions
diff --git a/Documentation/devicetree/bindings/serial/of-serial.txt b/Documentation/devicetree/bindings/serial/of-serial.txt
index 1928a3e83cd0..77054772a8f4 100644
--- a/Documentation/devicetree/bindings/serial/of-serial.txt
+++ b/Documentation/devicetree/bindings/serial/of-serial.txt
@@ -37,6 +37,7 @@ Optional properties:
37- auto-flow-control: one way to enable automatic flow control support. The 37- auto-flow-control: one way to enable automatic flow control support. The
38 driver is allowed to detect support for the capability even without this 38 driver is allowed to detect support for the capability even without this
39 property. 39 property.
40- has-hw-flow-control: the hardware has flow control capability.
40 41
41Example: 42Example:
42 43
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;