Skip to content

Commit 0e4deb5

Browse files
LinoSanfilippo333gregkh
authored andcommitted
serial: amba-pl011: do not time out prematurely when draining tx fifo
The current timeout for draining the tx fifo in RS485 mode is calculated by multiplying the time it takes to transmit one character (with the given baud rate) with the maximal number of characters in the tx queue. This timeout is too short for two reasons: First when calculating the time to transmit one character integer division is used which may round down the result in case of a remainder of the division. Fix this by rounding up the division result. Second the hardware may need additional time (e.g for first putting the characters from the fifo into the shift register) before the characters are actually put onto the wire. To be on the safe side double the current maximum number of iterations that are used to wait for the queue draining. Fixes: 8d47923 ("serial: amba-pl011: add RS485 support") Cc: [email protected] Signed-off-by: Lino Sanfilippo <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent ff9166c commit 0e4deb5

File tree

1 file changed

+7
-2
lines changed

1 file changed

+7
-2
lines changed

drivers/tty/serial/amba-pl011.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1255,13 +1255,18 @@ static inline bool pl011_dma_rx_running(struct uart_amba_port *uap)
12551255

12561256
static void pl011_rs485_tx_stop(struct uart_amba_port *uap)
12571257
{
1258+
/*
1259+
* To be on the safe side only time out after twice as many iterations
1260+
* as fifo size.
1261+
*/
1262+
const int MAX_TX_DRAIN_ITERS = uap->port.fifosize * 2;
12581263
struct uart_port *port = &uap->port;
12591264
int i = 0;
12601265
u32 cr;
12611266

12621267
/* Wait until hardware tx queue is empty */
12631268
while (!pl011_tx_empty(port)) {
1264-
if (i == port->fifosize) {
1269+
if (i > MAX_TX_DRAIN_ITERS) {
12651270
dev_warn(port->dev,
12661271
"timeout while draining hardware tx queue\n");
12671272
break;
@@ -2052,7 +2057,7 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios,
20522057
* with the given baud rate. We use this as the poll interval when we
20532058
* wait for the tx queue to empty.
20542059
*/
2055-
uap->rs485_tx_drain_interval = (bits * 1000 * 1000) / baud;
2060+
uap->rs485_tx_drain_interval = DIV_ROUND_UP(bits * 1000 * 1000, baud);
20562061

20572062
pl011_setup_status_masks(port, termios);
20582063

0 commit comments

Comments
 (0)