aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty
diff options
context:
space:
mode:
authorUwe Kleine-König <u.kleine-koenig@pengutronix.de>2013-06-28 05:49:41 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-07-26 19:34:00 -0400
commit079a036f4283e2b0e5c26080b8c5112bc0cc1831 (patch)
tree0e4e39b000d63c5a49d37b06f101d0f237fee73f /drivers/tty
parentd970d7fe65adff5efe75b4a73c4ffc9be57089f7 (diff)
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: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty')
-rw-r--r--drivers/tty/serial/mxs-auart.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c
index 3de0fb2712f5..f85b8e6d0346 100644
--- a/drivers/tty/serial/mxs-auart.c
+++ b/drivers/tty/serial/mxs-auart.c
@@ -851,7 +851,7 @@ auart_console_write(struct console *co, const char *str, unsigned int count)
851 struct mxs_auart_port *s; 851 struct mxs_auart_port *s;
852 struct uart_port *port; 852 struct uart_port *port;
853 unsigned int old_ctrl0, old_ctrl2; 853 unsigned int old_ctrl0, old_ctrl2;
854 unsigned int to = 1000; 854 unsigned int to = 20000;
855 855
856 if (co->index >= MXS_AUART_PORTS || co->index < 0) 856 if (co->index >= MXS_AUART_PORTS || co->index < 0)
857 return; 857 return;
@@ -872,18 +872,23 @@ auart_console_write(struct console *co, const char *str, unsigned int count)
872 872
873 uart_console_write(port, str, count, mxs_auart_console_putchar); 873 uart_console_write(port, str, count, mxs_auart_console_putchar);
874 874
875 /* 875 /* Finally, wait for transmitter to become empty ... */
876 * Finally, wait for transmitter to become empty
877 * and restore the TCR
878 */
879 while (readl(port->membase + AUART_STAT) & AUART_STAT_BUSY) { 876 while (readl(port->membase + AUART_STAT) & AUART_STAT_BUSY) {
877 udelay(1);
880 if (!to--) 878 if (!to--)
881 break; 879 break;
882 udelay(1);
883 } 880 }
884 881
885 writel(old_ctrl0, port->membase + AUART_CTRL0); 882 /*
886 writel(old_ctrl2, port->membase + AUART_CTRL2); 883 * ... and restore the TCR if we waited long enough for the transmitter
884 * to be idle. This might keep the transmitter enabled although it is
885 * unused, but that is better than to disable it while it is still
886 * transmitting.
887 */
888 if (!(readl(port->membase + AUART_STAT) & AUART_STAT_BUSY)) {
889 writel(old_ctrl0, port->membase + AUART_CTRL0);
890 writel(old_ctrl2, port->membase + AUART_CTRL2);
891 }
887 892
888 clk_disable(s->clk); 893 clk_disable(s->clk);
889} 894}