serial: sh-sci: Don't call sci_rx_interrupt() on error when using DMA
authorGeert Uytterhoeven <geert+renesas@glider.be>
Fri, 21 Aug 2015 18:02:55 +0000 (20:02 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 4 Oct 2015 16:33:48 +0000 (17:33 +0100)
The error handler calls sci_rx_interrupt() to drain the receive FIFO if
an error condition happens.

However, if DMA is enabled on SCIFA or SCIFB, this will call
disable_irq_nosync() twice. Due to this imbalance, the receive interrupt
will never be re-enabled, and reception stops forever.

To fix this, restrict draining the FIFO to PIO mode, and just call
sci_receive_chars() directly.

Inspired by a patch from Yoshihiro Shimoda
<yoshihiro.shimoda.uh@renesas.com>.

Reported-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/tty/serial/sh-sci.c

index 70e16f4..82456fb 100644 (file)
@@ -993,6 +993,7 @@ static irqreturn_t sci_tx_interrupt(int irq, void *ptr)
 static irqreturn_t sci_er_interrupt(int irq, void *ptr)
 {
        struct uart_port *port = ptr;
+       struct sci_port *s = to_sci_port(port);
 
        /* Handle errors */
        if (port->type == PORT_SCI) {
@@ -1003,7 +1004,8 @@ static irqreturn_t sci_er_interrupt(int irq, void *ptr)
                }
        } else {
                sci_handle_fifo_overrun(port);
-               sci_rx_interrupt(irq, ptr);
+               if (!s->chan_rx)
+                       sci_receive_chars(ptr);
        }
 
        sci_clear_SCxSR(port, SCxSR_ERROR_CLEAR(port));