The rs485.flags are lost in functions such as imx_uart_stop_tx(), causing the function of RS485 to be invalid when using the serial port as the RS485 port. Use a variable to store the state to avoid this issue. Signed-off-by: LiangCheng Wang <zaq14760@xxxxxxxxx> --- drivers/tty/serial/imx.c | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 67d4a72eda77..346bbd21536b 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -209,7 +209,7 @@ struct imx_port { const struct imx_uart_data *devdata; struct mctrl_gpios *gpios; - + int flags; /* counter to stop 0xff flood */ int idle_counter; @@ -434,7 +434,7 @@ static void imx_uart_stop_tx(struct uart_port *port) imx_uart_writel(sport, ucr4, UCR4); /* in rs485 mode disable transmitter */ - if (port->rs485.flags & SER_RS485_ENABLED) { + if (sport->flags & SER_RS485_ENABLED) { if (sport->tx_state == SEND) { sport->tx_state = WAIT_AFTER_SEND; @@ -454,7 +454,7 @@ static void imx_uart_stop_tx(struct uart_port *port) hrtimer_try_to_cancel(&sport->trigger_start_tx); ucr2 = imx_uart_readl(sport, UCR2); - if (port->rs485.flags & SER_RS485_RTS_AFTER_SEND) + if (sport->flags & SER_RS485_RTS_AFTER_SEND) imx_uart_rts_active(sport, &ucr2); else imx_uart_rts_inactive(sport, &ucr2); @@ -490,8 +490,8 @@ static void imx_uart_stop_rx_with_loopback_ctrl(struct uart_port *port, bool loo imx_uart_writel(sport, ucr4, UCR4); /* See SER_RS485_ENABLED/UTS_LOOP comment in imx_uart_probe() */ - if (port->rs485.flags & SER_RS485_ENABLED && - port->rs485.flags & SER_RS485_RTS_ON_SEND && + if (sport->flags & SER_RS485_ENABLED && + sport->flags & SER_RS485_RTS_ON_SEND && sport->have_rtscts && !sport->have_rtsgpio && loopback) { uts = imx_uart_readl(sport, imx_uart_uts_reg(sport)); uts |= UTS_LOOP; @@ -604,7 +604,7 @@ static void imx_uart_dma_tx_callback(void *data) if (!kfifo_is_empty(&tport->xmit_fifo) && !uart_tx_stopped(&sport->port)) imx_uart_dma_tx(sport); - else if (sport->port.rs485.flags & SER_RS485_ENABLED) { + else if (sport->flags & SER_RS485_ENABLED) { u32 ucr4 = imx_uart_readl(sport, UCR4); ucr4 |= UCR4_TCEN; imx_uart_writel(sport, ucr4, UCR4); @@ -681,10 +681,10 @@ static void imx_uart_start_tx(struct uart_port *port) * imx_uart_stop_tx(), but tx_state is still SEND. */ - if (port->rs485.flags & SER_RS485_ENABLED) { + if (sport->flags & SER_RS485_ENABLED) { if (sport->tx_state == OFF) { u32 ucr2 = imx_uart_readl(sport, UCR2); - if (port->rs485.flags & SER_RS485_RTS_ON_SEND) + if (sport->flags & SER_RS485_RTS_ON_SEND) imx_uart_rts_active(sport, &ucr2); else imx_uart_rts_inactive(sport, &ucr2); @@ -695,7 +695,7 @@ static void imx_uart_start_tx(struct uart_port *port) * with loopback enabled because that will make our * transmitted data being just looped to RX. */ - if (!(port->rs485.flags & SER_RS485_RX_DURING_TX) && + if (!(sport->flags & SER_RS485_RX_DURING_TX) && !port->rs485_rx_during_tx_gpio) imx_uart_stop_rx_with_loopback_ctrl(port, false); @@ -1078,7 +1078,7 @@ static void imx_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) struct imx_port *sport = to_imx_port(port); u32 ucr3, uts; - if (!(port->rs485.flags & SER_RS485_ENABLED)) { + if (!(sport->flags & SER_RS485_ENABLED)) { u32 ucr2; /* @@ -1604,8 +1604,8 @@ static void imx_uart_shutdown(struct uart_port *port) ucr1 &= ~(UCR1_TRDYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_RXDMAEN | UCR1_ATDMAEN | UCR1_SNDBRK); /* See SER_RS485_ENABLED/UTS_LOOP comment in imx_uart_probe() */ - if (port->rs485.flags & SER_RS485_ENABLED && - port->rs485.flags & SER_RS485_RTS_ON_SEND && + if (sport->flags & SER_RS485_ENABLED && + sport->flags & SER_RS485_RTS_ON_SEND && sport->have_rtscts && !sport->have_rtsgpio) { uts = imx_uart_readl(sport, imx_uart_uts_reg(sport)); uts |= UTS_LOOP; @@ -1643,7 +1643,7 @@ static void imx_uart_shutdown(struct uart_port *port) * those cases, we have to wait for the hrtimer to fire and * complete the transition to OFF. */ - loops = port->rs485.flags & SER_RS485_ENABLED ? + loops = sport->flags & SER_RS485_ENABLED ? port->rs485.delay_rts_after_send : 0; while (sport->tx_state != OFF && loops--) { uart_port_unlock_irqrestore(&sport->port, flags); @@ -1659,9 +1659,9 @@ static void imx_uart_shutdown(struct uart_port *port) * signal is inactive in order not to block other * devices. */ - if (port->rs485.flags & SER_RS485_ENABLED) { + if (sport->flags & SER_RS485_ENABLED) { ucr2 = imx_uart_readl(sport, UCR2); - if (port->rs485.flags & SER_RS485_RTS_AFTER_SEND) + if (sport->flags & SER_RS485_RTS_AFTER_SEND) imx_uart_rts_active(sport, &ucr2); else imx_uart_rts_inactive(sport, &ucr2); @@ -1749,13 +1749,13 @@ imx_uart_set_termios(struct uart_port *port, struct ktermios *termios, if (!sport->have_rtscts) termios->c_cflag &= ~CRTSCTS; - if (port->rs485.flags & SER_RS485_ENABLED) { + if (sport->flags & SER_RS485_ENABLED) { /* * RTS is mandatory for rs485 operation, so keep * it under manual control and keep transmitter * disabled. */ - if (port->rs485.flags & SER_RS485_RTS_AFTER_SEND) + if (sport->flags & SER_RS485_RTS_AFTER_SEND) imx_uart_rts_active(sport, &ucr2); else imx_uart_rts_inactive(sport, &ucr2); @@ -2394,6 +2394,7 @@ static int imx_uart_probe(struct platform_device *pdev) } ret = uart_get_rs485_mode(&sport->port); + sport->flags = sport->port.rs485.flags; if (ret) goto err_clk; -- 2.34.1