summaryrefslogtreecommitdiff
path: root/drivers/tty
diff options
context:
space:
mode:
authorAlexander Sverdlin <alexander.sverdlin@gmail.com>2020-12-10 06:52:57 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2020-12-10 16:27:47 +0100
commitd96f04d347e4011977abdbb4da5d8f303ebd26f8 (patch)
treec94b2bbe0807d13ca6c0e3de0dc870bbc2a5d79d /drivers/tty
parent4661f46e50f2d658592f665be1f1f999ff647d3c (diff)
downloadlwn-d96f04d347e4011977abdbb4da5d8f303ebd26f8.tar.gz
lwn-d96f04d347e4011977abdbb4da5d8f303ebd26f8.zip
serial: 8250_omap: Avoid FIFO corruption caused by MDR1 access
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>
Diffstat (limited to 'drivers/tty')
-rw-r--r--drivers/tty/serial/8250/8250_omap.c5
1 files changed, 0 insertions, 5 deletions
diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c
index 0ab6517d389a..23e0decde33e 100644
--- a/drivers/tty/serial/8250/8250_omap.c
+++ b/drivers/tty/serial/8250/8250_omap.c
@@ -190,11 +190,6 @@ static void omap_8250_mdr1_errataset(struct uart_8250_port *up,
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);