aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/serial/8250/8250_dma.c
diff options
context:
space:
mode:
authorHeikki Krogerus <heikki.krogerus@linux.intel.com>2013-04-10 09:58:25 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-04-11 16:18:39 -0400
commit75df022b5f8982a375adb04e9e4c0a34a9689ed9 (patch)
treee13d9f57e5207232907263a867400c033ed16d80 /drivers/tty/serial/8250/8250_dma.c
parent5ea5b24da80322b8136cb000a7340cdc29a3d6dc (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.c23
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);