diff options
author | Heikki Krogerus <heikki.krogerus@linux.intel.com> | 2013-04-10 16:58:25 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-04-11 13:18:39 -0700 |
commit | 75df022b5f8982a375adb04e9e4c0a34a9689ed9 (patch) | |
tree | e13d9f57e5207232907263a867400c033ed16d80 /drivers/tty | |
parent | 5ea5b24da80322b8136cb000a7340cdc29a3d6dc (diff) | |
download | lwn-75df022b5f8982a375adb04e9e4c0a34a9689ed9.tar.gz lwn-75df022b5f8982a375adb04e9e4c0a34a9689ed9.zip |
serial: 8250_dma: Fix RX handling
Overrun, parity and framing errors should be handled in
8250_core. This also adds check for the dma_status and exits
if the channel is not idle.
Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty')
-rw-r--r-- | drivers/tty/serial/8250/8250_dma.c | 23 |
1 files changed, 16 insertions, 7 deletions
diff --git a/drivers/tty/serial/8250/8250_dma.c b/drivers/tty/serial/8250/8250_dma.c index ce2518d5dfd1..66430614510a 100644 --- a/drivers/tty/serial/8250/8250_dma.c +++ b/drivers/tty/serial/8250/8250_dma.c @@ -101,20 +101,29 @@ int serial8250_rx_dma(struct uart_8250_port *p, unsigned int iir) struct dma_tx_state state; int dma_status; - /* - * If RCVR FIFO trigger level was not reached, complete the transfer and - * let 8250.c copy the remaining data. - */ - if ((iir & 0x3f) == UART_IIR_RX_TIMEOUT) { - dma_status = dmaengine_tx_status(dma->rxchan, dma->rx_cookie, - &state); + dma_status = dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state); + + switch (iir & 0x3f) { + case UART_IIR_RLSI: + /* 8250_core handles errors and break interrupts */ + 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_status == DMA_IN_PROGRESS) { dmaengine_pause(dma->rxchan); __dma_rx_complete(p); } return -ETIMEDOUT; + default: + break; } + if (dma_status) + return 0; + desc = dmaengine_prep_slave_single(dma->rxchan, dma->rx_addr, dma->rx_size, DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); |