Skip to content

Commit 1af2156

Browse files
Villemoesgregkh
authored andcommitted
serial: imx: ensure RTS signal is not left active after shutdown
If a process is killed while writing to a /dev/ttymxc* device in RS485 mode, we observe that the RTS signal is left high, thus making it impossible for other devices to transmit anything. Moreover, the ->tx_state variable is left in state SEND, which means that when one next opens the device and configures baud rate etc., the initialization code in imx_uart_set_termios dutifully ensures the RTS pin is pulled down, but since ->tx_state is already SEND, the logic in imx_uart_start_tx() does not in fact pull the pin high before transmitting, so nothing actually gets on the wire on the other side of the transceiver. Only when that transmission is allowed to complete is the state machine then back in a consistent state. This is completely reproducible by doing something as simple as seq 10000 > /dev/ttymxc0 and hitting ctrl-C, and watching with a logic analyzer. Signed-off-by: Rasmus Villemoes <[email protected]> Cc: stable <[email protected]> Reviewed-by: Marek Vasut <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent acd09ac commit 1af2156

File tree

1 file changed

+51
-0
lines changed

1 file changed

+51
-0
lines changed

drivers/tty/serial/imx.c

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1552,6 +1552,7 @@ static void imx_uart_shutdown(struct uart_port *port)
15521552
struct imx_port *sport = (struct imx_port *)port;
15531553
unsigned long flags;
15541554
u32 ucr1, ucr2, ucr4, uts;
1555+
int loops;
15551556

15561557
if (sport->dma_is_enabled) {
15571558
dmaengine_terminate_sync(sport->dma_chan_tx);
@@ -1614,6 +1615,56 @@ static void imx_uart_shutdown(struct uart_port *port)
16141615
ucr4 &= ~UCR4_TCEN;
16151616
imx_uart_writel(sport, ucr4, UCR4);
16161617

1618+
/*
1619+
* We have to ensure the tx state machine ends up in OFF. This
1620+
* is especially important for rs485 where we must not leave
1621+
* the RTS signal high, blocking the bus indefinitely.
1622+
*
1623+
* All interrupts are now disabled, so imx_uart_stop_tx() will
1624+
* no longer be called from imx_uart_transmit_buffer(). It may
1625+
* still be called via the hrtimers, and if those are in play,
1626+
* we have to honour the delays.
1627+
*/
1628+
if (sport->tx_state == WAIT_AFTER_RTS || sport->tx_state == SEND)
1629+
imx_uart_stop_tx(port);
1630+
1631+
/*
1632+
* In many cases (rs232 mode, or if tx_state was
1633+
* WAIT_AFTER_RTS, or if tx_state was SEND and there is no
1634+
* delay_rts_after_send), this will have moved directly to
1635+
* OFF. In rs485 mode, tx_state might already have been
1636+
* WAIT_AFTER_SEND and the hrtimer thus already started, or
1637+
* the above imx_uart_stop_tx() call could have started it. In
1638+
* those cases, we have to wait for the hrtimer to fire and
1639+
* complete the transition to OFF.
1640+
*/
1641+
loops = port->rs485.flags & SER_RS485_ENABLED ?
1642+
port->rs485.delay_rts_after_send : 0;
1643+
while (sport->tx_state != OFF && loops--) {
1644+
uart_port_unlock_irqrestore(&sport->port, flags);
1645+
msleep(1);
1646+
uart_port_lock_irqsave(&sport->port, &flags);
1647+
}
1648+
1649+
if (sport->tx_state != OFF) {
1650+
dev_warn(sport->port.dev, "unexpected tx_state %d\n",
1651+
sport->tx_state);
1652+
/*
1653+
* This machine may be busted, but ensure the RTS
1654+
* signal is inactive in order not to block other
1655+
* devices.
1656+
*/
1657+
if (port->rs485.flags & SER_RS485_ENABLED) {
1658+
ucr2 = imx_uart_readl(sport, UCR2);
1659+
if (port->rs485.flags & SER_RS485_RTS_AFTER_SEND)
1660+
imx_uart_rts_active(sport, &ucr2);
1661+
else
1662+
imx_uart_rts_inactive(sport, &ucr2);
1663+
imx_uart_writel(sport, ucr2, UCR2);
1664+
}
1665+
sport->tx_state = OFF;
1666+
}
1667+
16171668
uart_port_unlock_irqrestore(&sport->port, flags);
16181669

16191670
clk_disable_unprepare(sport->clk_per);

0 commit comments

Comments
 (0)