linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/9] tty: serial: fsl_lpuart various fixes and LS1028A support
@ 2020-02-21 17:47 Michael Walle
  2020-02-21 17:47 ` [PATCH v2 1/9] Revert "tty: serial: fsl_lpuart: drop EARLYCON_DECLARE" Michael Walle
                   ` (8 more replies)
  0 siblings, 9 replies; 17+ messages in thread
From: Michael Walle @ 2020-02-21 17:47 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, Michael Walle

These are various fixes for problems I found during development of the
LS1028A support for the LPUART. Sorry for the quick v2, but I didn't
thought I could fix the DMA issue that fast.

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 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               | 201 +++++++++++++-----
 3 files changed, 226 insertions(+), 60 deletions(-)

-- 
2.20.1


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

* [PATCH v2 1/9] Revert "tty: serial: fsl_lpuart: drop EARLYCON_DECLARE"
  2020-02-21 17:47 [PATCH v2 0/9] tty: serial: fsl_lpuart various fixes and LS1028A support Michael Walle
@ 2020-02-21 17:47 ` Michael Walle
  2020-02-21 17:47 ` [PATCH v2 2/9] tty: serial: fsl_lpuart: free IDs allocated by IDA Michael Walle
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 17+ messages in thread
From: Michael Walle @ 2020-02-21 17:47 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, 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] 17+ messages in thread

* [PATCH v2 2/9] tty: serial: fsl_lpuart: free IDs allocated by IDA
  2020-02-21 17:47 [PATCH v2 0/9] tty: serial: fsl_lpuart various fixes and LS1028A support Michael Walle
  2020-02-21 17:47 ` [PATCH v2 1/9] Revert "tty: serial: fsl_lpuart: drop EARLYCON_DECLARE" Michael Walle
@ 2020-02-21 17:47 ` Michael Walle
  2020-02-21 17:47 ` [PATCH v2 3/9] tty: serial: fsl_lpuart: handle EPROBE_DEFER for DMA Michael Walle
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 17+ messages in thread
From: Michael Walle @ 2020-02-21 17:47 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, 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] 17+ messages in thread

* [PATCH v2 3/9] tty: serial: fsl_lpuart: handle EPROBE_DEFER for DMA
  2020-02-21 17:47 [PATCH v2 0/9] tty: serial: fsl_lpuart various fixes and LS1028A support Michael Walle
  2020-02-21 17:47 ` [PATCH v2 1/9] Revert "tty: serial: fsl_lpuart: drop EARLYCON_DECLARE" Michael Walle
  2020-02-21 17:47 ` [PATCH v2 2/9] tty: serial: fsl_lpuart: free IDs allocated by IDA Michael Walle
@ 2020-02-21 17:47 ` Michael Walle
  2020-02-27 22:34   ` Rob Herring
  2020-02-21 17:47 ` [PATCH v2 4/9] tty: serial: fsl_lpuart: fix DMA mapping Michael Walle
                   ` (5 subsequent siblings)
  8 siblings, 1 reply; 17+ messages in thread
From: Michael Walle @ 2020-02-21 17:47 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, Michael Walle

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

Use the new dma_request_chan() API and handle EPROBE_DEFER errors. Also
reorder the code a bit, so that we don't prepare the whole UART just to
determine that the DMA channel is not ready yet and we have to undo all
the stuff. Try to map the DMA channels earlier.

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

diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
index c31b8f3db6bf..fd9f60d0817a 100644
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -2416,6 +2416,7 @@ static int lpuart_probe(struct platform_device *pdev)
 	const struct lpuart_soc_data *sdata = of_id->data;
 	struct device_node *np = pdev->dev.of_node;
 	struct lpuart_port *sport;
+	struct dma_chan *dma_chan;
 	struct resource *res;
 	int ret;
 
@@ -2483,6 +2484,26 @@ static int lpuart_probe(struct platform_device *pdev)
 	}
 	sport->port.line = ret;
 
+	dma_chan = dma_request_chan(sport->port.dev, "tx");
+	if (PTR_ERR(dma_chan) == -EPROBE_DEFER) {
+		ret = -EPROBE_DEFER;
+		goto failed_request_tx_dma;
+	} else if (IS_ERR(dma_chan))
+		dev_info(sport->port.dev, "DMA tx channel request failed, "
+				"operating without tx DMA\n");
+	else
+		sport->dma_tx_chan = dma_chan;
+
+	dma_chan = dma_request_chan(sport->port.dev, "rx");
+	if (PTR_ERR(dma_chan) == -EPROBE_DEFER) {
+		ret = -EPROBE_DEFER;
+		goto failed_request_rx_dma;
+	} else if (IS_ERR(dma_chan))
+		dev_info(sport->port.dev, "DMA rx channel request failed, "
+				"operating without rx DMA\n");
+	else
+		sport->dma_rx_chan = dma_chan;
+
 	ret = lpuart_enable_clks(sport);
 	if (ret)
 		goto failed_clock_enable;
@@ -2520,22 +2541,16 @@ 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:
 failed_irq_request:
 	lpuart_disable_clks(sport);
 failed_clock_enable:
+	dma_release_channel(sport->dma_rx_chan);
+failed_request_rx_dma:
+	dma_release_channel(sport->dma_tx_chan);
+failed_request_tx_dma:
 failed_out_of_range:
 	if (sport->id_allocated)
 		ida_simple_remove(&fsl_lpuart_ida, sport->port.line);
-- 
2.20.1


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

* [PATCH v2 4/9] tty: serial: fsl_lpuart: fix DMA mapping
  2020-02-21 17:47 [PATCH v2 0/9] tty: serial: fsl_lpuart various fixes and LS1028A support Michael Walle
                   ` (2 preceding siblings ...)
  2020-02-21 17:47 ` [PATCH v2 3/9] tty: serial: fsl_lpuart: handle EPROBE_DEFER for DMA Michael Walle
@ 2020-02-21 17:47 ` Michael Walle
  2020-02-21 17:47 ` [PATCH v2 5/9] dt-bindings: serial: lpuart: add ls1028a compatibility Michael Walle
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 17+ messages in thread
From: Michael Walle @ 2020-02-21 17:47 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, 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 | 47 +++++++++++++++++++--------------
 1 file changed, 27 insertions(+), 20 deletions(-)

diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
index fd9f60d0817a..b65db29a1cd0 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,18 @@ 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 +448,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 +461,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 +533,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 +998,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 +1059,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 +1067,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 +1110,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 +1142,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 +1164,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 +1176,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 +1184,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 +1198,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 +1216,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] 17+ messages in thread

* [PATCH v2 5/9] dt-bindings: serial: lpuart: add ls1028a compatibility
  2020-02-21 17:47 [PATCH v2 0/9] tty: serial: fsl_lpuart various fixes and LS1028A support Michael Walle
                   ` (3 preceding siblings ...)
  2020-02-21 17:47 ` [PATCH v2 4/9] tty: serial: fsl_lpuart: fix DMA mapping Michael Walle
@ 2020-02-21 17:47 ` Michael Walle
  2020-02-26 21:37   ` Rob Herring
  2020-02-21 17:47 ` [PATCH v2 6/9] tty: serial: fsl_lpuart: add LS1028A support Michael Walle
                   ` (3 subsequent siblings)
  8 siblings, 1 reply; 17+ messages in thread
From: Michael Walle @ 2020-02-21 17:47 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, Michael Walle

Signed-off-by: Michael Walle <michael@walle.cc>
---
 .../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] 17+ messages in thread

* [PATCH v2 6/9] tty: serial: fsl_lpuart: add LS1028A support
  2020-02-21 17:47 [PATCH v2 0/9] tty: serial: fsl_lpuart various fixes and LS1028A support Michael Walle
                   ` (4 preceding siblings ...)
  2020-02-21 17:47 ` [PATCH v2 5/9] dt-bindings: serial: lpuart: add ls1028a compatibility Michael Walle
@ 2020-02-21 17:47 ` Michael Walle
  2020-02-21 17:47 ` [PATCH v2 7/9] tty: serial: fsl_lpuart: add LS1028A earlycon support Michael Walle
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 17+ messages in thread
From: Michael Walle @ 2020-02-21 17:47 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, 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 b65db29a1cd0..d5a67e02f06a 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;
@@ -1596,6 +1608,17 @@ static int lpuart32_startup(struct uart_port *port)
 
 	spin_lock_irqsave(&sport->port.lock, flags);
 
+	/*
+	 * 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;
+	}
+
 	lpuart32_setup_watermark_enable(sport);
 
 
-- 
2.20.1


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

* [PATCH v2 7/9] tty: serial: fsl_lpuart: add LS1028A earlycon support
  2020-02-21 17:47 [PATCH v2 0/9] tty: serial: fsl_lpuart various fixes and LS1028A support Michael Walle
                   ` (5 preceding siblings ...)
  2020-02-21 17:47 ` [PATCH v2 6/9] tty: serial: fsl_lpuart: add LS1028A support Michael Walle
@ 2020-02-21 17:47 ` Michael Walle
  2020-02-21 17:47 ` [PATCH v2 8/9] arm64: dts: ls1028a: add "fsl,vf610-edma" compatible Michael Walle
  2020-02-21 17:47 ` [PATCH v2 9/9] arm64: dts: ls1028a: add missing LPUART nodes Michael Walle
  8 siblings, 0 replies; 17+ messages in thread
From: Michael Walle @ 2020-02-21 17:47 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, 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 d5a67e02f06a..e8e5c60e5b71 100644
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -1841,11 +1841,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.
@@ -1891,10 +1892,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;
@@ -1905,14 +1906,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)
@@ -2406,6 +2416,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)
 {
@@ -2420,6 +2454,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] 17+ messages in thread

* [PATCH v2 8/9] arm64: dts: ls1028a: add "fsl,vf610-edma" compatible
  2020-02-21 17:47 [PATCH v2 0/9] tty: serial: fsl_lpuart various fixes and LS1028A support Michael Walle
                   ` (6 preceding siblings ...)
  2020-02-21 17:47 ` [PATCH v2 7/9] tty: serial: fsl_lpuart: add LS1028A earlycon support Michael Walle
@ 2020-02-21 17:47 ` Michael Walle
  2020-02-21 17:47 ` [PATCH v2 9/9] arm64: dts: ls1028a: add missing LPUART nodes Michael Walle
  8 siblings, 0 replies; 17+ messages in thread
From: Michael Walle @ 2020-02-21 17:47 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, 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 40d82c49b174..f1909fee391d 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
@@ -392,7 +392,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] 17+ messages in thread

* [PATCH v2 9/9] arm64: dts: ls1028a: add missing LPUART nodes
  2020-02-21 17:47 [PATCH v2 0/9] tty: serial: fsl_lpuart various fixes and LS1028A support Michael Walle
                   ` (7 preceding siblings ...)
  2020-02-21 17:47 ` [PATCH v2 8/9] arm64: dts: ls1028a: add "fsl,vf610-edma" compatible Michael Walle
@ 2020-02-21 17:47 ` Michael Walle
  8 siblings, 0 replies; 17+ messages in thread
From: Michael Walle @ 2020-02-21 17:47 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, 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 f1909fee391d..3ece3f8446d3 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
@@ -390,6 +390,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] 17+ messages in thread

* Re: [PATCH v2 5/9] dt-bindings: serial: lpuart: add ls1028a compatibility
  2020-02-21 17:47 ` [PATCH v2 5/9] dt-bindings: serial: lpuart: add ls1028a compatibility Michael Walle
@ 2020-02-26 21:37   ` Rob Herring
  0 siblings, 0 replies; 17+ messages in thread
From: Rob Herring @ 2020-02-26 21:37 UTC (permalink / raw)
  To: Michael Walle
  Cc: linux-serial, devicetree, linux-kernel, linux-arm-kernel,
	Greg Kroah-Hartman, Li Yang, Jiri Slaby, Peng Fan, Vabhav Sharma,
	Michael Walle

On Fri, 21 Feb 2020 18:47:50 +0100, Michael Walle wrote:
> Signed-off-by: Michael Walle <michael@walle.cc>
> ---
>  .../devicetree/bindings/serial/fsl-lpuart.txt          | 10 ++++++----
>  1 file changed, 6 insertions(+), 4 deletions(-)
> 

Reviewed-by: Rob Herring <robh@kernel.org>

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

* Re: [PATCH v2 3/9] tty: serial: fsl_lpuart: handle EPROBE_DEFER for DMA
  2020-02-21 17:47 ` [PATCH v2 3/9] tty: serial: fsl_lpuart: handle EPROBE_DEFER for DMA Michael Walle
@ 2020-02-27 22:34   ` Rob Herring
  2020-02-27 22:48     ` Li Yang
  0 siblings, 1 reply; 17+ messages in thread
From: Rob Herring @ 2020-02-27 22:34 UTC (permalink / raw)
  To: Michael Walle
  Cc: open list:SERIAL DRIVERS, devicetree, linux-kernel,
	moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
	Greg Kroah-Hartman, Mark Rutland, Shawn Guo, Li Yang, Jiri Slaby,
	Peng Fan, Vabhav Sharma

On Fri, Feb 21, 2020 at 11:48 AM Michael Walle <michael@walle.cc> wrote:
>
> The DMA channel might not be available at the first probe time. This is
> esp. the case if the DMA controller has an IOMMU mapping.
>
> Use the new dma_request_chan() API and handle EPROBE_DEFER errors. Also
> reorder the code a bit, so that we don't prepare the whole UART just to
> determine that the DMA channel is not ready yet and we have to undo all
> the stuff. Try to map the DMA channels earlier.

Changing this means you never probe successfully if you boot a kernel
with the DMA driver disabled (or it's IOMMU disabled). Some other
drivers request DMA in open() and can work either way.

Rob

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

* Re: [PATCH v2 3/9] tty: serial: fsl_lpuart: handle EPROBE_DEFER for DMA
  2020-02-27 22:34   ` Rob Herring
@ 2020-02-27 22:48     ` Li Yang
  2020-02-27 23:03       ` Rob Herring
  0 siblings, 1 reply; 17+ messages in thread
From: Li Yang @ 2020-02-27 22:48 UTC (permalink / raw)
  To: Rob Herring
  Cc: Michael Walle, open list:SERIAL DRIVERS,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-kernel,
	moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
	Greg Kroah-Hartman, Mark Rutland, Shawn Guo, Jiri Slaby,
	Peng Fan, Vabhav Sharma

On Thu, Feb 27, 2020 at 4:35 PM Rob Herring <robh+dt@kernel.org> wrote:
>
> On Fri, Feb 21, 2020 at 11:48 AM Michael Walle <michael@walle.cc> wrote:
> >
> > The DMA channel might not be available at the first probe time. This is
> > esp. the case if the DMA controller has an IOMMU mapping.
> >
> > Use the new dma_request_chan() API and handle EPROBE_DEFER errors. Also
> > reorder the code a bit, so that we don't prepare the whole UART just to
> > determine that the DMA channel is not ready yet and we have to undo all
> > the stuff. Try to map the DMA channels earlier.
>
> Changing this means you never probe successfully if you boot a kernel
> with the DMA driver disabled (or it's IOMMU disabled). Some other
> drivers request DMA in open() and can work either way.

We got this exact issue previously with another driver.  When the
required DMA driver is disabled, the DMA framework cannot figure out
this situation and keeps returning EPROBE_DEFER.  I'm wondering if we
should update the DMA framework to use your deferred probe timeout
mechanism.  Is it still only used for debug purpose?

Regards,
Leo

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

* Re: [PATCH v2 3/9] tty: serial: fsl_lpuart: handle EPROBE_DEFER for DMA
  2020-02-27 22:48     ` Li Yang
@ 2020-02-27 23:03       ` Rob Herring
  2020-02-28 11:46         ` Michael Walle
  0 siblings, 1 reply; 17+ messages in thread
From: Rob Herring @ 2020-02-27 23:03 UTC (permalink / raw)
  To: Li Yang
  Cc: Michael Walle, open list:SERIAL DRIVERS,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-kernel,
	moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
	Greg Kroah-Hartman, Mark Rutland, Shawn Guo, Jiri Slaby,
	Peng Fan, Vabhav Sharma

On Thu, Feb 27, 2020 at 4:49 PM Li Yang <leoyang.li@nxp.com> wrote:
>
> On Thu, Feb 27, 2020 at 4:35 PM Rob Herring <robh+dt@kernel.org> wrote:
> >
> > On Fri, Feb 21, 2020 at 11:48 AM Michael Walle <michael@walle.cc> wrote:
> > >
> > > The DMA channel might not be available at the first probe time. This is
> > > esp. the case if the DMA controller has an IOMMU mapping.
> > >
> > > Use the new dma_request_chan() API and handle EPROBE_DEFER errors. Also
> > > reorder the code a bit, so that we don't prepare the whole UART just to
> > > determine that the DMA channel is not ready yet and we have to undo all
> > > the stuff. Try to map the DMA channels earlier.
> >
> > Changing this means you never probe successfully if you boot a kernel
> > with the DMA driver disabled (or it's IOMMU disabled). Some other
> > drivers request DMA in open() and can work either way.
>
> We got this exact issue previously with another driver.  When the
> required DMA driver is disabled, the DMA framework cannot figure out
> this situation and keeps returning EPROBE_DEFER.  I'm wondering if we
> should update the DMA framework to use your deferred probe timeout
> mechanism.  Is it still only used for debug purpose?

It's undergoing some rework ATM to not just be for debug. However,
it's not really going to help you if you care about the console
because waiting for the timeout will be too late to register the
console.

Rob

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

* Re: [PATCH v2 3/9] tty: serial: fsl_lpuart: handle EPROBE_DEFER for DMA
  2020-02-27 23:03       ` Rob Herring
@ 2020-02-28 11:46         ` Michael Walle
  2020-02-28 21:50           ` Michael Walle
  0 siblings, 1 reply; 17+ messages in thread
From: Michael Walle @ 2020-02-28 11:46 UTC (permalink / raw)
  To: Rob Herring
  Cc: Li Yang, open list:SERIAL DRIVERS,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-kernel,
	moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
	Greg Kroah-Hartman, Mark Rutland, Shawn Guo, Jiri Slaby,
	Peng Fan, Vabhav Sharma

Hi Rob, Hi Leo,

Am 2020-02-28 00:03, schrieb Rob Herring:
> On Thu, Feb 27, 2020 at 4:49 PM Li Yang <leoyang.li@nxp.com> wrote:
>> 
>> On Thu, Feb 27, 2020 at 4:35 PM Rob Herring <robh+dt@kernel.org> 
>> wrote:
>> >
>> > On Fri, Feb 21, 2020 at 11:48 AM Michael Walle <michael@walle.cc> wrote:
>> > >
>> > > The DMA channel might not be available at the first probe time. This is
>> > > esp. the case if the DMA controller has an IOMMU mapping.
>> > >
>> > > Use the new dma_request_chan() API and handle EPROBE_DEFER errors. Also
>> > > reorder the code a bit, so that we don't prepare the whole UART just to
>> > > determine that the DMA channel is not ready yet and we have to undo all
>> > > the stuff. Try to map the DMA channels earlier.
>> >
>> > Changing this means you never probe successfully if you boot a kernel
>> > with the DMA driver disabled (or it's IOMMU disabled). Some other
>> > drivers request DMA in open() and can work either way.

Oh, I see.

>> We got this exact issue previously with another driver.  When the

What driver is it? I've been working on the i2c-mxs.c driver which has
the same problem. Ie. its not working with DMA when the IOMMU is 
enabled.
Now that I've learned that dma_request_chan() will return EPROBE_DEFER
if the actual DMA driver is not available, I don't think there is any
trick like this there. There is no function which would be called late
except you'd do something like on the first master_xfer() try to request
the DMA channels. But I don't think that would be the way to go.

-michael

>> required DMA driver is disabled, the DMA framework cannot figure out
>> this situation and keeps returning EPROBE_DEFER.  I'm wondering if we
>> should update the DMA framework to use your deferred probe timeout
>> mechanism.  Is it still only used for debug purpose?
> 
> It's undergoing some rework ATM to not just be for debug. However,
> it's not really going to help you if you care about the console
> because waiting for the timeout will be too late to register the
> console.


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

* Re: [PATCH v2 3/9] tty: serial: fsl_lpuart: handle EPROBE_DEFER for DMA
  2020-02-28 11:46         ` Michael Walle
@ 2020-02-28 21:50           ` Michael Walle
  2020-02-28 21:53             ` Li Yang
  0 siblings, 1 reply; 17+ messages in thread
From: Michael Walle @ 2020-02-28 21:50 UTC (permalink / raw)
  To: Rob Herring
  Cc: Li Yang, open list:SERIAL DRIVERS,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-kernel,
	moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
	Greg Kroah-Hartman, Mark Rutland, Shawn Guo, Jiri Slaby,
	Peng Fan, Vabhav Sharma

Am 2020-02-28 12:46, schrieb Michael Walle:
> Hi Rob, Hi Leo,
> 
> Am 2020-02-28 00:03, schrieb Rob Herring:
>> On Thu, Feb 27, 2020 at 4:49 PM Li Yang <leoyang.li@nxp.com> wrote:
>>> 
>>> On Thu, Feb 27, 2020 at 4:35 PM Rob Herring <robh+dt@kernel.org> 
>>> wrote:
>>> >
>>> > On Fri, Feb 21, 2020 at 11:48 AM Michael Walle <michael@walle.cc> wrote:
>>> > >
>>> > > The DMA channel might not be available at the first probe time. This is
>>> > > esp. the case if the DMA controller has an IOMMU mapping.
>>> > >
>>> > > Use the new dma_request_chan() API and handle EPROBE_DEFER errors. Also
>>> > > reorder the code a bit, so that we don't prepare the whole UART just to
>>> > > determine that the DMA channel is not ready yet and we have to undo all
>>> > > the stuff. Try to map the DMA channels earlier.
>>> >
>>> > Changing this means you never probe successfully if you boot a kernel
>>> > with the DMA driver disabled (or it's IOMMU disabled). Some other
>>> > drivers request DMA in open() and can work either way.
> 
> Oh, I see.
> 
>>> We got this exact issue previously with another driver.  When the
> 
> What driver is it? I've been working on the i2c-mxs.c driver which has

whoops, i2c-imx.c, not i2c-mxs.c

-michael

> the same problem. Ie. its not working with DMA when the IOMMU is 
> enabled.
> Now that I've learned that dma_request_chan() will return EPROBE_DEFER
> if the actual DMA driver is not available, I don't think there is any
> trick like this there. There is no function which would be called late
> except you'd do something like on the first master_xfer() try to 
> request
> the DMA channels. But I don't think that would be the way to go.
> 
> -michael
> 
>>> required DMA driver is disabled, the DMA framework cannot figure out
>>> this situation and keeps returning EPROBE_DEFER.  I'm wondering if we
>>> should update the DMA framework to use your deferred probe timeout
>>> mechanism.  Is it still only used for debug purpose?
>> 
>> It's undergoing some rework ATM to not just be for debug. However,
>> it's not really going to help you if you care about the console
>> because waiting for the timeout will be too late to register the
>> console.

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

* Re: [PATCH v2 3/9] tty: serial: fsl_lpuart: handle EPROBE_DEFER for DMA
  2020-02-28 21:50           ` Michael Walle
@ 2020-02-28 21:53             ` Li Yang
  0 siblings, 0 replies; 17+ messages in thread
From: Li Yang @ 2020-02-28 21:53 UTC (permalink / raw)
  To: Michael Walle
  Cc: Rob Herring, open list:SERIAL DRIVERS,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS, lkml,
	moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
	Greg Kroah-Hartman, Mark Rutland, Shawn Guo, Jiri Slaby,
	Peng Fan, Vabhav Sharma

On Fri, Feb 28, 2020 at 3:51 PM Michael Walle <michael@walle.cc> wrote:
>
> Am 2020-02-28 12:46, schrieb Michael Walle:
> > Hi Rob, Hi Leo,
> >
> > Am 2020-02-28 00:03, schrieb Rob Herring:
> >> On Thu, Feb 27, 2020 at 4:49 PM Li Yang <leoyang.li@nxp.com> wrote:
> >>>
> >>> On Thu, Feb 27, 2020 at 4:35 PM Rob Herring <robh+dt@kernel.org>
> >>> wrote:
> >>> >
> >>> > On Fri, Feb 21, 2020 at 11:48 AM Michael Walle <michael@walle.cc> wrote:
> >>> > >
> >>> > > The DMA channel might not be available at the first probe time. This is
> >>> > > esp. the case if the DMA controller has an IOMMU mapping.
> >>> > >
> >>> > > Use the new dma_request_chan() API and handle EPROBE_DEFER errors. Also
> >>> > > reorder the code a bit, so that we don't prepare the whole UART just to
> >>> > > determine that the DMA channel is not ready yet and we have to undo all
> >>> > > the stuff. Try to map the DMA channels earlier.
> >>> >
> >>> > Changing this means you never probe successfully if you boot a kernel
> >>> > with the DMA driver disabled (or it's IOMMU disabled). Some other
> >>> > drivers request DMA in open() and can work either way.
> >
> > Oh, I see.
> >
> >>> We got this exact issue previously with another driver.  When the
> >
> > What driver is it? I've been working on the i2c-mxs.c driver which has
>
> whoops, i2c-imx.c, not i2c-mxs.c

Ya.  Same one.  I have added CONFIG_FSL_EDMA into the arm64/defconfig
as a workaround.

Regards,
Leo

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

end of thread, other threads:[~2020-02-28 21:54 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-02-21 17:47 [PATCH v2 0/9] tty: serial: fsl_lpuart various fixes and LS1028A support Michael Walle
2020-02-21 17:47 ` [PATCH v2 1/9] Revert "tty: serial: fsl_lpuart: drop EARLYCON_DECLARE" Michael Walle
2020-02-21 17:47 ` [PATCH v2 2/9] tty: serial: fsl_lpuart: free IDs allocated by IDA Michael Walle
2020-02-21 17:47 ` [PATCH v2 3/9] tty: serial: fsl_lpuart: handle EPROBE_DEFER for DMA Michael Walle
2020-02-27 22:34   ` Rob Herring
2020-02-27 22:48     ` Li Yang
2020-02-27 23:03       ` Rob Herring
2020-02-28 11:46         ` Michael Walle
2020-02-28 21:50           ` Michael Walle
2020-02-28 21:53             ` Li Yang
2020-02-21 17:47 ` [PATCH v2 4/9] tty: serial: fsl_lpuart: fix DMA mapping Michael Walle
2020-02-21 17:47 ` [PATCH v2 5/9] dt-bindings: serial: lpuart: add ls1028a compatibility Michael Walle
2020-02-26 21:37   ` Rob Herring
2020-02-21 17:47 ` [PATCH v2 6/9] tty: serial: fsl_lpuart: add LS1028A support Michael Walle
2020-02-21 17:47 ` [PATCH v2 7/9] tty: serial: fsl_lpuart: add LS1028A earlycon support Michael Walle
2020-02-21 17:47 ` [PATCH v2 8/9] arm64: dts: ls1028a: add "fsl,vf610-edma" compatible Michael Walle
2020-02-21 17:47 ` [PATCH v2 9/9] arm64: dts: ls1028a: add missing LPUART nodes Michael Walle

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).