diff options
| -rw-r--r-- | Documentation/devicetree/bindings/serial/of-serial.txt | 1 | ||||
| -rw-r--r-- | drivers/tty/serial/8250/8250_core.c | 6 | ||||
| -rw-r--r-- | drivers/tty/serial/of_serial.c | 4 | ||||
| -rw-r--r-- | drivers/tty/serial/serial_core.c | 12 |
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 | ||
| 41 | Example: | 42 | Example: |
| 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; |
