[PATCH v5 1/2] serial: fsl_lpuart: Add DMA quirk
Stefan Agner
stefan at agner.ch
Mon Apr 4 22:01:12 PDT 2016
On 2016-04-04 14:53, Andrew Lunn wrote:
> 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.
Hi Andrew,
[also added Greg and Jiri, maintainers of the tty subsystem]
Well, I am not sure if that is the right approach. Quirks are usually
used to hint to issues in the hardware. However, in this case we deal
with (a) software issue(s)...
At Toradex we were carry a patch which disabled DMA by default using a
module parameter:
http://git.toradex.com/cgit/linux-toradex.git/commit/?h=toradex_vf_4.4-next&id=f5baad61b77dd4b0ac0c7beeee284e12d49ba442
This allowed to re-enable the DMA easily for testing... Not sure if that
is the better approach.
However, we are working on a re-implementation of the DMA modes, I hope
we can post some patches soon.
IMHO we can just omit adding such a disable work around, people lived
with the current situation since 3.13, one more release probably doesn't
really matter... :-)
--
Stefan
>
> 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;
> }
More information about the linux-arm-kernel
mailing list