Skip to content

Commit

Permalink
serial: mxs-auart: fix the wrong RTS hardware flow control
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Huang Shijie authored and Greg Kroah-Hartman committed Aug 16, 2012
1 parent 7d9739c commit 0059202
Showing 1 changed file with 9 additions and 5 deletions.
14 changes: 9 additions & 5 deletions drivers/tty/serial/mxs-auart.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 0059202

Please sign in to comment.