.. | .. |
---|
15 | 15 | #define MAX_TX_BYTES 64 |
---|
16 | 16 | #define MAX_FIFO_SIZE 64 |
---|
17 | 17 | #define UART_RFL_16550A 0x21 |
---|
| 18 | +#define DW_UART_DMASA 0x2a |
---|
18 | 19 | #endif |
---|
19 | 20 | |
---|
20 | 21 | static void __dma_tx_complete(void *param) |
---|
.. | .. |
---|
85 | 86 | struct uart_8250_dma *dma = p->dma; |
---|
86 | 87 | struct tty_port *tty_port = &p->port.state->port; |
---|
87 | 88 | struct dma_tx_state state; |
---|
| 89 | + enum dma_status dma_status; |
---|
88 | 90 | int count; |
---|
89 | 91 | |
---|
90 | | - dma->rx_running = 0; |
---|
91 | | - dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state); |
---|
| 92 | + /* |
---|
| 93 | + * New DMA Rx can be started during the completion handler before it |
---|
| 94 | + * could acquire port's lock and it might still be ongoing. Don't to |
---|
| 95 | + * anything in such case. |
---|
| 96 | + */ |
---|
| 97 | + dma_status = dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state); |
---|
| 98 | + if (dma_status == DMA_IN_PROGRESS) |
---|
| 99 | + return; |
---|
92 | 100 | |
---|
93 | 101 | count = dma->rx_size - state.residue; |
---|
94 | 102 | |
---|
95 | 103 | tty_insert_flip_string(tty_port, dma->rx_buf, count); |
---|
96 | 104 | p->port.icount.rx += count; |
---|
| 105 | + dma->rx_running = 0; |
---|
97 | 106 | |
---|
98 | 107 | tty_flip_buffer_push(tty_port); |
---|
99 | 108 | } |
---|
100 | 109 | |
---|
| 110 | +static void dma_rx_complete(void *param) |
---|
| 111 | +{ |
---|
| 112 | + struct uart_8250_port *p = param; |
---|
| 113 | + struct uart_8250_dma *dma = p->dma; |
---|
| 114 | + unsigned long flags; |
---|
| 115 | + |
---|
| 116 | + spin_lock_irqsave(&p->port.lock, flags); |
---|
| 117 | + if (dma->rx_running) |
---|
| 118 | + __dma_rx_complete(p); |
---|
| 119 | + spin_unlock_irqrestore(&p->port.lock, flags); |
---|
| 120 | +} |
---|
101 | 121 | #endif |
---|
102 | 122 | |
---|
103 | 123 | int serial8250_tx_dma(struct uart_8250_port *p) |
---|
.. | .. |
---|
150 | 170 | dma_sync_single_for_device(dma->txchan->device->dev, dma->tx_addr, |
---|
151 | 171 | UART_XMIT_SIZE, DMA_TO_DEVICE); |
---|
152 | 172 | |
---|
| 173 | +#if defined(CONFIG_ARCH_ROCKCHIP) && defined(CONFIG_NO_GKI) |
---|
| 174 | + /* Clear uart dma request before start dma */ |
---|
| 175 | + serial_port_out(&p->port, DW_UART_DMASA, 0x1); |
---|
| 176 | +#endif |
---|
153 | 177 | dma_async_issue_pending(dma->txchan); |
---|
154 | 178 | if (dma->tx_err) { |
---|
155 | 179 | dma->tx_err = 0; |
---|
.. | .. |
---|
234 | 258 | return -EBUSY; |
---|
235 | 259 | |
---|
236 | 260 | dma->rx_running = 1; |
---|
237 | | - desc->callback = __dma_rx_complete; |
---|
| 261 | + desc->callback = dma_rx_complete; |
---|
238 | 262 | desc->callback_param = p; |
---|
239 | 263 | |
---|
240 | 264 | dma->rx_cookie = dmaengine_submit(desc); |
---|