RE: [RFC][PATCH] serial: imx: Fix RS485 behaviour on disabled RX_DURING_TX

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

 



> From: Christoph Niedermaier <cniedermaier@xxxxxxxxxxxxxxxxxx>
> Sent: Tuesday, February 20, 2024 10:56 AM
> To: linux-serial@xxxxxxxxxxxxxxx
> Cc: Christoph Niedermaier <cniedermaier@xxxxxxxxxxxxxxxxxx>; Greg Kroah-Hartman
> <gregkh@xxxxxxxxxxxxxxxxxxx>; Jiri Slaby <jirislaby@xxxxxxxxxx>; Shawn Guo
> <shawnguo@xxxxxxxxxx>; Marek Vasut <marex@xxxxxxx>; Fabio Estevam <festevam@xxxxxxx>;
> Sascha Hauer <s.hauer@xxxxxxxxxxxxxx>; Pengutronix Kernel Team <kernel@xxxxxxxxxxxxxx>;
> NXP Linux Team <linux-imx@xxxxxxx>; Sergey Organov <sorganov@xxxxxxxxx>; Uwe Kleine-König
> <u.kleine-koenig@xxxxxxxxxxxxxx>; Rob Herring <robh@xxxxxxxxxx>; Ilpo Järvinen
> <ilpo.jarvinen@xxxxxxxxxxxxxxx>; Tom Rix <trix@xxxxxxxxxx>; Thomas Gleixner
> <tglx@xxxxxxxxxxxxx>; Lukas Wunner <lukas@xxxxxxxxx>
> Subject: [RFC][PATCH] serial: imx: Fix RS485 behaviour on disabled RX_DURING_TX
> 
> I have made a patch that does not enable the loopback when
> the RX_DURING_TX flag is disabled. Would you be so kind to
> test my patch to see if it also solves your problem.
> 
> Regards
> Christoph

+CC Rickard X Andersson, because missed to add him.

> 
> 
> Commit 79d0224f6bf2 ("tty: serial: imx: Handle RS485 DE signal active high")
> activated the loopback mode for RS485 controlled by UART CTS_B when the
> function imx_uart_stop_rx() is called. But through that changes the RS485
> flag RX_DURING_TX isn’t able to turn off the receiver anymore. If the flag
> RX_DURING_TX is disabled everything that was sent will be received due to
> the active loopback. To turn off the receiver in this case the function
> imx_uart_stop_rx() is extended by a wrapper function
> imx_uart_stop_rx_with_loopback_rs485_ctrl() for the use of RS485 with
> disabled flag RX_DURING_TX, where the receiver is turn off. For all other
> cases there aren’t a functional change.
> 
> When the receiver is turned off the UART CTS_B signal is always high. To
> ensure that the RS485 bus won’t blocked by a disabled receiver caused by a
> high UART CTS_B signal the function imx_uart_shutdown() is extended. So in
> RS485 loopback mode the receiver is always on after shutdown the device.
> 
> Fixes: 79d0224f6bf2 ("tty: serial: imx: Handle RS485 DE signal active high")
> Signed-off-by: Christoph Niedermaier <cniedermaier@xxxxxxxxxxxxxxxxxx>
> ---
> Cc: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
> Cc: Jiri Slaby <jirislaby@xxxxxxxxxx>
> Cc: Shawn Guo <shawnguo@xxxxxxxxxx>
> Cc: Marek Vasut <marex@xxxxxxx>
> Cc: Fabio Estevam <festevam@xxxxxxx>
> Cc: Sascha Hauer <s.hauer@xxxxxxxxxxxxxx>
> Cc: Pengutronix Kernel Team <kernel@xxxxxxxxxxxxxx>
> Cc: NXP Linux Team <linux-imx@xxxxxxx>
> Cc: Sergey Organov <sorganov@xxxxxxxxx>
> Cc: "Uwe Kleine-König" <u.kleine-koenig@xxxxxxxxxxxxxx>
> Cc: Rob Herring <robh@xxxxxxxxxx>
> Cc: "Ilpo Järvinen" <ilpo.jarvinen@xxxxxxxxxxxxxxx>
> Cc: Tom Rix <trix@xxxxxxxxxx>
> Cc: Thomas Gleixner <tglx@xxxxxxxxxxxxx>
> Cc: Lukas Wunner <lukas@xxxxxxxxx>
> To: linux-serial@xxxxxxxxxxxxxxx
> ---
>  drivers/tty/serial/imx.c | 16 +++++++++++++---
>  1 file changed, 13 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
> index 4aa72d5aeafb..222e2c929bd7 100644
> --- a/drivers/tty/serial/imx.c
> +++ b/drivers/tty/serial/imx.c
> @@ -463,7 +463,8 @@ static void imx_uart_stop_tx(struct uart_port *port)
>  }
> 
>  /* called with port.lock taken and irqs off */
> -static void imx_uart_stop_rx(struct uart_port *port)
> +static void imx_uart_stop_rx_with_loopback_rs485_ctrl(struct uart_port *port,
> +						  bool loopback_rs485_enable)
>  {
>  	struct imx_port *sport = (struct imx_port *)port;
>  	u32 ucr1, ucr2, ucr4, uts;
> @@ -483,7 +484,7 @@ static void imx_uart_stop_rx(struct uart_port *port)
>  	imx_uart_writel(sport, ucr4, UCR4);
> 
>  	/* See SER_RS485_ENABLED/UTS_LOOP comment in imx_uart_probe() */
> -	if (port->rs485.flags & SER_RS485_ENABLED &&
> +	if (port->rs485.flags & SER_RS485_ENABLED && loopback_rs485_enable &&
>  	    port->rs485.flags & SER_RS485_RTS_ON_SEND &&
>  	    sport->have_rtscts && !sport->have_rtsgpio) {
>  		uts = imx_uart_readl(sport, imx_uart_uts_reg(sport));
> @@ -498,6 +499,12 @@ static void imx_uart_stop_rx(struct uart_port *port)
>  }
> 
>  /* called with port.lock taken and irqs off */
> +static void imx_uart_stop_rx(struct uart_port *port)
> +{
> +	imx_uart_stop_rx_with_loopback_rs485_ctrl(port, 1);
> +}
> +
> +/* called with port.lock taken and irqs off */
>  static void imx_uart_enable_ms(struct uart_port *port)
>  {
>  	struct imx_port *sport = (struct imx_port *)port;
> @@ -684,7 +691,7 @@ static void imx_uart_start_tx(struct uart_port *port)
> 
>  			if (!(port->rs485.flags & SER_RS485_RX_DURING_TX) &&
>  			    !port->rs485_rx_during_tx_gpio)
> -				imx_uart_stop_rx(port);
> +				imx_uart_stop_rx_with_loopback_rs485_ctrl(port, 0);
> 
>  			sport->tx_state = WAIT_AFTER_RTS;
> 
> @@ -1596,6 +1603,9 @@ static void imx_uart_shutdown(struct uart_port *port)
>  		uts = imx_uart_readl(sport, imx_uart_uts_reg(sport));
>  		uts |= UTS_LOOP;
>  		imx_uart_writel(sport, uts, imx_uart_uts_reg(sport));
> +		ucr2 = imx_uart_readl(sport, UCR2);
> +		ucr2 |= UCR2_RXEN;
> +		imx_uart_writel(sport, ucr2, UCR2);
>  		ucr1 |= UCR1_UARTEN;
>  	} else {
>  		ucr1 &= ~UCR1_UARTEN;
> --
> 2.11.0





[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