[PATCH] serial: pxa: Disable TX interrupt if there is no more data to transmit

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



If a TX interrupt occurs and no new data gets loaded into the TX FIFO,
the UART will never fire another TX interrupt until the UART_IER_THRI
flag is toggled off and back on. If nothing ever calls stop_tx(), this
effectively results in transmissions getting hung up until another
unrelated UART IRQ occurs, such as an RX interrupt.

The driver used to do this correctly until the transition to
uart_port_tx_limited(). This didn't matter until the behavior of
__uart_port_tx changed in commit 7bfb915a597a ("serial: core: only stop
transmit when HW fifo is empty").

Fixes: d11cc8c3c4b6 ("tty: serial: use uart_port_tx_limited()")
Signed-off-by: Doug Brown <doug@xxxxxxxxxxxxx>
---

Note: I based this on v6.9 instead of tty-next since it's a fix; please
let me know if that was the wrong move and I would be happy to resubmit
it based on tty-next. The patch changes ever so slightly because of the
circ_buf -> kfifo transition. The only difference is it needs this
condition in the "if" statement instead:

kfifo_is_empty(&up->port.state->port.xmit_fifo)

This has been tested to work properly on tty-next as well.

 drivers/tty/serial/pxa.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/tty/serial/pxa.c b/drivers/tty/serial/pxa.c
index e395ff29c1a2..8abb85bee87c 100644
--- a/drivers/tty/serial/pxa.c
+++ b/drivers/tty/serial/pxa.c
@@ -176,6 +176,14 @@ static void transmit_chars(struct uart_pxa_port *up)
 {
 	u8 ch;
 
+	/* If there is nothing left to transmit, disable the TX interrupt.
+	 * Otherwise we can get stuck waiting for another IRQ that never happens.
+	 */
+	if (uart_circ_empty(&up->port.state->xmit)) {
+		serial_pxa_stop_tx(&up->port);
+		return;
+	}
+
 	uart_port_tx_limited(&up->port, ch, up->port.fifosize / 2,
 		true,
 		serial_out(up, UART_TX, ch),
-- 
2.34.1





[Index of Archives]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux PPP]     [Linux FS]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Linmodem]     [Device Mapper]     [Linux Kernel for ARM]

  Powered by Linux