linux-serial.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 0/9] tty: serial: fsl_lpuart various fixes and LS1028A support
@ 2020-03-03 17:42 Michael Walle
  2020-03-03 17:42 ` [PATCH v3 1/9] Revert "tty: serial: fsl_lpuart: drop EARLYCON_DECLARE" Michael Walle
                   ` (9 more replies)
  0 siblings, 10 replies; 14+ messages in thread
From: Michael Walle @ 2020-03-03 17:42 UTC (permalink / raw)
  To: linux-serial, devicetree, linux-kernel, linux-arm-kernel
  Cc: Greg Kroah-Hartman, Rob Herring, Mark Rutland, Shawn Guo,
	Li Yang, Jiri Slaby, Peng Fan, Vabhav Sharma, Yuan Yao,
	Michael Walle

These are various fixes for problems I found during development of the
LS1028A support for the LPUART.

Also, I'm not sure if this series should be split between the "tty:
serial: fsl_lpuart" patches and the devicetree patches. So unless
someone tell me otherwise I keep them together to avoid mention any
dependencies.

Changes since v2:
Changed DMA channel request handling. Spotted by Rob Herring. Thanks.

Modified patches:
  tty: serial: fsl_lpuart: handle EPROBE_DEFER for DMA

Changes since v1:
DMA support fixes.

New patches:
  tty: serial: fsl_lpuart: fix DMA mapping
  arm64: dts: ls1028a: add "fsl,vf610-edma" compatible

Modified patches:
  arm64: dts: ls1028a: add missing LPUART nodes
   - add dma phandles

Michael Walle (9):
  Revert "tty: serial: fsl_lpuart: drop EARLYCON_DECLARE"
  tty: serial: fsl_lpuart: free IDs allocated by IDA
  tty: serial: fsl_lpuart: handle EPROBE_DEFER for DMA
  tty: serial: fsl_lpuart: fix DMA mapping
  dt-bindings: serial: lpuart: add ls1028a compatibility
  tty: serial: fsl_lpuart: add LS1028A support
  tty: serial: fsl_lpuart: add LS1028A earlycon support
  arm64: dts: ls1028a: add "fsl,vf610-edma" compatible
  arm64: dts: ls1028a: add missing LPUART nodes

 .../devicetree/bindings/serial/fsl-lpuart.txt |  10 +-
 .../arm64/boot/dts/freescale/fsl-ls1028a.dtsi |  75 +++++-
 drivers/tty/serial/fsl_lpuart.c               | 251 ++++++++++++------
 3 files changed, 255 insertions(+), 81 deletions(-)

-- 
2.20.1


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v3 1/9] Revert "tty: serial: fsl_lpuart: drop EARLYCON_DECLARE"
  2020-03-03 17:42 [PATCH v3 0/9] tty: serial: fsl_lpuart various fixes and LS1028A support Michael Walle
@ 2020-03-03 17:42 ` Michael Walle
  2020-03-03 17:42 ` [PATCH v3 2/9] tty: serial: fsl_lpuart: free IDs allocated by IDA Michael Walle
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Michael Walle @ 2020-03-03 17:42 UTC (permalink / raw)
  To: linux-serial, devicetree, linux-kernel, linux-arm-kernel
  Cc: Greg Kroah-Hartman, Rob Herring, Mark Rutland, Shawn Guo,
	Li Yang, Jiri Slaby, Peng Fan, Vabhav Sharma, Yuan Yao,
	Michael Walle

This reverts commit a659652f6169240a5818cb244b280c5a362ef5a4.

This broke the earlycon on LS1021A processors because the order of the
earlycon_setup() functions were changed. Before the commit the normal
lpuart32_early_console_setup() was called. After the commit the
lpuart32_imx_early_console_setup() is called instead.

Fixes: a659652f6169 ("tty: serial: fsl_lpuart: drop EARLYCON_DECLARE")
Signed-off-by: Michael Walle <michael@walle.cc>
---
 drivers/tty/serial/fsl_lpuart.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
index 91e2805e6441..27fdc131c352 100644
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -2390,6 +2390,8 @@ static int __init lpuart32_imx_early_console_setup(struct earlycon_device *devic
 OF_EARLYCON_DECLARE(lpuart, "fsl,vf610-lpuart", lpuart_early_console_setup);
 OF_EARLYCON_DECLARE(lpuart32, "fsl,ls1021a-lpuart", lpuart32_early_console_setup);
 OF_EARLYCON_DECLARE(lpuart32, "fsl,imx7ulp-lpuart", lpuart32_imx_early_console_setup);
+EARLYCON_DECLARE(lpuart, lpuart_early_console_setup);
+EARLYCON_DECLARE(lpuart32, lpuart32_early_console_setup);
 
 #define LPUART_CONSOLE	(&lpuart_console)
 #define LPUART32_CONSOLE	(&lpuart32_console)
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v3 2/9] tty: serial: fsl_lpuart: free IDs allocated by IDA
  2020-03-03 17:42 [PATCH v3 0/9] tty: serial: fsl_lpuart various fixes and LS1028A support Michael Walle
  2020-03-03 17:42 ` [PATCH v3 1/9] Revert "tty: serial: fsl_lpuart: drop EARLYCON_DECLARE" Michael Walle
@ 2020-03-03 17:42 ` Michael Walle
  2020-03-03 17:43 ` [PATCH v3 3/9] tty: serial: fsl_lpuart: handle EPROBE_DEFER for DMA Michael Walle
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Michael Walle @ 2020-03-03 17:42 UTC (permalink / raw)
  To: linux-serial, devicetree, linux-kernel, linux-arm-kernel
  Cc: Greg Kroah-Hartman, Rob Herring, Mark Rutland, Shawn Guo,
	Li Yang, Jiri Slaby, Peng Fan, Vabhav Sharma, Yuan Yao,
	Michael Walle

Since commit 3bc3206e1c0f ("serial: fsl_lpuart: Remove the alias node
dependence") the port line number can also be allocated by IDA, but in
case of an error the ID will no be removed again. More importantly, any
ID will be freed in remove(), even if it wasn't allocated but instead
fetched by of_alias_get_id(). If it was not allocated by IDA there will
be a warning:
  WARN(1, "ida_free called for id=%d which is not allocated.\n", id);

Move the ID allocation more to the end of the probe() so that we still
can use plain return in the first error cases.

Fixes: 3bc3206e1c0f ("serial: fsl_lpuart: Remove the alias node dependence")
Signed-off-by: Michael Walle <michael@walle.cc>
---
 drivers/tty/serial/fsl_lpuart.c | 39 ++++++++++++++++++++-------------
 1 file changed, 24 insertions(+), 15 deletions(-)

diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
index 27fdc131c352..c31b8f3db6bf 100644
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -264,6 +264,7 @@ struct lpuart_port {
 	int			rx_dma_rng_buf_len;
 	unsigned int		dma_tx_nents;
 	wait_queue_head_t	dma_wait;
+	bool			id_allocated;
 };
 
 struct lpuart_soc_data {
@@ -2422,19 +2423,6 @@ static int lpuart_probe(struct platform_device *pdev)
 	if (!sport)
 		return -ENOMEM;
 
-	ret = of_alias_get_id(np, "serial");
-	if (ret < 0) {
-		ret = ida_simple_get(&fsl_lpuart_ida, 0, UART_NR, GFP_KERNEL);
-		if (ret < 0) {
-			dev_err(&pdev->dev, "port line is full, add device failed\n");
-			return ret;
-		}
-	}
-	if (ret >= ARRAY_SIZE(lpuart_ports)) {
-		dev_err(&pdev->dev, "serial%d out of range\n", ret);
-		return -EINVAL;
-	}
-	sport->port.line = ret;
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	sport->port.membase = devm_ioremap_resource(&pdev->dev, res);
 	if (IS_ERR(sport->port.membase))
@@ -2479,9 +2467,25 @@ static int lpuart_probe(struct platform_device *pdev)
 		}
 	}
 
+	ret = of_alias_get_id(np, "serial");
+	if (ret < 0) {
+		ret = ida_simple_get(&fsl_lpuart_ida, 0, UART_NR, GFP_KERNEL);
+		if (ret < 0) {
+			dev_err(&pdev->dev, "port line is full, add device failed\n");
+			return ret;
+		}
+		sport->id_allocated = true;
+	}
+	if (ret >= ARRAY_SIZE(lpuart_ports)) {
+		dev_err(&pdev->dev, "serial%d out of range\n", ret);
+		ret = -EINVAL;
+		goto failed_out_of_range;
+	}
+	sport->port.line = ret;
+
 	ret = lpuart_enable_clks(sport);
 	if (ret)
-		return ret;
+		goto failed_clock_enable;
 	sport->port.uartclk = lpuart_get_baud_clk_rate(sport);
 
 	lpuart_ports[sport->port.line] = sport;
@@ -2531,6 +2535,10 @@ static int lpuart_probe(struct platform_device *pdev)
 failed_attach_port:
 failed_irq_request:
 	lpuart_disable_clks(sport);
+failed_clock_enable:
+failed_out_of_range:
+	if (sport->id_allocated)
+		ida_simple_remove(&fsl_lpuart_ida, sport->port.line);
 	return ret;
 }
 
@@ -2540,7 +2548,8 @@ static int lpuart_remove(struct platform_device *pdev)
 
 	uart_remove_one_port(&lpuart_reg, &sport->port);
 
-	ida_simple_remove(&fsl_lpuart_ida, sport->port.line);
+	if (sport->id_allocated)
+		ida_simple_remove(&fsl_lpuart_ida, sport->port.line);
 
 	lpuart_disable_clks(sport);
 
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v3 3/9] tty: serial: fsl_lpuart: handle EPROBE_DEFER for DMA
  2020-03-03 17:42 [PATCH v3 0/9] tty: serial: fsl_lpuart various fixes and LS1028A support Michael Walle
  2020-03-03 17:42 ` [PATCH v3 1/9] Revert "tty: serial: fsl_lpuart: drop EARLYCON_DECLARE" Michael Walle
  2020-03-03 17:42 ` [PATCH v3 2/9] tty: serial: fsl_lpuart: free IDs allocated by IDA Michael Walle
@ 2020-03-03 17:43 ` Michael Walle
  2020-03-03 18:47   ` Rob Herring
  2020-03-03 17:43 ` [PATCH v3 4/9] tty: serial: fsl_lpuart: fix DMA mapping Michael Walle
                   ` (6 subsequent siblings)
  9 siblings, 1 reply; 14+ messages in thread
From: Michael Walle @ 2020-03-03 17:43 UTC (permalink / raw)
  To: linux-serial, devicetree, linux-kernel, linux-arm-kernel
  Cc: Greg Kroah-Hartman, Rob Herring, Mark Rutland, Shawn Guo,
	Li Yang, Jiri Slaby, Peng Fan, Vabhav Sharma, Yuan Yao,
	Michael Walle

The DMA channel might not be available at probe time. This is esp. the
case if the DMA controller has an IOMMU mapping.

There is also another caveat. If there is no DMA controller at all,
dma_request_chan() will also return -EPROBE_DEFER. Thus we cannot test
for -EPROBE_DEFER in probe(). Otherwise the lpuart driver will fail to
probe if, for example, the DMA driver is not enabled in the kernel
configuration.

To workaround this, we request the DMA channel in _startup(). Other
serial drivers do it the same way.

Signed-off-by: Michael Walle <michael@walle.cc>
---
 drivers/tty/serial/fsl_lpuart.c | 84 +++++++++++++++++++++------------
 1 file changed, 53 insertions(+), 31 deletions(-)

diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
index c31b8f3db6bf..0b8c477b32a3 100644
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -1493,36 +1493,63 @@ static void rx_dma_timer_init(struct lpuart_port *sport)
 static void lpuart_tx_dma_startup(struct lpuart_port *sport)
 {
 	u32 uartbaud;
+	int ret;
 
-	if (sport->dma_tx_chan && !lpuart_dma_tx_request(&sport->port)) {
-		init_waitqueue_head(&sport->dma_wait);
-		sport->lpuart_dma_tx_use = true;
-		if (lpuart_is_32(sport)) {
-			uartbaud = lpuart32_read(&sport->port, UARTBAUD);
-			lpuart32_write(&sport->port,
-				       uartbaud | UARTBAUD_TDMAE, UARTBAUD);
-		} else {
-			writeb(readb(sport->port.membase + UARTCR5) |
-				UARTCR5_TDMAS, sport->port.membase + UARTCR5);
-		}
+	sport->dma_tx_chan = dma_request_slave_channel(sport->port.dev, "tx");
+	if (!sport->dma_tx_chan) {
+		dev_info_once(sport->port.dev,
+			      "DMA tx channel request failed, operating without tx DMA\n");
+		goto err;
+	}
+
+	ret = lpuart_dma_tx_request(&sport->port);
+	if (!ret)
+		goto err;
+
+	init_waitqueue_head(&sport->dma_wait);
+	sport->lpuart_dma_tx_use = true;
+	if (lpuart_is_32(sport)) {
+		uartbaud = lpuart32_read(&sport->port, UARTBAUD);
+		lpuart32_write(&sport->port,
+			       uartbaud | UARTBAUD_TDMAE, UARTBAUD);
 	} else {
-		sport->lpuart_dma_tx_use = false;
+		writeb(readb(sport->port.membase + UARTCR5) |
+		       UARTCR5_TDMAS, sport->port.membase + UARTCR5);
 	}
+
+	return;
+
+err:
+	sport->lpuart_dma_tx_use = false;
 }
 
 static void lpuart_rx_dma_startup(struct lpuart_port *sport)
 {
-	if (sport->dma_rx_chan && !lpuart_start_rx_dma(sport)) {
-		/* set Rx DMA timeout */
-		sport->dma_rx_timeout = msecs_to_jiffies(DMA_RX_TIMEOUT);
-		if (!sport->dma_rx_timeout)
-			sport->dma_rx_timeout = 1;
+	int ret;
 
-		sport->lpuart_dma_rx_use = true;
-		rx_dma_timer_init(sport);
-	} else {
-		sport->lpuart_dma_rx_use = false;
+	sport->dma_rx_chan = dma_request_slave_channel(sport->port.dev, "rx");
+	if (!sport->dma_rx_chan) {
+		dev_info_once(sport->port.dev,
+			      "DMA rx channel request failed, operating without rx DMA\n");
+		goto err;
 	}
+
+	ret = lpuart_start_rx_dma(sport);
+	if (ret)
+		goto err;
+
+	/* set Rx DMA timeout */
+	sport->dma_rx_timeout = msecs_to_jiffies(DMA_RX_TIMEOUT);
+	if (!sport->dma_rx_timeout)
+		sport->dma_rx_timeout = 1;
+
+	sport->lpuart_dma_rx_use = true;
+	rx_dma_timer_init(sport);
+
+	return;
+
+err:
+	sport->lpuart_dma_rx_use = false;
 }
 
 static int lpuart_startup(struct uart_port *port)
@@ -1615,6 +1642,11 @@ static void lpuart_dma_shutdown(struct lpuart_port *sport)
 			dmaengine_terminate_all(sport->dma_tx_chan);
 		}
 	}
+
+	if (sport->dma_tx_chan)
+		dma_release_channel(sport->dma_tx_chan);
+	if (sport->dma_rx_chan)
+		dma_release_channel(sport->dma_rx_chan);
 }
 
 static void lpuart_shutdown(struct uart_port *port)
@@ -2520,16 +2552,6 @@ static int lpuart_probe(struct platform_device *pdev)
 
 	sport->port.rs485_config(&sport->port, &sport->port.rs485);
 
-	sport->dma_tx_chan = dma_request_slave_channel(sport->port.dev, "tx");
-	if (!sport->dma_tx_chan)
-		dev_info(sport->port.dev, "DMA tx channel request failed, "
-				"operating without tx DMA\n");
-
-	sport->dma_rx_chan = dma_request_slave_channel(sport->port.dev, "rx");
-	if (!sport->dma_rx_chan)
-		dev_info(sport->port.dev, "DMA rx channel request failed, "
-				"operating without rx DMA\n");
-
 	return 0;
 
 failed_attach_port:
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v3 4/9] tty: serial: fsl_lpuart: fix DMA mapping
  2020-03-03 17:42 [PATCH v3 0/9] tty: serial: fsl_lpuart various fixes and LS1028A support Michael Walle
                   ` (2 preceding siblings ...)
  2020-03-03 17:43 ` [PATCH v3 3/9] tty: serial: fsl_lpuart: handle EPROBE_DEFER for DMA Michael Walle
@ 2020-03-03 17:43 ` Michael Walle
  2020-03-03 17:43 ` [PATCH v3 5/9] dt-bindings: serial: lpuart: add ls1028a compatibility Michael Walle
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Michael Walle @ 2020-03-03 17:43 UTC (permalink / raw)
  To: linux-serial, devicetree, linux-kernel, linux-arm-kernel
  Cc: Greg Kroah-Hartman, Rob Herring, Mark Rutland, Shawn Guo,
	Li Yang, Jiri Slaby, Peng Fan, Vabhav Sharma, Yuan Yao,
	Michael Walle

Use the correct device to request the DMA mapping. Otherwise the IOMMU
doesn't get the mapping and it will generate a page fault.

The error messages look like:
[   19.012140] arm-smmu 5000000.iommu: Unhandled context fault: fsr=0x402, iova=0xbbfff800, fsynr=0x3e0021, cbfrsynra=0x828, cb=9
[   19.023593] arm-smmu 5000000.iommu: Unhandled context fault: fsr=0x402, iova=0xbbfff800, fsynr=0x3e0021, cbfrsynra=0x828, cb=9

This was tested on a custom board with a LS1028A SoC.

Signed-off-by: Michael Walle <michael@walle.cc>
---
 drivers/tty/serial/fsl_lpuart.c | 48 +++++++++++++++++++--------------
 1 file changed, 28 insertions(+), 20 deletions(-)

diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
index 0b8c477b32a3..ada7fb1fa075 100644
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -409,6 +409,7 @@ static void lpuart_dma_tx(struct lpuart_port *sport)
 	struct circ_buf *xmit = &sport->port.state->xmit;
 	struct scatterlist *sgl = sport->tx_sgl;
 	struct device *dev = sport->port.dev;
+	struct dma_chan *chan = sport->dma_tx_chan;
 	int ret;
 
 	if (sport->dma_tx_in_progress)
@@ -427,17 +428,19 @@ static void lpuart_dma_tx(struct lpuart_port *sport)
 		sg_set_buf(sgl + 1, xmit->buf, xmit->head);
 	}
 
-	ret = dma_map_sg(dev, sgl, sport->dma_tx_nents, DMA_TO_DEVICE);
+	ret = dma_map_sg(chan->device->dev, sgl, sport->dma_tx_nents,
+			 DMA_TO_DEVICE);
 	if (!ret) {
 		dev_err(dev, "DMA mapping error for TX.\n");
 		return;
 	}
 
-	sport->dma_tx_desc = dmaengine_prep_slave_sg(sport->dma_tx_chan, sgl,
+	sport->dma_tx_desc = dmaengine_prep_slave_sg(chan, sgl,
 					ret, DMA_MEM_TO_DEV,
 					DMA_PREP_INTERRUPT);
 	if (!sport->dma_tx_desc) {
-		dma_unmap_sg(dev, sgl, sport->dma_tx_nents, DMA_TO_DEVICE);
+		dma_unmap_sg(chan->device->dev, sgl, sport->dma_tx_nents,
+			      DMA_TO_DEVICE);
 		dev_err(dev, "Cannot prepare TX slave DMA!\n");
 		return;
 	}
@@ -446,7 +449,7 @@ static void lpuart_dma_tx(struct lpuart_port *sport)
 	sport->dma_tx_desc->callback_param = sport;
 	sport->dma_tx_in_progress = true;
 	sport->dma_tx_cookie = dmaengine_submit(sport->dma_tx_desc);
-	dma_async_issue_pending(sport->dma_tx_chan);
+	dma_async_issue_pending(chan);
 }
 
 static bool lpuart_stopped_or_empty(struct uart_port *port)
@@ -459,11 +462,13 @@ static void lpuart_dma_tx_complete(void *arg)
 	struct lpuart_port *sport = arg;
 	struct scatterlist *sgl = &sport->tx_sgl[0];
 	struct circ_buf *xmit = &sport->port.state->xmit;
+	struct dma_chan *chan = sport->dma_tx_chan;
 	unsigned long flags;
 
 	spin_lock_irqsave(&sport->port.lock, flags);
 
-	dma_unmap_sg(sport->port.dev, sgl, sport->dma_tx_nents, DMA_TO_DEVICE);
+	dma_unmap_sg(chan->device->dev, sgl, sport->dma_tx_nents,
+		     DMA_TO_DEVICE);
 
 	xmit->tail = (xmit->tail + sport->dma_tx_bytes) & (UART_XMIT_SIZE - 1);
 
@@ -529,15 +534,16 @@ static bool lpuart_is_32(struct lpuart_port *sport)
 static void lpuart_flush_buffer(struct uart_port *port)
 {
 	struct lpuart_port *sport = container_of(port, struct lpuart_port, port);
+	struct dma_chan *chan = sport->dma_tx_chan;
 	u32 val;
 
 	if (sport->lpuart_dma_tx_use) {
 		if (sport->dma_tx_in_progress) {
-			dma_unmap_sg(sport->port.dev, &sport->tx_sgl[0],
+			dma_unmap_sg(chan->device->dev, &sport->tx_sgl[0],
 				sport->dma_tx_nents, DMA_TO_DEVICE);
 			sport->dma_tx_in_progress = false;
 		}
-		dmaengine_terminate_all(sport->dma_tx_chan);
+		dmaengine_terminate_all(chan);
 	}
 
 	if (lpuart_is_32(sport)) {
@@ -993,6 +999,7 @@ static void lpuart_copy_rx_to_tty(struct lpuart_port *sport)
 	struct tty_port *port = &sport->port.state->port;
 	struct dma_tx_state state;
 	enum dma_status dmastat;
+	struct dma_chan *chan = sport->dma_rx_chan;
 	struct circ_buf *ring = &sport->rx_ring;
 	unsigned long flags;
 	int count = 0;
@@ -1053,10 +1060,7 @@ static void lpuart_copy_rx_to_tty(struct lpuart_port *sport)
 
 	spin_lock_irqsave(&sport->port.lock, flags);
 
-	dmastat = dmaengine_tx_status(sport->dma_rx_chan,
-				sport->dma_rx_cookie,
-				&state);
-
+	dmastat = dmaengine_tx_status(chan, sport->dma_rx_cookie, &state);
 	if (dmastat == DMA_ERROR) {
 		dev_err(sport->port.dev, "Rx DMA transfer failed!\n");
 		spin_unlock_irqrestore(&sport->port.lock, flags);
@@ -1064,7 +1068,8 @@ static void lpuart_copy_rx_to_tty(struct lpuart_port *sport)
 	}
 
 	/* CPU claims ownership of RX DMA buffer */
-	dma_sync_sg_for_cpu(sport->port.dev, &sport->rx_sgl, 1, DMA_FROM_DEVICE);
+	dma_sync_sg_for_cpu(chan->device->dev, &sport->rx_sgl, 1,
+			    DMA_FROM_DEVICE);
 
 	/*
 	 * ring->head points to the end of data already written by the DMA.
@@ -1106,7 +1111,7 @@ static void lpuart_copy_rx_to_tty(struct lpuart_port *sport)
 		sport->port.icount.rx += count;
 	}
 
-	dma_sync_sg_for_device(sport->port.dev, &sport->rx_sgl, 1,
+	dma_sync_sg_for_device(chan->device->dev, &sport->rx_sgl, 1,
 			       DMA_FROM_DEVICE);
 
 	spin_unlock_irqrestore(&sport->port.lock, flags);
@@ -1138,6 +1143,7 @@ static inline int lpuart_start_rx_dma(struct lpuart_port *sport)
 	struct tty_port *port = &sport->port.state->port;
 	struct tty_struct *tty = port->tty;
 	struct ktermios *termios = &tty->termios;
+	struct dma_chan *chan = sport->dma_rx_chan;
 
 	baud = tty_get_baud_rate(tty);
 
@@ -1159,7 +1165,8 @@ static inline int lpuart_start_rx_dma(struct lpuart_port *sport)
 		return -ENOMEM;
 
 	sg_init_one(&sport->rx_sgl, ring->buf, sport->rx_dma_rng_buf_len);
-	nent = dma_map_sg(sport->port.dev, &sport->rx_sgl, 1, DMA_FROM_DEVICE);
+	nent = dma_map_sg(chan->device->dev, &sport->rx_sgl, 1,
+			  DMA_FROM_DEVICE);
 
 	if (!nent) {
 		dev_err(sport->port.dev, "DMA Rx mapping error\n");
@@ -1170,7 +1177,7 @@ static inline int lpuart_start_rx_dma(struct lpuart_port *sport)
 	dma_rx_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
 	dma_rx_sconfig.src_maxburst = 1;
 	dma_rx_sconfig.direction = DMA_DEV_TO_MEM;
-	ret = dmaengine_slave_config(sport->dma_rx_chan, &dma_rx_sconfig);
+	ret = dmaengine_slave_config(chan, &dma_rx_sconfig);
 
 	if (ret < 0) {
 		dev_err(sport->port.dev,
@@ -1178,7 +1185,7 @@ static inline int lpuart_start_rx_dma(struct lpuart_port *sport)
 		return ret;
 	}
 
-	sport->dma_rx_desc = dmaengine_prep_dma_cyclic(sport->dma_rx_chan,
+	sport->dma_rx_desc = dmaengine_prep_dma_cyclic(chan,
 				 sg_dma_address(&sport->rx_sgl),
 				 sport->rx_sgl.length,
 				 sport->rx_sgl.length / 2,
@@ -1192,7 +1199,7 @@ static inline int lpuart_start_rx_dma(struct lpuart_port *sport)
 	sport->dma_rx_desc->callback = lpuart_dma_rx_complete;
 	sport->dma_rx_desc->callback_param = sport;
 	sport->dma_rx_cookie = dmaengine_submit(sport->dma_rx_desc);
-	dma_async_issue_pending(sport->dma_rx_chan);
+	dma_async_issue_pending(chan);
 
 	if (lpuart_is_32(sport)) {
 		unsigned long temp = lpuart32_read(&sport->port, UARTBAUD);
@@ -1210,11 +1217,12 @@ static void lpuart_dma_rx_free(struct uart_port *port)
 {
 	struct lpuart_port *sport = container_of(port,
 					struct lpuart_port, port);
+	struct dma_chan *chan = sport->dma_rx_chan;
 
-	if (sport->dma_rx_chan)
-		dmaengine_terminate_all(sport->dma_rx_chan);
+	if (chan)
+		dmaengine_terminate_all(chan);
 
-	dma_unmap_sg(sport->port.dev, &sport->rx_sgl, 1, DMA_FROM_DEVICE);
+	dma_unmap_sg(chan->device->dev, &sport->rx_sgl, 1, DMA_FROM_DEVICE);
 	kfree(sport->rx_ring.buf);
 	sport->rx_ring.tail = 0;
 	sport->rx_ring.head = 0;
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v3 5/9] dt-bindings: serial: lpuart: add ls1028a compatibility
  2020-03-03 17:42 [PATCH v3 0/9] tty: serial: fsl_lpuart various fixes and LS1028A support Michael Walle
                   ` (3 preceding siblings ...)
  2020-03-03 17:43 ` [PATCH v3 4/9] tty: serial: fsl_lpuart: fix DMA mapping Michael Walle
@ 2020-03-03 17:43 ` Michael Walle
  2020-03-03 17:43 ` [PATCH v3 6/9] tty: serial: fsl_lpuart: add LS1028A support Michael Walle
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Michael Walle @ 2020-03-03 17:43 UTC (permalink / raw)
  To: linux-serial, devicetree, linux-kernel, linux-arm-kernel
  Cc: Greg Kroah-Hartman, Rob Herring, Mark Rutland, Shawn Guo,
	Li Yang, Jiri Slaby, Peng Fan, Vabhav Sharma, Yuan Yao,
	Michael Walle, Rob Herring

Signed-off-by: Michael Walle <michael@walle.cc>
Reviewed-by: Rob Herring <robh@kernel.org>
---
 .../devicetree/bindings/serial/fsl-lpuart.txt          | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/serial/fsl-lpuart.txt b/Documentation/devicetree/bindings/serial/fsl-lpuart.txt
index c904e2e68332..e7448b92dd9d 100644
--- a/Documentation/devicetree/bindings/serial/fsl-lpuart.txt
+++ b/Documentation/devicetree/bindings/serial/fsl-lpuart.txt
@@ -6,6 +6,8 @@ Required properties:
     on Vybrid vf610 SoC with 8-bit register organization
   - "fsl,ls1021a-lpuart" for lpuart compatible with the one integrated
     on LS1021A SoC with 32-bit big-endian register organization
+  - "fsl,ls1028a-lpuart" for lpuart compatible with the one integrated
+    on LS1028A SoC with 32-bit little-endian register organization
   - "fsl,imx7ulp-lpuart" for lpuart compatible with the one integrated
     on i.MX7ULP SoC with 32-bit little-endian register organization
   - "fsl,imx8qxp-lpuart" for lpuart compatible with the one integrated
@@ -15,10 +17,10 @@ Required properties:
 - reg : Address and length of the register set for the device
 - interrupts : Should contain uart interrupt
 - clocks : phandle + clock specifier pairs, one for each entry in clock-names
-- clock-names : For vf610/ls1021a/imx7ulp, "ipg" clock is for uart bus/baud
-  clock. For imx8qxp lpuart, "ipg" clock is bus clock that is used to access
-  lpuart controller registers, it also requires "baud" clock for module to
-  receive/transmit data.
+- clock-names : For vf610/ls1021a/ls1028a/imx7ulp, "ipg" clock is for uart
+  bus/baud clock. For imx8qxp lpuart, "ipg" clock is bus clock that is used
+  to access lpuart controller registers, it also requires "baud" clock for
+  module to receive/transmit data.
 
 Optional properties:
 - dmas: A list of two dma specifiers, one for each entry in dma-names.
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v3 6/9] tty: serial: fsl_lpuart: add LS1028A support
  2020-03-03 17:42 [PATCH v3 0/9] tty: serial: fsl_lpuart various fixes and LS1028A support Michael Walle
                   ` (4 preceding siblings ...)
  2020-03-03 17:43 ` [PATCH v3 5/9] dt-bindings: serial: lpuart: add ls1028a compatibility Michael Walle
@ 2020-03-03 17:43 ` Michael Walle
  2020-03-03 17:43 ` [PATCH v3 7/9] tty: serial: fsl_lpuart: add LS1028A earlycon support Michael Walle
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Michael Walle @ 2020-03-03 17:43 UTC (permalink / raw)
  To: linux-serial, devicetree, linux-kernel, linux-arm-kernel
  Cc: Greg Kroah-Hartman, Rob Herring, Mark Rutland, Shawn Guo,
	Li Yang, Jiri Slaby, Peng Fan, Vabhav Sharma, Yuan Yao,
	Michael Walle

The LS1028A uses little endian register access and has a different FIFO
size encoding.

Signed-off-by: Michael Walle <michael@walle.cc>
---
 drivers/tty/serial/fsl_lpuart.c | 27 +++++++++++++++++++++++++--
 1 file changed, 25 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
index ada7fb1fa075..54af8c1927ee 100644
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -234,6 +234,7 @@ static DEFINE_IDA(fsl_lpuart_ida);
 enum lpuart_type {
 	VF610_LPUART,
 	LS1021A_LPUART,
+	LS1028A_LPUART,
 	IMX7ULP_LPUART,
 	IMX8QXP_LPUART,
 };
@@ -278,11 +279,16 @@ static const struct lpuart_soc_data vf_data = {
 	.iotype = UPIO_MEM,
 };
 
-static const struct lpuart_soc_data ls_data = {
+static const struct lpuart_soc_data ls1021a_data = {
 	.devtype = LS1021A_LPUART,
 	.iotype = UPIO_MEM32BE,
 };
 
+static const struct lpuart_soc_data ls1028a_data = {
+	.devtype = LS1028A_LPUART,
+	.iotype = UPIO_MEM32,
+};
+
 static struct lpuart_soc_data imx7ulp_data = {
 	.devtype = IMX7ULP_LPUART,
 	.iotype = UPIO_MEM32,
@@ -297,7 +303,8 @@ static struct lpuart_soc_data imx8qxp_data = {
 
 static const struct of_device_id lpuart_dt_ids[] = {
 	{ .compatible = "fsl,vf610-lpuart",	.data = &vf_data, },
-	{ .compatible = "fsl,ls1021a-lpuart",	.data = &ls_data, },
+	{ .compatible = "fsl,ls1021a-lpuart",	.data = &ls1021a_data, },
+	{ .compatible = "fsl,ls1028a-lpuart",	.data = &ls1028a_data, },
 	{ .compatible = "fsl,imx7ulp-lpuart",	.data = &imx7ulp_data, },
 	{ .compatible = "fsl,imx8qxp-lpuart",	.data = &imx8qxp_data, },
 	{ /* sentinel */ }
@@ -307,6 +314,11 @@ MODULE_DEVICE_TABLE(of, lpuart_dt_ids);
 /* Forward declare this for the dma callbacks*/
 static void lpuart_dma_tx_complete(void *arg);
 
+static inline bool is_ls1028a_lpuart(struct lpuart_port *sport)
+{
+	return sport->devtype == LS1028A_LPUART;
+}
+
 static inline bool is_imx8qxp_lpuart(struct lpuart_port *sport)
 {
 	return sport->devtype == IMX8QXP_LPUART;
@@ -1622,6 +1634,17 @@ static int lpuart32_startup(struct uart_port *port)
 	sport->rxfifo_size = UARTFIFO_DEPTH((temp >> UARTFIFO_RXSIZE_OFF) &
 					    UARTFIFO_FIFOSIZE_MASK);
 
+	/*
+	 * The LS1028A has a fixed length of 16 words. Although it supports the
+	 * RX/TXSIZE fields their encoding is different. Eg the reference manual
+	 * states 0b101 is 16 words.
+	 */
+	if (is_ls1028a_lpuart(sport)) {
+		sport->rxfifo_size = 16;
+		sport->txfifo_size = 16;
+		sport->port.fifosize = sport->txfifo_size;
+	}
+
 	spin_lock_irqsave(&sport->port.lock, flags);
 
 	lpuart32_setup_watermark_enable(sport);
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v3 7/9] tty: serial: fsl_lpuart: add LS1028A earlycon support
  2020-03-03 17:42 [PATCH v3 0/9] tty: serial: fsl_lpuart various fixes and LS1028A support Michael Walle
                   ` (5 preceding siblings ...)
  2020-03-03 17:43 ` [PATCH v3 6/9] tty: serial: fsl_lpuart: add LS1028A support Michael Walle
@ 2020-03-03 17:43 ` Michael Walle
  2020-03-03 17:43 ` [PATCH v3 8/9] arm64: dts: ls1028a: add "fsl,vf610-edma" compatible Michael Walle
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Michael Walle @ 2020-03-03 17:43 UTC (permalink / raw)
  To: linux-serial, devicetree, linux-kernel, linux-arm-kernel
  Cc: Greg Kroah-Hartman, Rob Herring, Mark Rutland, Shawn Guo,
	Li Yang, Jiri Slaby, Peng Fan, Vabhav Sharma, Yuan Yao,
	Michael Walle

Add a early_console_setup() for the LS1028A SoC with 32bit, little
endian access. If the bootloader does a fixup of the clock-frequency
node the baudrate divisor register will automatically be set.

Signed-off-by: Michael Walle <michael@walle.cc>
---
 drivers/tty/serial/fsl_lpuart.c | 51 +++++++++++++++++++++++++++------
 1 file changed, 43 insertions(+), 8 deletions(-)

diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
index 54af8c1927ee..f443c74eee44 100644
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -1874,11 +1874,12 @@ lpuart_set_termios(struct uart_port *port, struct ktermios *termios,
 	spin_unlock_irqrestore(&sport->port.lock, flags);
 }
 
-static void
-lpuart32_serial_setbrg(struct lpuart_port *sport, unsigned int baudrate)
+static void __lpuart32_serial_setbrg(struct uart_port *port,
+				     unsigned int baudrate, bool use_rx_dma,
+				     bool use_tx_dma)
 {
 	u32 sbr, osr, baud_diff, tmp_osr, tmp_sbr, tmp_diff, tmp;
-	u32 clk = sport->port.uartclk;
+	u32 clk = port->uartclk;
 
 	/*
 	 * The idea is to use the best OSR (over-sampling rate) possible.
@@ -1924,10 +1925,10 @@ lpuart32_serial_setbrg(struct lpuart_port *sport, unsigned int baudrate)
 
 	/* handle buadrate outside acceptable rate */
 	if (baud_diff > ((baudrate / 100) * 3))
-		dev_warn(sport->port.dev,
+		dev_warn(port->dev,
 			 "unacceptable baud rate difference of more than 3%%\n");
 
-	tmp = lpuart32_read(&sport->port, UARTBAUD);
+	tmp = lpuart32_read(port, UARTBAUD);
 
 	if ((osr > 3) && (osr < 8))
 		tmp |= UARTBAUD_BOTHEDGE;
@@ -1938,14 +1939,23 @@ lpuart32_serial_setbrg(struct lpuart_port *sport, unsigned int baudrate)
 	tmp &= ~UARTBAUD_SBR_MASK;
 	tmp |= sbr & UARTBAUD_SBR_MASK;
 
-	if (!sport->lpuart_dma_rx_use)
+	if (!use_rx_dma)
 		tmp &= ~UARTBAUD_RDMAE;
-	if (!sport->lpuart_dma_tx_use)
+	if (!use_tx_dma)
 		tmp &= ~UARTBAUD_TDMAE;
 
-	lpuart32_write(&sport->port, tmp, UARTBAUD);
+	lpuart32_write(port, tmp, UARTBAUD);
+}
+
+static void lpuart32_serial_setbrg(struct lpuart_port *sport,
+				   unsigned int baudrate)
+{
+	__lpuart32_serial_setbrg(&sport->port, baudrate,
+				 sport->lpuart_dma_rx_use,
+				 sport->lpuart_dma_tx_use);
 }
 
+
 static void
 lpuart32_set_termios(struct uart_port *port, struct ktermios *termios,
 		   struct ktermios *old)
@@ -2439,6 +2449,30 @@ static int __init lpuart32_early_console_setup(struct earlycon_device *device,
 	return 0;
 }
 
+static int __init ls1028a_early_console_setup(struct earlycon_device *device,
+					      const char *opt)
+{
+	u32 cr;
+
+	if (!device->port.membase)
+		return -ENODEV;
+
+	device->port.iotype = UPIO_MEM32;
+	device->con->write = lpuart32_early_write;
+
+	/* set the baudrate */
+	if (device->port.uartclk && device->baud)
+		__lpuart32_serial_setbrg(&device->port, device->baud,
+					 false, false);
+
+	/* enable transmitter */
+	cr = lpuart32_read(&device->port, UARTCTRL);
+	cr |= UARTCTRL_TE;
+	lpuart32_write(&device->port, cr, UARTCTRL);
+
+	return 0;
+}
+
 static int __init lpuart32_imx_early_console_setup(struct earlycon_device *device,
 						   const char *opt)
 {
@@ -2453,6 +2487,7 @@ static int __init lpuart32_imx_early_console_setup(struct earlycon_device *devic
 }
 OF_EARLYCON_DECLARE(lpuart, "fsl,vf610-lpuart", lpuart_early_console_setup);
 OF_EARLYCON_DECLARE(lpuart32, "fsl,ls1021a-lpuart", lpuart32_early_console_setup);
+OF_EARLYCON_DECLARE(lpuart32, "fsl,ls1028a-lpuart", ls1028a_early_console_setup);
 OF_EARLYCON_DECLARE(lpuart32, "fsl,imx7ulp-lpuart", lpuart32_imx_early_console_setup);
 EARLYCON_DECLARE(lpuart, lpuart_early_console_setup);
 EARLYCON_DECLARE(lpuart32, lpuart32_early_console_setup);
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v3 8/9] arm64: dts: ls1028a: add "fsl,vf610-edma" compatible
  2020-03-03 17:42 [PATCH v3 0/9] tty: serial: fsl_lpuart various fixes and LS1028A support Michael Walle
                   ` (6 preceding siblings ...)
  2020-03-03 17:43 ` [PATCH v3 7/9] tty: serial: fsl_lpuart: add LS1028A earlycon support Michael Walle
@ 2020-03-03 17:43 ` Michael Walle
  2020-03-03 22:43   ` Leo Li
  2020-03-03 17:43 ` [PATCH v3 9/9] arm64: dts: ls1028a: add missing LPUART nodes Michael Walle
  2020-03-03 22:49 ` [PATCH v3 0/9] tty: serial: fsl_lpuart various fixes and LS1028A support Leo Li
  9 siblings, 1 reply; 14+ messages in thread
From: Michael Walle @ 2020-03-03 17:43 UTC (permalink / raw)
  To: linux-serial, devicetree, linux-kernel, linux-arm-kernel
  Cc: Greg Kroah-Hartman, Rob Herring, Mark Rutland, Shawn Guo,
	Li Yang, Jiri Slaby, Peng Fan, Vabhav Sharma, Yuan Yao,
	Michael Walle

The bootloader does the IOMMU fixup and dynamically adds the "iommus"
property to devices according to its compatible string. In case of the
eDMA controller this property is missing. Add it. After that the IOMMU
will work with the eDMA core.

Signed-off-by: Michael Walle <michael@walle.cc>
---
 arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
index 0bf375ec959b..0843cfbe7ae1 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
@@ -335,7 +335,7 @@
 
 		edma0: dma-controller@22c0000 {
 			#dma-cells = <2>;
-			compatible = "fsl,ls1028a-edma";
+			compatible = "fsl,ls1028a-edma", "fsl,vf610-edma";
 			reg = <0x0 0x22c0000 0x0 0x10000>,
 			      <0x0 0x22d0000 0x0 0x10000>,
 			      <0x0 0x22e0000 0x0 0x10000>;
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v3 9/9] arm64: dts: ls1028a: add missing LPUART nodes
  2020-03-03 17:42 [PATCH v3 0/9] tty: serial: fsl_lpuart various fixes and LS1028A support Michael Walle
                   ` (7 preceding siblings ...)
  2020-03-03 17:43 ` [PATCH v3 8/9] arm64: dts: ls1028a: add "fsl,vf610-edma" compatible Michael Walle
@ 2020-03-03 17:43 ` Michael Walle
  2020-03-03 22:49 ` [PATCH v3 0/9] tty: serial: fsl_lpuart various fixes and LS1028A support Leo Li
  9 siblings, 0 replies; 14+ messages in thread
From: Michael Walle @ 2020-03-03 17:43 UTC (permalink / raw)
  To: linux-serial, devicetree, linux-kernel, linux-arm-kernel
  Cc: Greg Kroah-Hartman, Rob Herring, Mark Rutland, Shawn Guo,
	Li Yang, Jiri Slaby, Peng Fan, Vabhav Sharma, Yuan Yao,
	Michael Walle

The LS1028A has six LPUART controllers. Add the nodes.

This was tested on a custom board.

Signed-off-by: Michael Walle <michael@walle.cc>
---
 .../arm64/boot/dts/freescale/fsl-ls1028a.dtsi | 73 +++++++++++++++++++
 1 file changed, 73 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
index 0843cfbe7ae1..df51e81ebe84 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
@@ -333,6 +333,79 @@
 			status = "disabled";
 		};
 
+
+		lpuart0: serial@2260000 {
+			compatible = "fsl,ls1028a-lpuart";
+			reg = <0x0 0x2260000 0x0 0x1000>;
+			interrupts = <GIC_SPI 232 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clockgen 4 1>;
+			clock-names = "ipg";
+			dma-names = "rx","tx";
+			dmas = <&edma0 1 32>,
+			       <&edma0 1 33>;
+			status = "disabled";
+		};
+
+		lpuart1: serial@2270000 {
+			compatible = "fsl,ls1028a-lpuart";
+			reg = <0x0 0x2270000 0x0 0x1000>;
+			interrupts = <GIC_SPI 233 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clockgen 4 1>;
+			clock-names = "ipg";
+			dma-names = "rx","tx";
+			dmas = <&edma0 1 30>,
+			       <&edma0 1 31>;
+			status = "disabled";
+		};
+
+		lpuart2: serial@2280000 {
+			compatible = "fsl,ls1028a-lpuart";
+			reg = <0x0 0x2280000 0x0 0x1000>;
+			interrupts = <GIC_SPI 234 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clockgen 4 1>;
+			clock-names = "ipg";
+			dma-names = "rx","tx";
+			dmas = <&edma0 1 28>,
+			       <&edma0 1 29>;
+			status = "disabled";
+		};
+
+		lpuart3: serial@2290000 {
+			compatible = "fsl,ls1028a-lpuart";
+			reg = <0x0 0x2290000 0x0 0x1000>;
+			interrupts = <GIC_SPI 235 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clockgen 4 1>;
+			clock-names = "ipg";
+			dma-names = "rx","tx";
+			dmas = <&edma0 1 26>,
+			       <&edma0 1 27>;
+			status = "disabled";
+		};
+
+		lpuart4: serial@22a0000 {
+			compatible = "fsl,ls1028a-lpuart";
+			reg = <0x0 0x22a0000 0x0 0x1000>;
+			interrupts = <GIC_SPI 236 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clockgen 4 1>;
+			clock-names = "ipg";
+			dma-names = "rx","tx";
+			dmas = <&edma0 1 24>,
+			       <&edma0 1 25>;
+			status = "disabled";
+		};
+
+		lpuart5: serial@22b0000 {
+			compatible = "fsl,ls1028a-lpuart";
+			reg = <0x0 0x22b0000 0x0 0x1000>;
+			interrupts = <GIC_SPI 237 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clockgen 4 1>;
+			clock-names = "ipg";
+			dma-names = "rx","tx";
+			dmas = <&edma0 1 22>,
+			       <&edma0 1 23>;
+			status = "disabled";
+		};
+
 		edma0: dma-controller@22c0000 {
 			#dma-cells = <2>;
 			compatible = "fsl,ls1028a-edma", "fsl,vf610-edma";
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH v3 3/9] tty: serial: fsl_lpuart: handle EPROBE_DEFER for DMA
  2020-03-03 17:43 ` [PATCH v3 3/9] tty: serial: fsl_lpuart: handle EPROBE_DEFER for DMA Michael Walle
@ 2020-03-03 18:47   ` Rob Herring
  2020-03-03 20:57     ` Michael Walle
  0 siblings, 1 reply; 14+ messages in thread
From: Rob Herring @ 2020-03-03 18:47 UTC (permalink / raw)
  To: Michael Walle
  Cc: linux-serial, devicetree, linux-kernel, linux-arm-kernel,
	Greg Kroah-Hartman, Mark Rutland, Shawn Guo, Li Yang, Jiri Slaby,
	Peng Fan, Vabhav Sharma, Yuan Yao

On Tue, Mar 03, 2020 at 06:43:00PM +0100, Michael Walle wrote:
> The DMA channel might not be available at probe time. This is esp. the
> case if the DMA controller has an IOMMU mapping.

The subject should be updated as this doesn't involve deferred probe any 
more. 

> There is also another caveat. If there is no DMA controller at all,
> dma_request_chan() will also return -EPROBE_DEFER. Thus we cannot test
> for -EPROBE_DEFER in probe(). Otherwise the lpuart driver will fail to
> probe if, for example, the DMA driver is not enabled in the kernel
> configuration.
> 
> To workaround this, we request the DMA channel in _startup(). Other
> serial drivers do it the same way.
> 
> Signed-off-by: Michael Walle <michael@walle.cc>
> ---
>  drivers/tty/serial/fsl_lpuart.c | 84 +++++++++++++++++++++------------
>  1 file changed, 53 insertions(+), 31 deletions(-)
> 
> diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
> index c31b8f3db6bf..0b8c477b32a3 100644
> --- a/drivers/tty/serial/fsl_lpuart.c
> +++ b/drivers/tty/serial/fsl_lpuart.c
> @@ -1493,36 +1493,63 @@ static void rx_dma_timer_init(struct lpuart_port *sport)
>  static void lpuart_tx_dma_startup(struct lpuart_port *sport)
>  {
>  	u32 uartbaud;
> +	int ret;
>  
> -	if (sport->dma_tx_chan && !lpuart_dma_tx_request(&sport->port)) {
> -		init_waitqueue_head(&sport->dma_wait);
> -		sport->lpuart_dma_tx_use = true;
> -		if (lpuart_is_32(sport)) {
> -			uartbaud = lpuart32_read(&sport->port, UARTBAUD);
> -			lpuart32_write(&sport->port,
> -				       uartbaud | UARTBAUD_TDMAE, UARTBAUD);
> -		} else {
> -			writeb(readb(sport->port.membase + UARTCR5) |
> -				UARTCR5_TDMAS, sport->port.membase + UARTCR5);
> -		}
> +	sport->dma_tx_chan = dma_request_slave_channel(sport->port.dev, "tx");
> +	if (!sport->dma_tx_chan) {
> +		dev_info_once(sport->port.dev,
> +			      "DMA tx channel request failed, operating without tx DMA\n");

Might be useful to print the errno too.

Rob

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v3 3/9] tty: serial: fsl_lpuart: handle EPROBE_DEFER for DMA
  2020-03-03 18:47   ` Rob Herring
@ 2020-03-03 20:57     ` Michael Walle
  0 siblings, 0 replies; 14+ messages in thread
From: Michael Walle @ 2020-03-03 20:57 UTC (permalink / raw)
  To: Rob Herring
  Cc: linux-serial, devicetree, linux-kernel, linux-arm-kernel,
	Greg Kroah-Hartman, Mark Rutland, Shawn Guo, Li Yang, Jiri Slaby,
	Peng Fan, Vabhav Sharma, Yuan Yao

Am 3. März 2020 19:47:37 MEZ schrieb Rob Herring <robh@kernel.org>:
>On Tue, Mar 03, 2020 at 06:43:00PM +0100, Michael Walle wrote:
>> The DMA channel might not be available at probe time. This is esp.
>the
>> case if the DMA controller has an IOMMU mapping.
>
>The subject should be updated as this doesn't involve deferred probe
>any more. 

ok

>
>> There is also another caveat. If there is no DMA controller at all,
>> dma_request_chan() will also return -EPROBE_DEFER. Thus we cannot
>test
>> for -EPROBE_DEFER in probe(). Otherwise the lpuart driver will fail
>to
>> probe if, for example, the DMA driver is not enabled in the kernel
>> configuration.
>> 
>> To workaround this, we request the DMA channel in _startup(). Other
>> serial drivers do it the same way.
>> 
>> Signed-off-by: Michael Walle <michael@walle.cc>
>> ---
>>  drivers/tty/serial/fsl_lpuart.c | 84
>+++++++++++++++++++++------------
>>  1 file changed, 53 insertions(+), 31 deletions(-)
>> 
>> diff --git a/drivers/tty/serial/fsl_lpuart.c
>b/drivers/tty/serial/fsl_lpuart.c
>> index c31b8f3db6bf..0b8c477b32a3 100644
>> --- a/drivers/tty/serial/fsl_lpuart.c
>> +++ b/drivers/tty/serial/fsl_lpuart.c
>> @@ -1493,36 +1493,63 @@ static void rx_dma_timer_init(struct
>lpuart_port *sport)
>>  static void lpuart_tx_dma_startup(struct lpuart_port *sport)
>>  {
>>  	u32 uartbaud;
>> +	int ret;
>>  
>> -	if (sport->dma_tx_chan && !lpuart_dma_tx_request(&sport->port)) {
>> -		init_waitqueue_head(&sport->dma_wait);
>> -		sport->lpuart_dma_tx_use = true;
>> -		if (lpuart_is_32(sport)) {
>> -			uartbaud = lpuart32_read(&sport->port, UARTBAUD);
>> -			lpuart32_write(&sport->port,
>> -				       uartbaud | UARTBAUD_TDMAE, UARTBAUD);
>> -		} else {
>> -			writeb(readb(sport->port.membase + UARTCR5) |
>> -				UARTCR5_TDMAS, sport->port.membase + UARTCR5);
>> -		}
>> +	sport->dma_tx_chan = dma_request_slave_channel(sport->port.dev,
>"tx");
>> +	if (!sport->dma_tx_chan) {
>> +		dev_info_once(sport->port.dev,
>> +			      "DMA tx channel request failed, operating without tx
>DMA\n");
>
>Might be useful to print the errno too.

I didn't want to change the original error message. But I can change that when I update the subject. 

-michael


^ permalink raw reply	[flat|nested] 14+ messages in thread

* RE: [PATCH v3 8/9] arm64: dts: ls1028a: add "fsl,vf610-edma" compatible
  2020-03-03 17:43 ` [PATCH v3 8/9] arm64: dts: ls1028a: add "fsl,vf610-edma" compatible Michael Walle
@ 2020-03-03 22:43   ` Leo Li
  0 siblings, 0 replies; 14+ messages in thread
From: Leo Li @ 2020-03-03 22:43 UTC (permalink / raw)
  To: Michael Walle, linux-serial, devicetree, linux-kernel, linux-arm-kernel
  Cc: Greg Kroah-Hartman, Rob Herring, Mark Rutland, Shawn Guo,
	Jiri Slaby, Peng Fan, Vabhav Sharma, Yuan Yao



> -----Original Message-----
> From: Michael Walle <michael@walle.cc>
> Sent: Tuesday, March 3, 2020 11:43 AM
> To: linux-serial@vger.kernel.org; devicetree@vger.kernel.org; linux-
> kernel@vger.kernel.org; linux-arm-kernel@lists.infradead.org
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>; Rob Herring
> <robh+dt@kernel.org>; Mark Rutland <mark.rutland@arm.com>; Shawn
> Guo <shawnguo@kernel.org>; Leo Li <leoyang.li@nxp.com>; Jiri Slaby
> <jslaby@suse.com>; Peng Fan <peng.fan@nxp.com>; Vabhav Sharma
> <vabhav.sharma@nxp.com>; Yuan Yao <yao.yuan@nxp.com>; Michael Walle
> <michael@walle.cc>
> Subject: [PATCH v3 8/9] arm64: dts: ls1028a: add "fsl,vf610-edma" compatible
> 
> The bootloader does the IOMMU fixup and dynamically adds the "iommus"
> property to devices according to its compatible string. In case of the eDMA
> controller this property is missing. Add it. After that the IOMMU will work
> with the eDMA core.

It probably makes sense to have the fsl,vf610-edma as a secondary compatible.  But I think it probably need an update to the binding document too(especially the compatible is required to function).  Also looks like the recent update for the binding has a typo for " fsl,fsl,ls1028a-edma", can you also fix that all together?

> 
> Signed-off-by: Michael Walle <michael@walle.cc>
> ---
>  arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
> b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
> index 0bf375ec959b..0843cfbe7ae1 100644
> --- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
> +++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
> @@ -335,7 +335,7 @@
> 
>  		edma0: dma-controller@22c0000 {
>  			#dma-cells = <2>;
> -			compatible = "fsl,ls1028a-edma";
> +			compatible = "fsl,ls1028a-edma", "fsl,vf610-edma";
>  			reg = <0x0 0x22c0000 0x0 0x10000>,
>  			      <0x0 0x22d0000 0x0 0x10000>,
>  			      <0x0 0x22e0000 0x0 0x10000>;
> --
> 2.20.1


^ permalink raw reply	[flat|nested] 14+ messages in thread

* RE: [PATCH v3 0/9] tty: serial: fsl_lpuart various fixes and LS1028A support
  2020-03-03 17:42 [PATCH v3 0/9] tty: serial: fsl_lpuart various fixes and LS1028A support Michael Walle
                   ` (8 preceding siblings ...)
  2020-03-03 17:43 ` [PATCH v3 9/9] arm64: dts: ls1028a: add missing LPUART nodes Michael Walle
@ 2020-03-03 22:49 ` Leo Li
  9 siblings, 0 replies; 14+ messages in thread
From: Leo Li @ 2020-03-03 22:49 UTC (permalink / raw)
  To: Michael Walle, linux-serial, devicetree, linux-kernel, linux-arm-kernel
  Cc: Greg Kroah-Hartman, Rob Herring, Mark Rutland, Shawn Guo,
	Jiri Slaby, Peng Fan, Vabhav Sharma, Yuan Yao



> -----Original Message-----
> From: Michael Walle <michael@walle.cc>
> Sent: Tuesday, March 3, 2020 11:43 AM
> To: linux-serial@vger.kernel.org; devicetree@vger.kernel.org; linux-
> kernel@vger.kernel.org; linux-arm-kernel@lists.infradead.org
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>; Rob Herring
> <robh+dt@kernel.org>; Mark Rutland <mark.rutland@arm.com>; Shawn
> Guo <shawnguo@kernel.org>; Leo Li <leoyang.li@nxp.com>; Jiri Slaby
> <jslaby@suse.com>; Peng Fan <peng.fan@nxp.com>; Vabhav Sharma
> <vabhav.sharma@nxp.com>; Yuan Yao <yao.yuan@nxp.com>; Michael Walle
> <michael@walle.cc>
> Subject: [PATCH v3 0/9] tty: serial: fsl_lpuart various fixes and LS1028A
> support
> 
> These are various fixes for problems I found during development of the
> LS1028A support for the LPUART.
> 
> Also, I'm not sure if this series should be split between the "tty:
> serial: fsl_lpuart" patches and the devicetree patches. So unless someone
> tell me otherwise I keep them together to avoid mention any dependencies.

Normally the soc maintainer prefer to have device tree patches merged through the soc subsystem.  So probably better to separate.

> 
> Changes since v2:
> Changed DMA channel request handling. Spotted by Rob Herring. Thanks.
> 
> Modified patches:
>   tty: serial: fsl_lpuart: handle EPROBE_DEFER for DMA
> 
> Changes since v1:
> DMA support fixes.
> 
> New patches:
>   tty: serial: fsl_lpuart: fix DMA mapping
>   arm64: dts: ls1028a: add "fsl,vf610-edma" compatible
> 
> Modified patches:
>   arm64: dts: ls1028a: add missing LPUART nodes
>    - add dma phandles
> 
> Michael Walle (9):
>   Revert "tty: serial: fsl_lpuart: drop EARLYCON_DECLARE"
>   tty: serial: fsl_lpuart: free IDs allocated by IDA
>   tty: serial: fsl_lpuart: handle EPROBE_DEFER for DMA
>   tty: serial: fsl_lpuart: fix DMA mapping
>   dt-bindings: serial: lpuart: add ls1028a compatibility
>   tty: serial: fsl_lpuart: add LS1028A support
>   tty: serial: fsl_lpuart: add LS1028A earlycon support
>   arm64: dts: ls1028a: add "fsl,vf610-edma" compatible
>   arm64: dts: ls1028a: add missing LPUART nodes
> 
>  .../devicetree/bindings/serial/fsl-lpuart.txt |  10 +-
>   .../arm64/boot/dts/freescale/fsl-ls1028a.dtsi |  75 +++++-
>  drivers/tty/serial/fsl_lpuart.c               | 251 ++++++++++++------
>  3 files changed, 255 insertions(+), 81 deletions(-)
> 
> --
> 2.20.1


^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2020-03-03 22:49 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-03 17:42 [PATCH v3 0/9] tty: serial: fsl_lpuart various fixes and LS1028A support Michael Walle
2020-03-03 17:42 ` [PATCH v3 1/9] Revert "tty: serial: fsl_lpuart: drop EARLYCON_DECLARE" Michael Walle
2020-03-03 17:42 ` [PATCH v3 2/9] tty: serial: fsl_lpuart: free IDs allocated by IDA Michael Walle
2020-03-03 17:43 ` [PATCH v3 3/9] tty: serial: fsl_lpuart: handle EPROBE_DEFER for DMA Michael Walle
2020-03-03 18:47   ` Rob Herring
2020-03-03 20:57     ` Michael Walle
2020-03-03 17:43 ` [PATCH v3 4/9] tty: serial: fsl_lpuart: fix DMA mapping Michael Walle
2020-03-03 17:43 ` [PATCH v3 5/9] dt-bindings: serial: lpuart: add ls1028a compatibility Michael Walle
2020-03-03 17:43 ` [PATCH v3 6/9] tty: serial: fsl_lpuart: add LS1028A support Michael Walle
2020-03-03 17:43 ` [PATCH v3 7/9] tty: serial: fsl_lpuart: add LS1028A earlycon support Michael Walle
2020-03-03 17:43 ` [PATCH v3 8/9] arm64: dts: ls1028a: add "fsl,vf610-edma" compatible Michael Walle
2020-03-03 22:43   ` Leo Li
2020-03-03 17:43 ` [PATCH v3 9/9] arm64: dts: ls1028a: add missing LPUART nodes Michael Walle
2020-03-03 22:49 ` [PATCH v3 0/9] tty: serial: fsl_lpuart various fixes and LS1028A support Leo Li

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).