From c6f9f7f1cff11b3c240634c9c885be589e772baa Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 5 Aug 2013 09:12:21 +0800 Subject: [PATCH] 3.0-stable patches added patches: serial-mxs-auart-fix-race-condition-in-interrupt-handler.patch serial-mxs-auart-increase-time-to-wait-for-transmitter-to-become-idle.patch --- ...-race-condition-in-interrupt-handler.patch | 60 ++++++++++++++++ ...-wait-for-transmitter-to-become-idle.patch | 71 +++++++++++++++++++ queue-3.0/series | 2 + 3 files changed, 133 insertions(+) create mode 100644 queue-3.0/serial-mxs-auart-fix-race-condition-in-interrupt-handler.patch create mode 100644 queue-3.0/serial-mxs-auart-increase-time-to-wait-for-transmitter-to-become-idle.patch create mode 100644 queue-3.0/series diff --git a/queue-3.0/serial-mxs-auart-fix-race-condition-in-interrupt-handler.patch b/queue-3.0/serial-mxs-auart-fix-race-condition-in-interrupt-handler.patch new file mode 100644 index 00000000000..f6f6d50aed1 --- /dev/null +++ b/queue-3.0/serial-mxs-auart-fix-race-condition-in-interrupt-handler.patch @@ -0,0 +1,60 @@ +From d970d7fe65adff5efe75b4a73c4ffc9be57089f7 Mon Sep 17 00:00:00 2001 +From: Uwe Kleine-König +Date: Thu, 4 Jul 2013 11:28:51 +0200 +Subject: serial/mxs-auart: fix race condition in interrupt handler + +From: Uwe Kleine-König + +commit d970d7fe65adff5efe75b4a73c4ffc9be57089f7 upstream. + +The handler needs to ack the pending events before actually handling them. +Otherwise a new event might come in after it it considered non-pending or +handled and is acked then without being handled. So this event is only +noticed when the next interrupt happens. + +Without this patch an i.MX28 based machine running an rt-patched kernel +regularly hangs during boot. + +Signed-off-by: Uwe Kleine-König +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/tty/serial/mxs-auart.c | 17 +++++++++-------- + 1 file changed, 9 insertions(+), 8 deletions(-) + +--- a/drivers/tty/serial/mxs-auart.c ++++ b/drivers/tty/serial/mxs-auart.c +@@ -374,11 +374,18 @@ static void mxs_auart_settermios(struct + + static irqreturn_t mxs_auart_irq_handle(int irq, void *context) + { +- u32 istatus, istat; ++ u32 istat; + struct mxs_auart_port *s = context; + u32 stat = readl(s->port.membase + AUART_STAT); + +- istatus = istat = readl(s->port.membase + AUART_INTR); ++ istat = readl(s->port.membase + AUART_INTR); ++ ++ /* ack irq */ ++ writel(istat & (AUART_INTR_RTIS ++ | AUART_INTR_TXIS ++ | AUART_INTR_RXIS ++ | AUART_INTR_CTSMIS), ++ s->port.membase + AUART_INTR_CLR); + + if (istat & AUART_INTR_CTSMIS) { + uart_handle_cts_change(&s->port, stat & AUART_STAT_CTS); +@@ -397,12 +404,6 @@ static irqreturn_t mxs_auart_irq_handle( + istat &= ~AUART_INTR_TXIS; + } + +- writel(istatus & (AUART_INTR_RTIS +- | AUART_INTR_TXIS +- | AUART_INTR_RXIS +- | AUART_INTR_CTSMIS), +- s->port.membase + AUART_INTR_CLR); +- + return IRQ_HANDLED; + } + diff --git a/queue-3.0/serial-mxs-auart-increase-time-to-wait-for-transmitter-to-become-idle.patch b/queue-3.0/serial-mxs-auart-increase-time-to-wait-for-transmitter-to-become-idle.patch new file mode 100644 index 00000000000..67cd1995a23 --- /dev/null +++ b/queue-3.0/serial-mxs-auart-increase-time-to-wait-for-transmitter-to-become-idle.patch @@ -0,0 +1,71 @@ +From 079a036f4283e2b0e5c26080b8c5112bc0cc1831 Mon Sep 17 00:00:00 2001 +From: Uwe Kleine-König +Date: Fri, 28 Jun 2013 11:49:41 +0200 +Subject: serial/mxs-auart: increase time to wait for transmitter to become idle + +From: Uwe Kleine-König + +commit 079a036f4283e2b0e5c26080b8c5112bc0cc1831 upstream. + +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. + +Signed-off-by: Uwe Kleine-König +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/tty/serial/mxs-auart.c | 21 +++++++++++++-------- + 1 file changed, 13 insertions(+), 8 deletions(-) + +--- a/drivers/tty/serial/mxs-auart.c ++++ b/drivers/tty/serial/mxs-auart.c +@@ -543,7 +543,7 @@ auart_console_write(struct console *co, + struct mxs_auart_port *s; + struct uart_port *port; + unsigned int old_ctrl0, old_ctrl2; +- unsigned int to = 1000; ++ unsigned int to = 20000; + + if (co->index > MXS_AUART_PORTS || co->index < 0) + return; +@@ -564,18 +564,23 @@ auart_console_write(struct console *co, + + uart_console_write(port, str, count, mxs_auart_console_putchar); + +- /* +- * Finally, wait for transmitter to become empty +- * and restore the TCR +- */ ++ /* Finally, wait for transmitter to become empty ... */ + while (readl(port->membase + AUART_STAT) & AUART_STAT_BUSY) { ++ udelay(1); + if (!to--) + break; +- udelay(1); + } + +- writel(old_ctrl0, port->membase + AUART_CTRL0); +- writel(old_ctrl2, port->membase + AUART_CTRL2); ++ /* ++ * ... 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_ctrl2, port->membase + AUART_CTRL2); ++ } + + clk_disable(s->clk); + } diff --git a/queue-3.0/series b/queue-3.0/series new file mode 100644 index 00000000000..a89f82e6f76 --- /dev/null +++ b/queue-3.0/series @@ -0,0 +1,2 @@ +serial-mxs-auart-fix-race-condition-in-interrupt-handler.patch +serial-mxs-auart-increase-time-to-wait-for-transmitter-to-become-idle.patch -- 2.47.3