diff options
author | Charanya Venkatraman <charanya@codeaurora.org> | 2016-06-07 15:58:41 +0530 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2016-06-25 10:23:54 -0700 |
commit | 002eb41f303e007011aecba25ea6de25a4ed475f (patch) | |
tree | ba3f7e89dc3570126fa55b458ecc8fe73a92654a /drivers/tty | |
parent | e4276ff8a08116f22589b4f52974cf82cd3207db (diff) | |
download | linux-002eb41f303e007011aecba25ea6de25a4ed475f.tar.gz linux-002eb41f303e007011aecba25ea6de25a4ed475f.tar.bz2 linux-002eb41f303e007011aecba25ea6de25a4ed475f.zip |
tty:serial:msm:Do not restore Rx interrupts in DMA
Avoid data corruption issues that result in CRC errors during file
transfers over serial ports at higher baud rates.
The current msm_serial driver masks the FIFO Rx interrupts in
msm_start_rx_dma() since Rx FIFO interrupts are not required in DMA
mode. However, msm_complete_rx_dma() re-enables the Rx FIFO interrupts
which could cause RXSTALE event to be processed when a TXLEV interrupt
occurs.
The following is the sequence of events that could occur resulting in
data corruption.
msm_start_rx_dma -> msm_complete_rx_dma -->
spin_unlock_irqrestore(&port->lock) -->
msm_uart_irq()(For TXLEV interrupt) --> msm_handle_rx_dm() (Read from
FIFO resulting in data corruption)
The patch fixes the issue by not restoring the RXLEV and RXSTALE
interrupts in msm_complete_rx_dma(). These interrupts are required only
in FIFO mode.
Signed-off-by: Charanya Venkatraman <charanya@codeaurora.org>
Acked-by: Andy Gross <andy.gross@linaro.org>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty')
-rw-r--r-- | drivers/tty/serial/msm_serial.c | 4 |
1 files changed, 0 insertions, 4 deletions
diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c index 88af5a3d21dd..d0384d4cccb1 100644 --- a/drivers/tty/serial/msm_serial.c +++ b/drivers/tty/serial/msm_serial.c @@ -557,10 +557,6 @@ static void msm_complete_rx_dma(void *args) val &= ~dma->enable_bit; msm_write(port, val, UARTDM_DMEN); - /* Restore interrupts */ - msm_port->imr |= UART_IMR_RXLEV | UART_IMR_RXSTALE; - msm_write(port, msm_port->imr, UART_IMR); - if (msm_read(port, UART_SR) & UART_SR_OVERRUN) { port->icount.overrun++; tty_insert_flip_char(tport, 0, TTY_OVERRUN); |