From: LiangCheng Wang <zaq14760@gmail.com>
To: shawnguo@kernel.org
Cc: s.hauer@pengutronix.de, gregkh@linuxfoundation.org,
jirislaby@kernel.org, kernel@pengutronix.de, festevam@gmail.com,
u.kleine-koenig@pengutronix.de, cniedermaier@dh-electronics.com,
l.sanfilippo@kunbus.com, linux@rasmusvillemoes.dk,
stefan.eichenberger@toradex.com, tglx@linutronix.de,
rickaran@axis.com, zaq14760@gmail.com,
linux-kernel@vger.kernel.org, linux-serial@vger.kernel.org,
imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org
Subject: [PATCH 1/1] drivers: tty: imx: fix flags of rs485 not work properly
Date: Fri, 6 Sep 2024 10:19:05 +0800 [thread overview]
Message-ID: <20240906021905.197891-1-zaq14760@gmail.com> (raw)
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@gmail.com>
---
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
next reply other threads:[~2024-09-06 2:19 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-09-06 2:19 LiangCheng Wang [this message]
2024-09-06 6:03 ` [PATCH 1/1] drivers: tty: imx: fix flags of rs485 not work properly Jiri Slaby
2024-09-20 15:58 ` Ilpo Järvinen
-- strict thread matches above, loose matches on Subject: below --
2024-09-05 6:20 LiangCheng Wang
2024-09-05 11:03 ` Fabio Estevam
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240906021905.197891-1-zaq14760@gmail.com \
--to=zaq14760@gmail.com \
--cc=cniedermaier@dh-electronics.com \
--cc=festevam@gmail.com \
--cc=gregkh@linuxfoundation.org \
--cc=imx@lists.linux.dev \
--cc=jirislaby@kernel.org \
--cc=kernel@pengutronix.de \
--cc=l.sanfilippo@kunbus.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-serial@vger.kernel.org \
--cc=linux@rasmusvillemoes.dk \
--cc=rickaran@axis.com \
--cc=s.hauer@pengutronix.de \
--cc=shawnguo@kernel.org \
--cc=stefan.eichenberger@toradex.com \
--cc=tglx@linutronix.de \
--cc=u.kleine-koenig@pengutronix.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox