Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 00592021 authored by Huang Shijie's avatar Huang Shijie Committed by Greg Kroah-Hartman
Browse files

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: default avatarHuang Shijie <b32955@freescale.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 7d9739cd
Loading
Loading
Loading
Loading
+9 −5
Original line number Diff line number Diff line
@@ -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);