[PATCH] serial: xilinx_uartps: fix rs485 delay_rts_after_send

j.turek posted 1 patch 1 month, 2 weeks ago
drivers/tty/serial/xilinx_uartps.c | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
[PATCH] serial: xilinx_uartps: fix rs485 delay_rts_after_send
Posted by j.turek 1 month, 2 weeks ago
RTS line control with delay should be triggered when there is no more bytes
in kfifo and hardware buffer is empty. Without this patch RTS control is
scheduled right after feeding hardware buffer and this is too early.
RTS line may change state before hardware buffer is empty.
With this patch delayed RTS state change is triggered when function
cdns_uart_handle_tx is called from cdns_uart_isr on CDNS_UART_IXR_TXEMPTY
exactly when hardware completed transmission

Signed-off-by: Jakub Turek  <jakub.turek@elsta.tech>

Fixes: fccc9d9233f9 ("tty: serial: uartps: Add rs485 support to uartps driver")
---
 drivers/tty/serial/xilinx_uartps.c | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c
index 1e4d54fd5762..923a8b57ec82 100644
--- a/drivers/tty/serial/xilinx_uartps.c
+++ b/drivers/tty/serial/xilinx_uartps.c
@@ -432,6 +432,12 @@ static void cdns_uart_handle_tx(void *dev_id)
 	if (kfifo_is_empty(&tport->xmit_fifo) || uart_tx_stopped(port)) {
 		/* Disable the TX Empty interrupt */
 		writel(CDNS_UART_IXR_TXEMPTY, port->membase + CDNS_UART_IDR);
+		/* Set RTS line after delay */
+		if (cdns_uart->port->rs485.flags & SER_RS485_ENABLED) {
+			cdns_uart->tx_timer.function = &cdns_rs485_rx_callback;
+			rts_delay = ns_to_ktime(cdns_calc_after_tx_delay(cdns_uart));
+			hrtimer_start(&cdns_uart->tx_timer, rts_delay, HRTIMER_MODE_REL);
+		}
 		return;
 	}
 
@@ -448,13 +454,6 @@ static void cdns_uart_handle_tx(void *dev_id)
 
 	/* Enable the TX Empty interrupt */
 	writel(CDNS_UART_IXR_TXEMPTY, cdns_uart->port->membase + CDNS_UART_IER);
-
-	if (cdns_uart->port->rs485.flags & SER_RS485_ENABLED &&
-	    (kfifo_is_empty(&tport->xmit_fifo) || uart_tx_stopped(port))) {
-		hrtimer_update_function(&cdns_uart->tx_timer, cdns_rs485_rx_callback);
-		hrtimer_start(&cdns_uart->tx_timer,
-			      ns_to_ktime(cdns_calc_after_tx_delay(cdns_uart)), HRTIMER_MODE_REL);
-	}
 }
 
 /**
-- 
2.34.1
Re: [PATCH] serial: xilinx_uartps: fix rs485 delay_rts_after_send
Posted by kernel test robot 1 month, 2 weeks ago
Hi j.turek,

kernel test robot noticed the following build errors:

[auto build test ERROR on tty/tty-testing]
[also build test ERROR on tty/tty-next tty/tty-linus usb/usb-testing usb/usb-next usb/usb-linus linus/master v6.19-rc1 next-20251219]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/j-turek/serial-xilinx_uartps-fix-rs485-delay_rts_after_send/20251219-203016
base:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git tty-testing
patch link:    https://lore.kernel.org/r/20251219114826.135017-1-jakub.turek%40elsta.tech
patch subject: [PATCH] serial: xilinx_uartps: fix rs485 delay_rts_after_send
config: sh-allmodconfig (https://download.01.org/0day-ci/archive/20251220/202512202222.7nCGPOv4-lkp@intel.com/config)
compiler: sh4-linux-gcc (GCC) 15.1.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251220/202512202222.7nCGPOv4-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202512202222.7nCGPOv4-lkp@intel.com/

All errors (new ones prefixed by >>):

   drivers/tty/serial/xilinx_uartps.c: In function 'cdns_uart_handle_tx':
>> drivers/tty/serial/xilinx_uartps.c:438:25: error: 'rts_delay' undeclared (first use in this function)
     438 |                         rts_delay = ns_to_ktime(cdns_calc_after_tx_delay(cdns_uart));
         |                         ^~~~~~~~~
   drivers/tty/serial/xilinx_uartps.c:438:25: note: each undeclared identifier is reported only once for each function it appears in


vim +/rts_delay +438 drivers/tty/serial/xilinx_uartps.c

   418	
   419	/**
   420	 * cdns_uart_handle_tx - Handle the bytes to be transmitted.
   421	 * @dev_id: Id of the UART port
   422	 * Return: None
   423	 */
   424	static void cdns_uart_handle_tx(void *dev_id)
   425	{
   426		struct uart_port *port = (struct uart_port *)dev_id;
   427		struct cdns_uart *cdns_uart = port->private_data;
   428		struct tty_port *tport = &port->state->port;
   429		unsigned int numbytes;
   430		unsigned char ch;
   431	
   432		if (kfifo_is_empty(&tport->xmit_fifo) || uart_tx_stopped(port)) {
   433			/* Disable the TX Empty interrupt */
   434			writel(CDNS_UART_IXR_TXEMPTY, port->membase + CDNS_UART_IDR);
   435			/* Set RTS line after delay */
   436			if (cdns_uart->port->rs485.flags & SER_RS485_ENABLED) {
   437				cdns_uart->tx_timer.function = &cdns_rs485_rx_callback;
 > 438				rts_delay = ns_to_ktime(cdns_calc_after_tx_delay(cdns_uart));
   439				hrtimer_start(&cdns_uart->tx_timer, rts_delay, HRTIMER_MODE_REL);
   440			}
   441			return;
   442		}
   443	
   444		numbytes = port->fifosize;
   445		while (numbytes &&
   446		       !(readl(port->membase + CDNS_UART_SR) & CDNS_UART_SR_TXFULL) &&
   447		       uart_fifo_get(port, &ch)) {
   448			writel(ch, port->membase + CDNS_UART_FIFO);
   449			numbytes--;
   450		}
   451	
   452		if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
   453			uart_write_wakeup(port);
   454	
   455		/* Enable the TX Empty interrupt */
   456		writel(CDNS_UART_IXR_TXEMPTY, cdns_uart->port->membase + CDNS_UART_IER);
   457	}
   458	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Re: [PATCH] serial: xilinx_uartps: fix rs485 delay_rts_after_send
Posted by kernel test robot 1 month, 2 weeks ago
Hi j.turek,

kernel test robot noticed the following build errors:

[auto build test ERROR on tty/tty-testing]
[also build test ERROR on tty/tty-next tty/tty-linus usb/usb-testing usb/usb-next usb/usb-linus linus/master v6.19-rc1 next-20251219]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/j-turek/serial-xilinx_uartps-fix-rs485-delay_rts_after_send/20251219-203016
base:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git tty-testing
patch link:    https://lore.kernel.org/r/20251219114826.135017-1-jakub.turek%40elsta.tech
patch subject: [PATCH] serial: xilinx_uartps: fix rs485 delay_rts_after_send
config: hexagon-allmodconfig (https://download.01.org/0day-ci/archive/20251220/202512202351.ovK2vDUR-lkp@intel.com/config)
compiler: clang version 17.0.6 (https://github.com/llvm/llvm-project 6009708b4367171ccdbf4b5905cb6a803753fe18)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251220/202512202351.ovK2vDUR-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202512202351.ovK2vDUR-lkp@intel.com/

All errors (new ones prefixed by >>):

>> drivers/tty/serial/xilinx_uartps.c:438:4: error: use of undeclared identifier 'rts_delay'
     438 |                         rts_delay = ns_to_ktime(cdns_calc_after_tx_delay(cdns_uart));
         |                         ^
   drivers/tty/serial/xilinx_uartps.c:439:40: error: use of undeclared identifier 'rts_delay'; did you mean '__delay'?
     439 |                         hrtimer_start(&cdns_uart->tx_timer, rts_delay, HRTIMER_MODE_REL);
         |                                                             ^~~~~~~~~
         |                                                             __delay
   arch/hexagon/include/asm/delay.h:11:13: note: '__delay' declared here
      11 | extern void __delay(unsigned long cycles);
         |             ^
   2 errors generated.


vim +/rts_delay +438 drivers/tty/serial/xilinx_uartps.c

   418	
   419	/**
   420	 * cdns_uart_handle_tx - Handle the bytes to be transmitted.
   421	 * @dev_id: Id of the UART port
   422	 * Return: None
   423	 */
   424	static void cdns_uart_handle_tx(void *dev_id)
   425	{
   426		struct uart_port *port = (struct uart_port *)dev_id;
   427		struct cdns_uart *cdns_uart = port->private_data;
   428		struct tty_port *tport = &port->state->port;
   429		unsigned int numbytes;
   430		unsigned char ch;
   431	
   432		if (kfifo_is_empty(&tport->xmit_fifo) || uart_tx_stopped(port)) {
   433			/* Disable the TX Empty interrupt */
   434			writel(CDNS_UART_IXR_TXEMPTY, port->membase + CDNS_UART_IDR);
   435			/* Set RTS line after delay */
   436			if (cdns_uart->port->rs485.flags & SER_RS485_ENABLED) {
   437				cdns_uart->tx_timer.function = &cdns_rs485_rx_callback;
 > 438				rts_delay = ns_to_ktime(cdns_calc_after_tx_delay(cdns_uart));
   439				hrtimer_start(&cdns_uart->tx_timer, rts_delay, HRTIMER_MODE_REL);
   440			}
   441			return;
   442		}
   443	
   444		numbytes = port->fifosize;
   445		while (numbytes &&
   446		       !(readl(port->membase + CDNS_UART_SR) & CDNS_UART_SR_TXFULL) &&
   447		       uart_fifo_get(port, &ch)) {
   448			writel(ch, port->membase + CDNS_UART_FIFO);
   449			numbytes--;
   450		}
   451	
   452		if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
   453			uart_write_wakeup(port);
   454	
   455		/* Enable the TX Empty interrupt */
   456		writel(CDNS_UART_IXR_TXEMPTY, cdns_uart->port->membase + CDNS_UART_IER);
   457	}
   458	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki