From: Andy Shevchenko <andriy.shevche...@linux.intel.com>

If we get an exeption interrupt. i.e. UART_IIR_RLSI, stop any ongoing RX DMA
transfer otherwise it might generates more spurious interrupts and make port
unavailable anymore.

As has been seen on Intel Broxton system:
...
[  168.526281] serial8250: too much work for irq5
[  168.535908] serial8250: too much work for irq5
[  173.449464] serial8250_interrupt: 4439 callbacks suppressed
[  173.455694] serial8250: too much work for irq5
...

Signed-off-by: Andy Shevchenko <andriy.shevche...@linux.intel.com>
(cherry picked from commit e12d119865e55525ccf7c7d76b50081d6e4c83a6)
Signed-off-by: Yong, Jonathan <jonathan.y...@intel.com>
---
 drivers/tty/serial/8250/8250_dma.c | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/drivers/tty/serial/8250/8250_dma.c 
b/drivers/tty/serial/8250/8250_dma.c
index 78259d3..ec4d33f 100644
--- a/drivers/tty/serial/8250/8250_dma.c
+++ b/drivers/tty/serial/8250/8250_dma.c
@@ -110,6 +110,16 @@ err:
        return ret;
 }
 
+static void __dma_rx_stop(struct uart_8250_port *p, struct uart_8250_dma *dma)
+{
+       if (!dma->rx_running)
+               return;
+
+       dmaengine_pause(dma->rxchan);
+       __dma_rx_complete(p);
+       dmaengine_terminate_all(dma->rxchan);
+}
+
 int serial8250_rx_dma(struct uart_8250_port *p, unsigned int iir)
 {
        struct uart_8250_dma            *dma = p->dma;
@@ -118,17 +128,14 @@ int serial8250_rx_dma(struct uart_8250_port *p, unsigned 
int iir)
        switch (iir & 0x3f) {
        case UART_IIR_RLSI:
                /* 8250_core handles errors and break interrupts */
+               __dma_rx_stop(p, dma);
                return -EIO;
        case UART_IIR_RX_TIMEOUT:
                /*
                 * If RCVR FIFO trigger level was not reached, complete the
                 * transfer and let 8250_core copy the remaining data.
                 */
-               if (dma->rx_running) {
-                       dmaengine_pause(dma->rxchan);
-                       __dma_rx_complete(p);
-                       dmaengine_terminate_all(dma->rxchan);
-               }
+               __dma_rx_stop(p, dma);
                return -ETIMEDOUT;
        default:
                break;
-- 
2.7.3

-- 
_______________________________________________
linux-yocto mailing list
linux-yocto@yoctoproject.org
https://lists.yoctoproject.org/listinfo/linux-yocto

Reply via email to