lkml.org 
[lkml]   [2019]   [Jul]   [29]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 01/24] tty: serial: fsl_lpuart: fix framing error handling when using DMA
    Date
    From: Stefan Agner <stefan.agner@toradex.com>

    When using DMA framing error get cleared properly. However, due
    to the additional read from the data register, an underflow in
    the receive FIFO buffer occurs (the FIFO pointer gets out of
    sync).

    Clear the FIFO in case an underflow has occurred. Also disable the
    receiver during this operation and when reading the data register to
    minimize potential interference.

    Signed-off-by: Stefan Agner <stefan.agner@toradex.com>
    Acked-by: Max Krummenacher <max.krummenacher@toradex.com>
    Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
    Cc: Stefan Agner <stefan@agner.ch>
    Cc: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com>
    Cc: Chris Healy <cphealy@gmail.com>
    Cc: Cory Tusar <cory.tusar@zii.aero>
    Cc: Lucas Stach <l.stach@pengutronix.de>
    Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    Cc: Jiri Slaby <jslaby@suse.com>
    Cc: linux-imx@nxp.com
    Cc: linux-serial@vger.kernel.org
    Cc: linux-kernel@vger.kernel.org
    ---
    drivers/tty/serial/fsl_lpuart.c | 26 ++++++++++++++++++++++++++
    1 file changed, 26 insertions(+)

    diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
    index 92dad2b4ec36..586b3513a6b0 100644
    --- a/drivers/tty/serial/fsl_lpuart.c
    +++ b/drivers/tty/serial/fsl_lpuart.c
    @@ -982,6 +982,13 @@ static void lpuart_copy_rx_to_tty(struct lpuart_port *sport)
    unsigned char sr = readb(sport->port.membase + UARTSR1);

    if (sr & (UARTSR1_PE | UARTSR1_FE)) {
    + unsigned char cr2;
    +
    + /* Disable receiver during this operation... */
    + cr2 = readb(sport->port.membase + UARTCR2);
    + cr2 &= ~UARTCR2_RE;
    + writeb(cr2, sport->port.membase + UARTCR2);
    +
    /* Read DR to clear the error flags */
    readb(sport->port.membase + UARTDR);

    @@ -989,6 +996,25 @@ static void lpuart_copy_rx_to_tty(struct lpuart_port *sport)
    sport->port.icount.parity++;
    else if (sr & UARTSR1_FE)
    sport->port.icount.frame++;
    + /*
    + * At this point parity/framing error is
    + * cleared However, since the DMA already read
    + * the data register and we had to read it
    + * again after reading the status register to
    + * properly clear the flags, the FIFO actually
    + * underflowed... This requires a clearing of
    + * the FIFO...
    + */
    + if (readb(sport->port.membase + UARTSFIFO) &
    + UARTSFIFO_RXUF) {
    + writeb(UARTSFIFO_RXUF,
    + sport->port.membase + UARTSFIFO);
    + writeb(UARTCFIFO_RXFLUSH,
    + sport->port.membase + UARTCFIFO);
    + }
    +
    + cr2 |= UARTCR2_RE;
    + writeb(cr2, sport->port.membase + UARTCR2);
    }
    }

    --
    2.21.0
    \
     
     \ /
      Last update: 2019-07-29 22:10    [W:4.378 / U:0.668 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site