lkml.org 
[lkml]   [2020]   [Dec]   [28]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.19 047/346] serial: 8250_omap: Avoid FIFO corruption caused by MDR1 access
    Date
    From: Alexander Sverdlin <alexander.sverdlin@gmail.com>

    commit d96f04d347e4011977abdbb4da5d8f303ebd26f8 upstream.

    It has been observed that once per 300-1300 port openings the first
    transmitted byte is being corrupted on AM3352 ("v" written to FIFO appeared
    as "e" on the wire). It only happened if single byte has been transmitted
    right after port open, which means, DMA is not used for this transfer and
    the corruption never happened afterwards.

    Therefore I've carefully re-read the MDR1 errata (link below), which says
    "when accessing the MDR1 registers that causes a dummy under-run condition
    that will freeze the UART in IrDA transmission. In UART mode, this may
    corrupt the transferred data". Strictly speaking,
    omap_8250_mdr1_errataset() performs a read access and if the value is the
    same as should be written, exits without errata-recommended FIFO reset.

    A brief check of the serial_omap_mdr1_errataset() from the competing
    omap-serial driver showed it has no read access of MDR1. After removing the
    read access from omap_8250_mdr1_errataset() the data corruption never
    happened any more.

    Link: https://www.ti.com/lit/er/sprz360i/sprz360i.pdf
    Fixes: 61929cf0169d ("tty: serial: Add 8250-core based omap driver")
    Cc: stable@vger.kernel.org
    Signed-off-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
    Link: https://lore.kernel.org/r/20201210055257.1053028-1-alexander.sverdlin@gmail.com
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/tty/serial/8250/8250_omap.c | 5 -----
    1 file changed, 5 deletions(-)

    --- a/drivers/tty/serial/8250/8250_omap.c
    +++ b/drivers/tty/serial/8250/8250_omap.c
    @@ -163,11 +163,6 @@ static void omap_8250_mdr1_errataset(str
    struct omap8250_priv *priv)
    {
    u8 timeout = 255;
    - u8 old_mdr1;
    -
    - old_mdr1 = serial_in(up, UART_OMAP_MDR1);
    - if (old_mdr1 == priv->mdr1)
    - return;

    serial_out(up, UART_OMAP_MDR1, priv->mdr1);
    udelay(2);

    \
     
     \ /
      Last update: 2020-12-28 17:40    [W:2.081 / U:0.196 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site