diff options
Diffstat (limited to 'drivers/tty/serial/mxs-auart.c')
-rw-r--r-- | drivers/tty/serial/mxs-auart.c | 38 |
1 files changed, 22 insertions, 16 deletions
diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c index 4f5f161896a1..f85b8e6d0346 100644 --- a/drivers/tty/serial/mxs-auart.c +++ b/drivers/tty/serial/mxs-auart.c | |||
@@ -678,11 +678,18 @@ static void mxs_auart_settermios(struct uart_port *u, | |||
678 | 678 | ||
679 | static irqreturn_t mxs_auart_irq_handle(int irq, void *context) | 679 | static irqreturn_t mxs_auart_irq_handle(int irq, void *context) |
680 | { | 680 | { |
681 | u32 istatus, istat; | 681 | u32 istat; |
682 | struct mxs_auart_port *s = context; | 682 | struct mxs_auart_port *s = context; |
683 | u32 stat = readl(s->port.membase + AUART_STAT); | 683 | u32 stat = readl(s->port.membase + AUART_STAT); |
684 | 684 | ||
685 | istatus = istat = readl(s->port.membase + AUART_INTR); | 685 | istat = readl(s->port.membase + AUART_INTR); |
686 | |||
687 | /* ack irq */ | ||
688 | writel(istat & (AUART_INTR_RTIS | ||
689 | | AUART_INTR_TXIS | ||
690 | | AUART_INTR_RXIS | ||
691 | | AUART_INTR_CTSMIS), | ||
692 | s->port.membase + AUART_INTR_CLR); | ||
686 | 693 | ||
687 | if (istat & AUART_INTR_CTSMIS) { | 694 | if (istat & AUART_INTR_CTSMIS) { |
688 | uart_handle_cts_change(&s->port, stat & AUART_STAT_CTS); | 695 | 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) | |||
702 | istat &= ~AUART_INTR_TXIS; | 709 | istat &= ~AUART_INTR_TXIS; |
703 | } | 710 | } |
704 | 711 | ||
705 | writel(istatus & (AUART_INTR_RTIS | ||
706 | | AUART_INTR_TXIS | ||
707 | | AUART_INTR_RXIS | ||
708 | | AUART_INTR_CTSMIS), | ||
709 | s->port.membase + AUART_INTR_CLR); | ||
710 | |||
711 | return IRQ_HANDLED; | 712 | return IRQ_HANDLED; |
712 | } | 713 | } |
713 | 714 | ||
@@ -850,7 +851,7 @@ auart_console_write(struct console *co, const char *str, unsigned int count) | |||
850 | struct mxs_auart_port *s; | 851 | struct mxs_auart_port *s; |
851 | struct uart_port *port; | 852 | struct uart_port *port; |
852 | unsigned int old_ctrl0, old_ctrl2; | 853 | unsigned int old_ctrl0, old_ctrl2; |
853 | unsigned int to = 1000; | 854 | unsigned int to = 20000; |
854 | 855 | ||
855 | if (co->index >= MXS_AUART_PORTS || co->index < 0) | 856 | if (co->index >= MXS_AUART_PORTS || co->index < 0) |
856 | return; | 857 | return; |
@@ -871,18 +872,23 @@ auart_console_write(struct console *co, const char *str, unsigned int count) | |||
871 | 872 | ||
872 | uart_console_write(port, str, count, mxs_auart_console_putchar); | 873 | uart_console_write(port, str, count, mxs_auart_console_putchar); |
873 | 874 | ||
874 | /* | 875 | /* Finally, wait for transmitter to become empty ... */ |
875 | * Finally, wait for transmitter to become empty | ||
876 | * and restore the TCR | ||
877 | */ | ||
878 | while (readl(port->membase + AUART_STAT) & AUART_STAT_BUSY) { | 876 | while (readl(port->membase + AUART_STAT) & AUART_STAT_BUSY) { |
877 | udelay(1); | ||
879 | if (!to--) | 878 | if (!to--) |
880 | break; | 879 | break; |
881 | udelay(1); | ||
882 | } | 880 | } |
883 | 881 | ||
884 | writel(old_ctrl0, port->membase + AUART_CTRL0); | 882 | /* |
885 | 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 | } | ||
886 | 892 | ||
887 | clk_disable(s->clk); | 893 | clk_disable(s->clk); |
888 | } | 894 | } |