diff options
Diffstat (limited to 'drivers/tty/serial')
-rw-r--r-- | drivers/tty/serial/mxs-auart.c | 38 | ||||
-rw-r--r-- | drivers/tty/serial/pch_uart.c | 29 | ||||
-rw-r--r-- | drivers/tty/serial/serial_core.c | 4 |
3 files changed, 48 insertions, 23 deletions
diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c index 5b3d063..ab7d11e 100644 --- a/drivers/tty/serial/mxs-auart.c +++ b/drivers/tty/serial/mxs-auart.c @@ -374,11 +374,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); @@ -397,12 +404,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; } @@ -542,7 +543,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; @@ -563,18 +564,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); } diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c index 73038ba..78c26ca 100644 --- a/drivers/tty/serial/pch_uart.c +++ b/drivers/tty/serial/pch_uart.c @@ -935,22 +935,37 @@ static unsigned int dma_handle_tx(struct eg20t_port *priv) static void pch_uart_err_ir(struct eg20t_port *priv, unsigned int lsr) { u8 fcr = ioread8(priv->membase + UART_FCR); + struct uart_port *port = &priv->port; + struct tty_struct *tty = tty_port_tty_get(&port->state->port); + char *error_msg[5] = {}; + int i = 0; /* Reset FIFO */ fcr |= UART_FCR_CLEAR_RCVR; iowrite8(fcr, priv->membase + UART_FCR); if (lsr & PCH_UART_LSR_ERR) - dev_err(&priv->pdev->dev, "Error data in FIFO\n"); + error_msg[i++] = "Error data in FIFO\n"; - if (lsr & UART_LSR_FE) - dev_err(&priv->pdev->dev, "Framing Error\n"); + if (lsr & UART_LSR_FE) { + port->icount.frame++; + error_msg[i++] = " Framing Error\n"; + } - if (lsr & UART_LSR_PE) - dev_err(&priv->pdev->dev, "Parity Error\n"); + if (lsr & UART_LSR_PE) { + port->icount.parity++; + error_msg[i++] = " Parity Error\n"; + } - if (lsr & UART_LSR_OE) - dev_err(&priv->pdev->dev, "Overrun Error\n"); + if (lsr & UART_LSR_OE) { + port->icount.overrun++; + error_msg[i++] = " Overrun Error\n"; + } + + if (tty == NULL) { + for (i = 0; error_msg[i] != NULL; i++) + dev_err(&priv->pdev->dev, error_msg[i]); + } } static irqreturn_t pch_uart_interrupt(int irq, void *dev_id) diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index dca63e8..f512dc4 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -1920,6 +1920,8 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport) mutex_unlock(&port->mutex); return 0; } + put_device(tty_dev); + if (console_suspend_enabled || !uart_console(uport)) uport->suspended = 1; @@ -1985,9 +1987,11 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport) disable_irq_wake(uport->irq); uport->irq_wake = 0; } + put_device(tty_dev); mutex_unlock(&port->mutex); return 0; } + put_device(tty_dev); uport->suspended = 0; /* |