diff options
author | Heikki Krogerus <heikki.krogerus@linux.intel.com> | 2013-04-10 09:58:25 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-04-11 16:18:39 -0400 |
commit | 75df022b5f8982a375adb04e9e4c0a34a9689ed9 (patch) | |
tree | e13d9f57e5207232907263a867400c033ed16d80 /drivers/tty/serial/8250/8250_dma.c | |
parent | 5ea5b24da80322b8136cb000a7340cdc29a3d6dc (diff) |
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/serial/8250/8250_dma.c')
-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) | |||
101 | struct dma_tx_state state; | 101 | struct dma_tx_state state; |
102 | int dma_status; | 102 | int dma_status; |
103 | 103 | ||
104 | /* | 104 | dma_status = dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state); |
105 | * If RCVR FIFO trigger level was not reached, complete the transfer and | 105 | |
106 | * let 8250.c copy the remaining data. | 106 | switch (iir & 0x3f) { |
107 | */ | 107 | case UART_IIR_RLSI: |
108 | if ((iir & 0x3f) == UART_IIR_RX_TIMEOUT) { | 108 | /* 8250_core handles errors and break interrupts */ |
109 | dma_status = dmaengine_tx_status(dma->rxchan, dma->rx_cookie, | 109 | return -EIO; |
110 | &state); | 110 | case UART_IIR_RX_TIMEOUT: |
111 | /* | ||
112 | * If RCVR FIFO trigger level was not reached, complete the | ||
113 | * transfer and let 8250_core copy the remaining data. | ||
114 | */ | ||
111 | if (dma_status == DMA_IN_PROGRESS) { | 115 | if (dma_status == DMA_IN_PROGRESS) { |
112 | dmaengine_pause(dma->rxchan); | 116 | dmaengine_pause(dma->rxchan); |
113 | __dma_rx_complete(p); | 117 | __dma_rx_complete(p); |
114 | } | 118 | } |
115 | return -ETIMEDOUT; | 119 | return -ETIMEDOUT; |
120 | default: | ||
121 | break; | ||
116 | } | 122 | } |
117 | 123 | ||
124 | if (dma_status) | ||
125 | return 0; | ||
126 | |||
118 | desc = dmaengine_prep_slave_single(dma->rxchan, dma->rx_addr, | 127 | desc = dmaengine_prep_slave_single(dma->rxchan, dma->rx_addr, |
119 | dma->rx_size, DMA_DEV_TO_MEM, | 128 | dma->rx_size, DMA_DEV_TO_MEM, |
120 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | 129 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); |