hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/tty/serial/8250/8250_dma.c
....@@ -15,6 +15,7 @@
1515 #define MAX_TX_BYTES 64
1616 #define MAX_FIFO_SIZE 64
1717 #define UART_RFL_16550A 0x21
18
+#define DW_UART_DMASA 0x2a
1819 #endif
1920
2021 static void __dma_tx_complete(void *param)
....@@ -85,19 +86,38 @@
8586 struct uart_8250_dma *dma = p->dma;
8687 struct tty_port *tty_port = &p->port.state->port;
8788 struct dma_tx_state state;
89
+ enum dma_status dma_status;
8890 int count;
8991
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;
92100
93101 count = dma->rx_size - state.residue;
94102
95103 tty_insert_flip_string(tty_port, dma->rx_buf, count);
96104 p->port.icount.rx += count;
105
+ dma->rx_running = 0;
97106
98107 tty_flip_buffer_push(tty_port);
99108 }
100109
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
+}
101121 #endif
102122
103123 int serial8250_tx_dma(struct uart_8250_port *p)
....@@ -150,6 +170,10 @@
150170 dma_sync_single_for_device(dma->txchan->device->dev, dma->tx_addr,
151171 UART_XMIT_SIZE, DMA_TO_DEVICE);
152172
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
153177 dma_async_issue_pending(dma->txchan);
154178 if (dma->tx_err) {
155179 dma->tx_err = 0;
....@@ -234,7 +258,7 @@
234258 return -EBUSY;
235259
236260 dma->rx_running = 1;
237
- desc->callback = __dma_rx_complete;
261
+ desc->callback = dma_rx_complete;
238262 desc->callback_param = p;
239263
240264 dma->rx_cookie = dmaengine_submit(desc);