serial: samsung: check DMA channel capabilities before using DMA mode

Message ID 20180510070048.9035-1-m.szyprowski@samsung.com
State New
Headers show
Series
  • serial: samsung: check DMA channel capabilities before using DMA mode
Related show

Commit Message

Marek Szyprowski May 10, 2018, 7 a.m.
DMA engine driver might not always provide all the features needed by
serial driver to properly operate in DMA mode, so check that before
selecting DMA mode.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>

---
 drivers/tty/serial/samsung.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

-- 
2.17.0

--
To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

Krzysztof Kozlowski May 13, 2018, 9:22 a.m. | #1
On Thu, May 10, 2018 at 09:00:48AM +0200, Marek Szyprowski wrote:
> DMA engine driver might not always provide all the features needed by

> serial driver to properly operate in DMA mode, so check that before

> selecting DMA mode.

> 

> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>

> ---

>  drivers/tty/serial/samsung.c | 15 +++++++++++++++

>  1 file changed, 15 insertions(+)

> 

> diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c

> index 64e96926f1ad..334b53c6eb14 100644

> --- a/drivers/tty/serial/samsung.c

> +++ b/drivers/tty/serial/samsung.c

> @@ -856,6 +856,7 @@ static void s3c24xx_serial_break_ctl(struct uart_port *port, int break_state)

>  static int s3c24xx_serial_request_dma(struct s3c24xx_uart_port *p)

>  {

>  	struct s3c24xx_uart_dma	*dma = p->dma;

> +	struct dma_slave_caps dma_caps;

>  	int ret;

>  

>  	/* Default slave configuration parameters */

> @@ -874,6 +875,13 @@ static int s3c24xx_serial_request_dma(struct s3c24xx_uart_port *p)

>  	if (IS_ERR(dma->rx_chan))

>  		return PTR_ERR(dma->rx_chan);

>  

> +	ret = dma_get_slave_caps(dma->rx_chan, &dma_caps);

> +	if (ret < 0 ||

> +	    dma_caps.residue_granularity < DMA_RESIDUE_GRANULARITY_BURST) {


Let's print here reason of DMA setup failure? Later only generic message
about not using DMA would be shown.

The same in second path.

Best regards,
Krzysztof


> +		ret = -ENODEV;

> +		goto err_release_rx;

> +	}

> +

>  	dmaengine_slave_config(dma->rx_chan, &dma->rx_conf);

>  

>  	dma->tx_chan = dma_request_chan(p->port.dev, "tx");

> @@ -882,6 +890,13 @@ static int s3c24xx_serial_request_dma(struct s3c24xx_uart_port *p)

>  		goto err_release_rx;

>  	}

>  

> +	ret = dma_get_slave_caps(dma->tx_chan, &dma_caps);

> +	if (ret < 0 ||

> +	    dma_caps.residue_granularity < DMA_RESIDUE_GRANULARITY_BURST) {

> +		ret = -ENODEV;

> +		goto err_release_tx;

> +	}

> +

>  	dmaengine_slave_config(dma->tx_chan, &dma->tx_conf);

>  

>  	/* RX buffer */

> -- 

> 2.17.0

> 

--
To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Patch

diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c
index 64e96926f1ad..334b53c6eb14 100644
--- a/drivers/tty/serial/samsung.c
+++ b/drivers/tty/serial/samsung.c
@@ -856,6 +856,7 @@  static void s3c24xx_serial_break_ctl(struct uart_port *port, int break_state)
 static int s3c24xx_serial_request_dma(struct s3c24xx_uart_port *p)
 {
 	struct s3c24xx_uart_dma	*dma = p->dma;
+	struct dma_slave_caps dma_caps;
 	int ret;
 
 	/* Default slave configuration parameters */
@@ -874,6 +875,13 @@  static int s3c24xx_serial_request_dma(struct s3c24xx_uart_port *p)
 	if (IS_ERR(dma->rx_chan))
 		return PTR_ERR(dma->rx_chan);
 
+	ret = dma_get_slave_caps(dma->rx_chan, &dma_caps);
+	if (ret < 0 ||
+	    dma_caps.residue_granularity < DMA_RESIDUE_GRANULARITY_BURST) {
+		ret = -ENODEV;
+		goto err_release_rx;
+	}
+
 	dmaengine_slave_config(dma->rx_chan, &dma->rx_conf);
 
 	dma->tx_chan = dma_request_chan(p->port.dev, "tx");
@@ -882,6 +890,13 @@  static int s3c24xx_serial_request_dma(struct s3c24xx_uart_port *p)
 		goto err_release_rx;
 	}
 
+	ret = dma_get_slave_caps(dma->tx_chan, &dma_caps);
+	if (ret < 0 ||
+	    dma_caps.residue_granularity < DMA_RESIDUE_GRANULARITY_BURST) {
+		ret = -ENODEV;
+		goto err_release_tx;
+	}
+
 	dmaengine_slave_config(dma->tx_chan, &dma->tx_conf);
 
 	/* RX buffer */