serial: amba-pl011: Fix DMA transmission in RS485 mode

When DMA is used in RS485 mode make sure that the UARTs tx section is
enabled before the DMA buffers are queued for transmission.

Cc: stable@vger.kernel.org
Fixes: 8d479237727c ("serial: amba-pl011: add RS485 support")
Signed-off-by: Lino Sanfilippo <l.sanfilippo@kunbus.com>
Link: https://lore.kernel.org/r/20240216224709.9928-2-l.sanfilippo@kunbus.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by Lino Sanfilippo and committed by Greg Kroah-Hartman 3b69e32e f418ae73

Changed files
+30 -30
drivers
tty
serial
+30 -30
drivers/tty/serial/amba-pl011.c
··· 1339 1339 } 1340 1340 } 1341 1341 1342 + static void pl011_rs485_tx_start(struct uart_amba_port *uap) 1343 + { 1344 + struct uart_port *port = &uap->port; 1345 + u32 cr; 1346 + 1347 + /* Enable transmitter */ 1348 + cr = pl011_read(uap, REG_CR); 1349 + cr |= UART011_CR_TXE; 1350 + 1351 + /* Disable receiver if half-duplex */ 1352 + if (!(port->rs485.flags & SER_RS485_RX_DURING_TX)) 1353 + cr &= ~UART011_CR_RXE; 1354 + 1355 + if (port->rs485.flags & SER_RS485_RTS_ON_SEND) 1356 + cr &= ~UART011_CR_RTS; 1357 + else 1358 + cr |= UART011_CR_RTS; 1359 + 1360 + pl011_write(cr, uap, REG_CR); 1361 + 1362 + if (port->rs485.delay_rts_before_send) 1363 + mdelay(port->rs485.delay_rts_before_send); 1364 + 1365 + uap->rs485_tx_started = true; 1366 + } 1367 + 1342 1368 static void pl011_start_tx(struct uart_port *port) 1343 1369 { 1344 1370 struct uart_amba_port *uap = 1345 1371 container_of(port, struct uart_amba_port, port); 1372 + 1373 + if ((uap->port.rs485.flags & SER_RS485_ENABLED) && 1374 + !uap->rs485_tx_started) 1375 + pl011_rs485_tx_start(uap); 1346 1376 1347 1377 if (!pl011_dma_tx_start(uap)) 1348 1378 pl011_start_tx_pio(uap); ··· 1454 1424 return true; 1455 1425 } 1456 1426 1457 - static void pl011_rs485_tx_start(struct uart_amba_port *uap) 1458 - { 1459 - struct uart_port *port = &uap->port; 1460 - u32 cr; 1461 - 1462 - /* Enable transmitter */ 1463 - cr = pl011_read(uap, REG_CR); 1464 - cr |= UART011_CR_TXE; 1465 - 1466 - /* Disable receiver if half-duplex */ 1467 - if (!(port->rs485.flags & SER_RS485_RX_DURING_TX)) 1468 - cr &= ~UART011_CR_RXE; 1469 - 1470 - if (port->rs485.flags & SER_RS485_RTS_ON_SEND) 1471 - cr &= ~UART011_CR_RTS; 1472 - else 1473 - cr |= UART011_CR_RTS; 1474 - 1475 - pl011_write(cr, uap, REG_CR); 1476 - 1477 - if (port->rs485.delay_rts_before_send) 1478 - mdelay(port->rs485.delay_rts_before_send); 1479 - 1480 - uap->rs485_tx_started = true; 1481 - } 1482 - 1483 1427 /* Returns true if tx interrupts have to be (kept) enabled */ 1484 1428 static bool pl011_tx_chars(struct uart_amba_port *uap, bool from_irq) 1485 1429 { 1486 1430 struct circ_buf *xmit = &uap->port.state->xmit; 1487 1431 int count = uap->fifosize >> 1; 1488 - 1489 - if ((uap->port.rs485.flags & SER_RS485_ENABLED) && 1490 - !uap->rs485_tx_started) 1491 - pl011_rs485_tx_start(uap); 1492 1432 1493 1433 if (uap->port.x_char) { 1494 1434 if (!pl011_tx_char(uap, uap->port.x_char, from_irq))