From 1543e317f1da31b75942316931e8f491a8920811 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Thu, 04 Jan 2024 10:08:02 +0000
Subject: [PATCH] disable FB
---
kernel/drivers/tty/serial/8250/8250_dma.c | 86 ++++++++++++++++++++++++++----------------
1 files changed, 53 insertions(+), 33 deletions(-)
diff --git a/kernel/drivers/tty/serial/8250/8250_dma.c b/kernel/drivers/tty/serial/8250/8250_dma.c
index 141a5b0..8cde714 100644
--- a/kernel/drivers/tty/serial/8250/8250_dma.c
+++ b/kernel/drivers/tty/serial/8250/8250_dma.c
@@ -11,10 +11,11 @@
#include "8250.h"
-#ifdef CONFIG_ARCH_ROCKCHIP
+#if defined(CONFIG_ARCH_ROCKCHIP) && defined(CONFIG_NO_GKI)
#define MAX_TX_BYTES 64
#define MAX_FIFO_SIZE 64
#define UART_RFL_16550A 0x21
+#define DW_UART_DMASA 0x2a
#endif
static void __dma_tx_complete(void *param)
@@ -40,18 +41,13 @@
uart_write_wakeup(&p->port);
ret = serial8250_tx_dma(p);
- if (ret) {
- p->ier |= UART_IER_THRI;
-#ifdef CONFIG_ARCH_ROCKCHIP
- p->ier |= UART_IER_PTIME;
-#endif
- serial_port_out(&p->port, UART_IER, p->ier);
- }
+ if (ret)
+ serial8250_set_THRI(p);
spin_unlock_irqrestore(&p->port.lock, flags);
}
-#ifdef CONFIG_ARCH_ROCKCHIP
+#if defined(CONFIG_ARCH_ROCKCHIP) && defined(CONFIG_NO_GKI)
static void __dma_rx_complete(void *param)
{
@@ -90,19 +86,38 @@
struct uart_8250_dma *dma = p->dma;
struct tty_port *tty_port = &p->port.state->port;
struct dma_tx_state state;
+ enum dma_status dma_status;
int count;
- dma->rx_running = 0;
- dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state);
+ /*
+ * New DMA Rx can be started during the completion handler before it
+ * could acquire port's lock and it might still be ongoing. Don't to
+ * anything in such case.
+ */
+ dma_status = dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state);
+ if (dma_status == DMA_IN_PROGRESS)
+ return;
count = dma->rx_size - state.residue;
tty_insert_flip_string(tty_port, dma->rx_buf, count);
p->port.icount.rx += count;
+ dma->rx_running = 0;
tty_flip_buffer_push(tty_port);
}
+static void dma_rx_complete(void *param)
+{
+ struct uart_8250_port *p = param;
+ struct uart_8250_dma *dma = p->dma;
+ unsigned long flags;
+
+ spin_lock_irqsave(&p->port.lock, flags);
+ if (dma->rx_running)
+ __dma_rx_complete(p);
+ spin_unlock_irqrestore(&p->port.lock, flags);
+}
#endif
int serial8250_tx_dma(struct uart_8250_port *p)
@@ -110,10 +125,19 @@
struct uart_8250_dma *dma = p->dma;
struct circ_buf *xmit = &p->port.state->xmit;
struct dma_async_tx_descriptor *desc;
+ struct uart_port *up = &p->port;
int ret;
- if (dma->tx_running)
+ if (dma->tx_running) {
+ if (up->x_char) {
+ dmaengine_pause(dma->txchan);
+ uart_xchar_out(up, UART_TX);
+ dmaengine_resume(dma->txchan);
+ }
return 0;
+ } else if (up->x_char) {
+ uart_xchar_out(up, UART_TX);
+ }
if (uart_tx_stopped(&p->port) || uart_circ_empty(xmit)) {
/* We have been called from __dma_tx_complete() */
@@ -122,7 +146,7 @@
}
dma->tx_size = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE);
-#ifdef CONFIG_ARCH_ROCKCHIP
+#if defined(CONFIG_ARCH_ROCKCHIP) && defined(CONFIG_NO_GKI)
if (dma->tx_size < MAX_TX_BYTES) {
ret = -EBUSY;
goto err;
@@ -146,16 +170,14 @@
dma_sync_single_for_device(dma->txchan->device->dev, dma->tx_addr,
UART_XMIT_SIZE, DMA_TO_DEVICE);
+#if defined(CONFIG_ARCH_ROCKCHIP) && defined(CONFIG_NO_GKI)
+ /* Clear uart dma request before start dma */
+ serial_port_out(&p->port, DW_UART_DMASA, 0x1);
+#endif
dma_async_issue_pending(dma->txchan);
if (dma->tx_err) {
dma->tx_err = 0;
- if (p->ier & UART_IER_THRI) {
- p->ier &= ~UART_IER_THRI;
-#ifdef CONFIG_ARCH_ROCKCHIP
- p->ier &= ~UART_IER_PTIME;
-#endif
- serial_out(p, UART_IER, p->ier);
- }
+ serial8250_clear_THRI(p);
}
return 0;
err:
@@ -163,7 +185,7 @@
return ret;
}
-#ifdef CONFIG_ARCH_ROCKCHIP
+#if defined(CONFIG_ARCH_ROCKCHIP) && defined(CONFIG_NO_GKI)
int serial8250_rx_dma(struct uart_8250_port *p)
{
@@ -236,7 +258,7 @@
return -EBUSY;
dma->rx_running = 1;
- desc->callback = __dma_rx_complete;
+ desc->callback = dma_rx_complete;
desc->callback_param = p;
dma->rx_cookie = dmaengine_submit(desc);
@@ -275,7 +297,7 @@
dma->rxconf.direction = DMA_DEV_TO_MEM;
dma->rxconf.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
dma->rxconf.src_addr = rx_dma_addr + UART_RX;
-#ifdef CONFIG_ARCH_ROCKCHIP
+#if defined(CONFIG_ARCH_ROCKCHIP) && defined(CONFIG_NO_GKI)
if ((p->port.fifosize / 4) < 16)
dma->rxconf.src_maxburst = p->port.fifosize / 4;
else
@@ -285,7 +307,7 @@
dma->txconf.direction = DMA_MEM_TO_DEV;
dma->txconf.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
dma->txconf.dst_addr = tx_dma_addr + UART_TX;
-#ifdef CONFIG_ARCH_ROCKCHIP
+#if defined(CONFIG_ARCH_ROCKCHIP) && defined(CONFIG_NO_GKI)
dma->txconf.dst_maxburst = 16;
#endif
dma_cap_zero(mask);
@@ -301,17 +323,17 @@
/* 8250 rx dma requires dmaengine driver to support pause/terminate */
ret = dma_get_slave_caps(dma->rxchan, &caps);
if (ret)
- goto err_rx;
+ goto release_rx;
if (!caps.cmd_pause || !caps.cmd_terminate ||
caps.residue_granularity == DMA_RESIDUE_GRANULARITY_DESCRIPTOR) {
ret = -EINVAL;
- goto err_rx;
+ goto release_rx;
}
dmaengine_slave_config(dma->rxchan, &dma->rxconf);
/* RX buffer */
-#ifdef CONFIG_ARCH_ROCKCHIP
+#if defined(CONFIG_ARCH_ROCKCHIP) && defined(CONFIG_NO_GKI)
if (!dma->rx_size)
dma->rx_size = PAGE_SIZE * 2;
#else
@@ -321,10 +343,9 @@
dma->rx_buf = dma_alloc_coherent(dma->rxchan->device->dev, dma->rx_size,
&dma->rx_addr, GFP_KERNEL);
-
if (!dma->rx_buf) {
ret = -ENOMEM;
- goto err_rx;
+ goto release_rx;
}
/* Get a channel for TX */
@@ -352,13 +373,12 @@
dev_info_ratelimited(p->port.dev, "got rx dma channels only\n");
}
-#ifdef CONFIG_ARCH_ROCKCHIP
+#if defined(CONFIG_ARCH_ROCKCHIP) && defined(CONFIG_NO_GKI)
/* start dma for rx*/
serial8250_start_rx_dma(p);
#endif
return 0;
-
-err_rx:
+release_rx:
dma_release_channel(dma->rxchan);
return ret;
}
@@ -377,7 +397,7 @@
dma->rx_addr);
dma_release_channel(dma->rxchan);
dma->rxchan = NULL;
-#ifdef CONFIG_ARCH_ROCKCHIP
+#if defined(CONFIG_ARCH_ROCKCHIP) && defined(CONFIG_NO_GKI)
dma->rx_running = 0;
#endif
/* Release TX resources */
--
Gitblit v1.6.2