[PATCH v5 1/2] serial: fsl_lpuart: Add DMA quirk
Andrew Lunn
andrew at lunn.ch
Mon Apr 4 14:53:11 PDT 2016
Using DMA with the vf610 and other Vybrid devices results in a corrupt
serial stream. Add a quirk to disable the use of DMA.
Refactor the existing code to add a 32 bit access quirk for the
fsl,ls1021a-lpuart.
Signed-off-by: Andrew Lunn <andrew at lunn.ch>
---
drivers/tty/serial/fsl_lpuart.c | 36 ++++++++++++++++++++++++++----------
1 file changed, 26 insertions(+), 10 deletions(-)
diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
index 3d790033744e..8d2f67b93e1f 100644
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -257,12 +257,17 @@ struct lpuart_port {
struct timer_list lpuart_timer;
};
+#define QUIRK_LPUART32 BIT(0)
+#define QUIRK_NO_DMA BIT(1)
+
static const struct of_device_id lpuart_dt_ids[] = {
{
.compatible = "fsl,vf610-lpuart",
+ .data = (void *)QUIRK_NO_DMA,
},
{
.compatible = "fsl,ls1021a-lpuart",
+ .data = (void *)QUIRK_LPUART32,
},
{ /* sentinel */ }
};
@@ -1803,7 +1808,9 @@ static struct uart_driver lpuart_reg = {
static int lpuart_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
+ const struct of_device_id *match;
struct lpuart_port *sport;
+ kernel_ulong_t quirks;
struct resource *res;
int ret;
@@ -1819,7 +1826,10 @@ static int lpuart_probe(struct platform_device *pdev)
return ret;
}
sport->port.line = ret;
- sport->lpuart32 = of_device_is_compatible(np, "fsl,ls1021a-lpuart");
+
+ match = of_match_node(lpuart_dt_ids, np);
+ quirks = (kernel_ulong_t)match->data;
+ sport->lpuart32 = quirks & QUIRK_LPUART32;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
sport->port.membase = devm_ioremap_resource(&pdev->dev, res);
@@ -1867,15 +1877,21 @@ static int lpuart_probe(struct platform_device *pdev)
return ret;
}
- 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");
+ if (quirks & QUIRK_NO_DMA) {
+ dev_info(sport->port.dev, "Not using DMA\n");
+ } else {
+ 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;
}
--
2.7.0
More information about the linux-arm-kernel
mailing list