diff mbox series

i2c: imx: Only DMA messages with I2C_M_DMA_SAFE flag set

Message ID 20221109235902.468723-1-andrew@lunn.ch
State New
Headers show
Series i2c: imx: Only DMA messages with I2C_M_DMA_SAFE flag set | expand

Commit Message

Andrew Lunn Nov. 9, 2022, 11:59 p.m. UTC
Recent changes to the DMA code has resulting in the IMX driver failing
I2C transfers when the buffer has been vmalloc. Only perform DMA
transfers if the message has the I2C_M_DMA_SAFE flag set, indicating
the client is providing a buffer which is DMA safe.

This is a minimal fix for stable. The I2C core provides helpers to
allocate a bounce buffer. For a fuller fix the master should make use
of these helpers.

Fixes: 4544b9f25e70 ("dma-mapping: Add vmap checks to dma_map_single()")
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 drivers/i2c/busses/i2c-imx.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

Comments

Oleksij Rempel Nov. 16, 2022, 9:02 a.m. UTC | #1
On Thu, Nov 10, 2022 at 12:59:02AM +0100, Andrew Lunn wrote:
> Recent changes to the DMA code has resulting in the IMX driver failing
> I2C transfers when the buffer has been vmalloc. Only perform DMA
> transfers if the message has the I2C_M_DMA_SAFE flag set, indicating
> the client is providing a buffer which is DMA safe.
> 
> This is a minimal fix for stable. The I2C core provides helpers to
> allocate a bounce buffer. For a fuller fix the master should make use
> of these helpers.
> 
> Fixes: 4544b9f25e70 ("dma-mapping: Add vmap checks to dma_map_single()")
> Signed-off-by: Andrew Lunn <andrew@lunn.ch>

Acked-by: Oleksij Rempel <o.rempel@pengutronix.de>

> ---
>  drivers/i2c/busses/i2c-imx.c | 6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
> index 3082183bd66a..fc70920c4dda 100644
> --- a/drivers/i2c/busses/i2c-imx.c
> +++ b/drivers/i2c/busses/i2c-imx.c
> @@ -1132,7 +1132,8 @@ static int i2c_imx_read(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs,
>  	int i, result;
>  	unsigned int temp;
>  	int block_data = msgs->flags & I2C_M_RECV_LEN;
> -	int use_dma = i2c_imx->dma && msgs->len >= DMA_THRESHOLD && !block_data;
> +	int use_dma = i2c_imx->dma && msgs->flags & I2C_M_DMA_SAFE &&
> +		msgs->len >= DMA_THRESHOLD && !block_data;
>  
>  	dev_dbg(&i2c_imx->adapter.dev,
>  		"<%s> write slave address: addr=0x%x\n",
> @@ -1298,7 +1299,8 @@ static int i2c_imx_xfer_common(struct i2c_adapter *adapter,
>  			result = i2c_imx_read(i2c_imx, &msgs[i], is_lastmsg, atomic);
>  		} else {
>  			if (!atomic &&
> -			    i2c_imx->dma && msgs[i].len >= DMA_THRESHOLD)
> +			    i2c_imx->dma && msgs[i].len >= DMA_THRESHOLD &&
> +				msgs[i].flags & I2C_M_DMA_SAFE)
>  				result = i2c_imx_dma_write(i2c_imx, &msgs[i]);
>  			else
>  				result = i2c_imx_write(i2c_imx, &msgs[i], atomic);
> -- 
> 2.37.2
> 
>
Wolfram Sang Dec. 1, 2022, 11:12 p.m. UTC | #2
On Thu, Nov 10, 2022 at 12:59:02AM +0100, Andrew Lunn wrote:
> Recent changes to the DMA code has resulting in the IMX driver failing
> I2C transfers when the buffer has been vmalloc. Only perform DMA
> transfers if the message has the I2C_M_DMA_SAFE flag set, indicating
> the client is providing a buffer which is DMA safe.
> 
> This is a minimal fix for stable. The I2C core provides helpers to
> allocate a bounce buffer. For a fuller fix the master should make use
> of these helpers.
> 
> Fixes: 4544b9f25e70 ("dma-mapping: Add vmap checks to dma_map_single()")
> Signed-off-by: Andrew Lunn <andrew@lunn.ch>

Applied to for-current, thanks!
diff mbox series

Patch

diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
index 3082183bd66a..fc70920c4dda 100644
--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -1132,7 +1132,8 @@  static int i2c_imx_read(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs,
 	int i, result;
 	unsigned int temp;
 	int block_data = msgs->flags & I2C_M_RECV_LEN;
-	int use_dma = i2c_imx->dma && msgs->len >= DMA_THRESHOLD && !block_data;
+	int use_dma = i2c_imx->dma && msgs->flags & I2C_M_DMA_SAFE &&
+		msgs->len >= DMA_THRESHOLD && !block_data;
 
 	dev_dbg(&i2c_imx->adapter.dev,
 		"<%s> write slave address: addr=0x%x\n",
@@ -1298,7 +1299,8 @@  static int i2c_imx_xfer_common(struct i2c_adapter *adapter,
 			result = i2c_imx_read(i2c_imx, &msgs[i], is_lastmsg, atomic);
 		} else {
 			if (!atomic &&
-			    i2c_imx->dma && msgs[i].len >= DMA_THRESHOLD)
+			    i2c_imx->dma && msgs[i].len >= DMA_THRESHOLD &&
+				msgs[i].flags & I2C_M_DMA_SAFE)
 				result = i2c_imx_dma_write(i2c_imx, &msgs[i]);
 			else
 				result = i2c_imx_write(i2c_imx, &msgs[i], atomic);