serial: mxs-auart: fix the wrong RTS hardware flow control
Without checking if the auart supports the hardware flow control or not, the old mxs_auart_set_mctrl() asserted the RTS pin blindly. This will causes the auart receives wrong data in the following case: The far-end has already started the write operation, and wait for the auart asserts the RTS pin. Then the auart starts the read operation, but mxs_auart_set_mctrl() may be called before we set the RTSCTS in the mxs_auart_settermios(). So the RTS pin is asserted in a wrong situation, and we get the wrong data in the end. This bug has been catched when I connect the mx23(DTE) to the mx53(DCE). This patch also replaces the AUART_CTRL2_RTS with AUART_CTRL2_RTSEN. We should use the real the hardware flow control, not the software-controled hardware flow control. Signed-off-by: Huang Shijie <b32955@freescale.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
7d9739cd6b
commit
0059202101
1 changed files with 9 additions and 5 deletions
|
@ -73,6 +73,7 @@
|
|||
#define AUART_CTRL0_CLKGATE (1 << 30)
|
||||
|
||||
#define AUART_CTRL2_CTSEN (1 << 15)
|
||||
#define AUART_CTRL2_RTSEN (1 << 14)
|
||||
#define AUART_CTRL2_RTS (1 << 11)
|
||||
#define AUART_CTRL2_RXE (1 << 9)
|
||||
#define AUART_CTRL2_TXE (1 << 8)
|
||||
|
@ -259,9 +260,12 @@ static void mxs_auart_set_mctrl(struct uart_port *u, unsigned mctrl)
|
|||
|
||||
u32 ctrl = readl(u->membase + AUART_CTRL2);
|
||||
|
||||
ctrl &= ~AUART_CTRL2_RTS;
|
||||
if (mctrl & TIOCM_RTS)
|
||||
ctrl |= AUART_CTRL2_RTS;
|
||||
ctrl &= ~AUART_CTRL2_RTSEN;
|
||||
if (mctrl & TIOCM_RTS) {
|
||||
if (u->state->port.flags & ASYNC_CTS_FLOW)
|
||||
ctrl |= AUART_CTRL2_RTSEN;
|
||||
}
|
||||
|
||||
s->ctrl = mctrl;
|
||||
writel(ctrl, u->membase + AUART_CTRL2);
|
||||
}
|
||||
|
@ -359,9 +363,9 @@ static void mxs_auart_settermios(struct uart_port *u,
|
|||
|
||||
/* figure out the hardware flow control settings */
|
||||
if (cflag & CRTSCTS)
|
||||
ctrl2 |= AUART_CTRL2_CTSEN;
|
||||
ctrl2 |= AUART_CTRL2_CTSEN | AUART_CTRL2_RTSEN;
|
||||
else
|
||||
ctrl2 &= ~AUART_CTRL2_CTSEN;
|
||||
ctrl2 &= ~(AUART_CTRL2_CTSEN | AUART_CTRL2_RTSEN);
|
||||
|
||||
/* set baud rate */
|
||||
baud = uart_get_baud_rate(u, termios, old, 0, u->uartclk);
|
||||
|
|
Loading…
Reference in a new issue