OpenNuvoton / NUC970_Linux_Kernel

Linux Kernel Source Code for NUC970 Series Microprocessor
Other
68 stars 69 forks source link

RS485 direction(RTS) bug #33

Closed qianfan-Zhao closed 5 years ago

qianfan-Zhao commented 5 years ago

Current the kernel code has a bug when config serial port as RS485 mode.

Although we already clear LEV_RTS(0X200) bit based on SER_RS485_RTS_ON_SEND flag, but after that, when we try open serial port and write sometings, LEV_RTS are setted again.

if(rs485conf->flags & SER_RS485_RTS_ON_SEND)
{
        serial_out(p, UART_REG_MCR, (serial_in(p, UART_REG_MCR) & ~0x200) );
}

I had traced the kernel and found we set this bit in nuc970serial_set_mctrl.

if (mctrl & TIOCM_RTS)
    {
        // set RTS high level trigger
        mcr = serial_in(up, UART_REG_MCR);
        mcr |= 0x200;
        mcr &= ~(0x2);
    }

    if (up->mcr & UART_MCR_AFE)
    {
        // set RTS high level trigger
        mcr = serial_in(up, UART_REG_MCR);
        mcr |= 0x200;
        mcr &= ~(0x2);

This function doesn't check if we are in RS485 mode, may set LEV_RTS again, even if we clear that flag in rs485_config.

Next is a patch can solve this problem:

diff --git a/drivers/tty/serial/nuc970_serial-dt.c b/drivers/tty/serial/nuc970_serial-
dt.c
index 2d69b418133..ed3782bd20e 100644
--- a/drivers/tty/serial/nuc970_serial-dt.c
+++ b/drivers/tty/serial/nuc970_serial-dt.c
@@ -370,6 +370,12 @@ static void nuc970serial_set_mctrl(struct uart_port *port, unsign
ed int mctrl)
        unsigned int mcr = 0;
        unsigned int ier = 0;

+       /* Don't change RTS's configuration due to RS485 use this pin
+        * as direction pin.
+        */
+       if (up->rs485.flags & SER_RS485_ENABLED)
+               return;
+
        if (mctrl & TIOCM_RTS)
        {
                // set RTS high level trigger
yachen commented 5 years ago

Hi @qianfan-Zhao ,

Would you like to send a pull request? Or you prefer I make the change directly?

Sincerely,

Yi-An Chen

qianfan-Zhao commented 5 years ago

I found there has 2 file, nuc970_serial.c and nuc970_serial-dt.c. I only change nuc970-serial-dt.c.

Please check this issue and change it directly.

yachen commented 5 years ago

Fixed. Thanks.