|
@@ -678,11 +678,18 @@ static void mxs_auart_settermios(struct uart_port *u,
|
|
|
|
|
|
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);
|
|
@@ -702,12 +709,6 @@ static irqreturn_t mxs_auart_irq_handle(int irq, void *context)
|
|
|
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;
|
|
|
}
|
|
|
|
|
@@ -850,7 +851,7 @@ auart_console_write(struct console *co, const char *str, unsigned int count)
|
|
|
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;
|
|
@@ -871,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);
|
|
|
|
|
|
- /*
|
|
|
- * 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);
|
|
|
}
|