Commit 079a036f authored by Uwe Kleine-König's avatar Uwe Kleine-König Committed by Greg Kroah-Hartman

serial/mxs-auart: increase time to wait for transmitter to become idle

Without this patch the driver waits ~1 ms for the UART to become idle. At
115200n8 this time is (theoretically) enough to transfer 11.5 characters
(= 115200 bits/s / (10 Bits/char) * 1ms). As the mxs-auart has a fifo size
of 16 characters the clock is gated too early. The problem is worse for
lower baud rates.

This only happens to really shut down the transmitter in the middle of a
transfer if /dev/ttyAPPx isn't opened in userspace (e.g. by a getty) but
was at least once (because the bootloader doesn't disable the transmitter).

So increase the timeout to 20 ms which should be enough for 9600n8, too.
Moreover skip gating the clock if the timeout is elapsed.

Cc: stable@vger.kernel.org # v2.6.39+
Signed-off-by: default avatarUwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent d970d7fe
...@@ -851,7 +851,7 @@ auart_console_write(struct console *co, const char *str, unsigned int count) ...@@ -851,7 +851,7 @@ auart_console_write(struct console *co, const char *str, unsigned int count)
struct mxs_auart_port *s; struct mxs_auart_port *s;
struct uart_port *port; struct uart_port *port;
unsigned int old_ctrl0, old_ctrl2; unsigned int old_ctrl0, old_ctrl2;
unsigned int to = 1000; unsigned int to = 20000;
if (co->index >= MXS_AUART_PORTS || co->index < 0) if (co->index >= MXS_AUART_PORTS || co->index < 0)
return; return;
...@@ -872,18 +872,23 @@ auart_console_write(struct console *co, const char *str, unsigned int count) ...@@ -872,18 +872,23 @@ auart_console_write(struct console *co, const char *str, unsigned int count)
uart_console_write(port, str, count, mxs_auart_console_putchar); uart_console_write(port, str, count, mxs_auart_console_putchar);
/* /* Finally, wait for transmitter to become empty ... */
* Finally, wait for transmitter to become empty
* and restore the TCR
*/
while (readl(port->membase + AUART_STAT) & AUART_STAT_BUSY) { while (readl(port->membase + AUART_STAT) & AUART_STAT_BUSY) {
udelay(1);
if (!to--) if (!to--)
break; break;
udelay(1);
} }
/*
* ... and restore the TCR if we waited long enough for the transmitter
* to be idle. This might keep the transmitter enabled although it is
* unused, but that is better than to disable it while it is still
* transmitting.
*/
if (!(readl(port->membase + AUART_STAT) & AUART_STAT_BUSY)) {
writel(old_ctrl0, port->membase + AUART_CTRL0); writel(old_ctrl0, port->membase + AUART_CTRL0);
writel(old_ctrl2, port->membase + AUART_CTRL2); writel(old_ctrl2, port->membase + AUART_CTRL2);
}
clk_disable(s->clk); clk_disable(s->clk);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment