* [PATCH v4 0/3] Fix STM32 I2C dma operations
@ 2025-07-04 8:39 Clément Le Goffic
2025-07-04 8:39 ` [PATCH v4 1/3] i2c: stm32: fix the device used for the DMA map Clément Le Goffic
` (4 more replies)
0 siblings, 5 replies; 6+ messages in thread
From: Clément Le Goffic @ 2025-07-04 8:39 UTC (permalink / raw)
To: Pierre-Yves MORDRET, Alain Volmat, Andi Shyti, Maxime Coquelin,
Alexandre Torgue, Sumit Semwal, Christian König,
M'boumba Cedric Madianga, Wolfram Sang
Cc: Pierre-Yves MORDRET, linux-i2c, linux-stm32, linux-arm-kernel,
linux-kernel, linux-media, dri-devel, linaro-mm-sig,
Clément Le Goffic
This patch series aims to fix some issues inside the driver's DMA
handling.
It also uses newer I2C DMA API.
Signed-off-by: Clément Le Goffic <clement.legoffic@foss.st.com>
---
Changes in v4:
- Patch[1]: Remove all `chan_dev` variable occurrencies
- Patch[2]:
- Refine commit message
- Use the dma_callback to factorize the code
- Patch[3]: Refine commit message
- Link to v3: https://lore.kernel.org/r/20250630-i2c-upstream-v3-0-7a23ab26683a@foss.st.com
Changes in v3:
- Add Alain Volmat's "Acked-by" on patch 1 and 2
- Link to v2: https://lore.kernel.org/r/20250627-i2c-upstream-v2-0-8c14523481dc@foss.st.com
Changes in v2:
- Fix the dev used in dma_unmap also in the error path of
`stm32_i2c_prep_dma_xfer`
- Add a dma_unmap_single also in the ITs error handler
- Add Alain Volmat's "Acked-by" on patch 3
- Link to v1: https://lore.kernel.org/r/20250616-i2c-upstream-v1-0-42d3d5374e65@foss.st.com
---
Clément Le Goffic (3):
i2c: stm32: fix the device used for the DMA map
i2c: stm32f7: unmap DMA mapped buffer
i2c: stm32f7: support i2c_*_dma_safe_msg_buf APIs
drivers/i2c/busses/i2c-stm32.c | 8 +++---
drivers/i2c/busses/i2c-stm32f7.c | 56 +++++++++++++++++++++-------------------
2 files changed, 33 insertions(+), 31 deletions(-)
---
base-commit: d0b3b7b22dfa1f4b515fd3a295b3fd958f9e81af
change-id: 20250527-i2c-upstream-e5b69501359a
Best regards,
--
Clément Le Goffic <clement.legoffic@foss.st.com>
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v4 1/3] i2c: stm32: fix the device used for the DMA map
2025-07-04 8:39 [PATCH v4 0/3] Fix STM32 I2C dma operations Clément Le Goffic
@ 2025-07-04 8:39 ` Clément Le Goffic
2025-07-04 8:39 ` [PATCH v4 2/3] i2c: stm32f7: unmap DMA mapped buffer Clément Le Goffic
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Clément Le Goffic @ 2025-07-04 8:39 UTC (permalink / raw)
To: Pierre-Yves MORDRET, Alain Volmat, Andi Shyti, Maxime Coquelin,
Alexandre Torgue, Sumit Semwal, Christian König,
M'boumba Cedric Madianga, Wolfram Sang
Cc: Pierre-Yves MORDRET, linux-i2c, linux-stm32, linux-arm-kernel,
linux-kernel, linux-media, dri-devel, linaro-mm-sig,
Clément Le Goffic
If the DMA mapping failed, it produced an error log with the wrong
device name:
"stm32-dma3 40400000.dma-controller: rejecting DMA map of vmalloc memory"
Fix this issue by replacing the dev with the I2C dev.
Fixes: bb8822cbbc53 ("i2c: i2c-stm32: Add generic DMA API")
Acked-by: Alain Volmat <alain.volmat@foss.st.com>
Signed-off-by: Clément Le Goffic <clement.legoffic@foss.st.com>
---
drivers/i2c/busses/i2c-stm32.c | 8 +++-----
drivers/i2c/busses/i2c-stm32f7.c | 4 ++--
2 files changed, 5 insertions(+), 7 deletions(-)
diff --git a/drivers/i2c/busses/i2c-stm32.c b/drivers/i2c/busses/i2c-stm32.c
index 157c64e27d0b..f84ec056e36d 100644
--- a/drivers/i2c/busses/i2c-stm32.c
+++ b/drivers/i2c/busses/i2c-stm32.c
@@ -102,7 +102,6 @@ int stm32_i2c_prep_dma_xfer(struct device *dev, struct stm32_i2c_dma *dma,
void *dma_async_param)
{
struct dma_async_tx_descriptor *txdesc;
- struct device *chan_dev;
int ret;
if (rd_wr) {
@@ -116,11 +115,10 @@ int stm32_i2c_prep_dma_xfer(struct device *dev, struct stm32_i2c_dma *dma,
}
dma->dma_len = len;
- chan_dev = dma->chan_using->device->dev;
- dma->dma_buf = dma_map_single(chan_dev, buf, dma->dma_len,
+ dma->dma_buf = dma_map_single(dev, buf, dma->dma_len,
dma->dma_data_dir);
- if (dma_mapping_error(chan_dev, dma->dma_buf)) {
+ if (dma_mapping_error(dev, dma->dma_buf)) {
dev_err(dev, "DMA mapping failed\n");
return -EINVAL;
}
@@ -150,7 +148,7 @@ int stm32_i2c_prep_dma_xfer(struct device *dev, struct stm32_i2c_dma *dma,
return 0;
err:
- dma_unmap_single(chan_dev, dma->dma_buf, dma->dma_len,
+ dma_unmap_single(dev, dma->dma_buf, dma->dma_len,
dma->dma_data_dir);
return ret;
}
diff --git a/drivers/i2c/busses/i2c-stm32f7.c b/drivers/i2c/busses/i2c-stm32f7.c
index e4aaeb2262d0..817d081460c2 100644
--- a/drivers/i2c/busses/i2c-stm32f7.c
+++ b/drivers/i2c/busses/i2c-stm32f7.c
@@ -741,10 +741,10 @@ static void stm32f7_i2c_dma_callback(void *arg)
{
struct stm32f7_i2c_dev *i2c_dev = (struct stm32f7_i2c_dev *)arg;
struct stm32_i2c_dma *dma = i2c_dev->dma;
- struct device *dev = dma->chan_using->device->dev;
stm32f7_i2c_disable_dma_req(i2c_dev);
- dma_unmap_single(dev, dma->dma_buf, dma->dma_len, dma->dma_data_dir);
+ dma_unmap_single(i2c_dev->dev, dma->dma_buf, dma->dma_len,
+ dma->dma_data_dir);
complete(&dma->dma_complete);
}
--
2.43.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v4 2/3] i2c: stm32f7: unmap DMA mapped buffer
2025-07-04 8:39 [PATCH v4 0/3] Fix STM32 I2C dma operations Clément Le Goffic
2025-07-04 8:39 ` [PATCH v4 1/3] i2c: stm32: fix the device used for the DMA map Clément Le Goffic
@ 2025-07-04 8:39 ` Clément Le Goffic
2025-07-04 8:39 ` [PATCH v4 3/3] i2c: stm32f7: support i2c_*_dma_safe_msg_buf APIs Clément Le Goffic
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Clément Le Goffic @ 2025-07-04 8:39 UTC (permalink / raw)
To: Pierre-Yves MORDRET, Alain Volmat, Andi Shyti, Maxime Coquelin,
Alexandre Torgue, Sumit Semwal, Christian König,
M'boumba Cedric Madianga, Wolfram Sang
Cc: Pierre-Yves MORDRET, linux-i2c, linux-stm32, linux-arm-kernel,
linux-kernel, linux-media, dri-devel, linaro-mm-sig,
Clément Le Goffic
Before each I2C transfer using DMA, the I2C buffer is DMA'pped to make
sure the memory buffer is DMA'able. This is handle in the function
`stm32_i2c_prep_dma_xfer()`.
If the transfer fails for any reason the I2C buffer must be unmap.
Use the dma_callback to factorize the code and fix this issue.
Note that the `stm32f7_i2c_dma_callback()` is now called in case of DMA
transfer success and error and that the `complete()` on the dma_complete
completion structure is done inconditionnally in case of transfer
success or error as well as the `dmaengine_terminate_async()`.
This is allowed as a `complete()` in case transfer error has no effect
as well as a `dmaengine_terminate_async()` on a transfer success.
Also fix the unneeded cast and remove not more needed variables.
Fixes: 7ecc8cfde553 ("i2c: i2c-stm32f7: Add DMA support")
Acked-by: Alain Volmat <alain.volmat@foss.st.com>
Signed-off-by: Clément Le Goffic <clement.legoffic@foss.st.com>
---
drivers/i2c/busses/i2c-stm32f7.c | 20 +++++++-------------
1 file changed, 7 insertions(+), 13 deletions(-)
diff --git a/drivers/i2c/busses/i2c-stm32f7.c b/drivers/i2c/busses/i2c-stm32f7.c
index 817d081460c2..73a7b8894c0d 100644
--- a/drivers/i2c/busses/i2c-stm32f7.c
+++ b/drivers/i2c/busses/i2c-stm32f7.c
@@ -739,10 +739,11 @@ static void stm32f7_i2c_disable_dma_req(struct stm32f7_i2c_dev *i2c_dev)
static void stm32f7_i2c_dma_callback(void *arg)
{
- struct stm32f7_i2c_dev *i2c_dev = (struct stm32f7_i2c_dev *)arg;
+ struct stm32f7_i2c_dev *i2c_dev = arg;
struct stm32_i2c_dma *dma = i2c_dev->dma;
stm32f7_i2c_disable_dma_req(i2c_dev);
+ dmaengine_terminate_async(dma->chan_using);
dma_unmap_single(i2c_dev->dev, dma->dma_buf, dma->dma_len,
dma->dma_data_dir);
complete(&dma->dma_complete);
@@ -1510,7 +1511,6 @@ static irqreturn_t stm32f7_i2c_handle_isr_errs(struct stm32f7_i2c_dev *i2c_dev,
u16 addr = f7_msg->addr;
void __iomem *base = i2c_dev->base;
struct device *dev = i2c_dev->dev;
- struct stm32_i2c_dma *dma = i2c_dev->dma;
/* Bus error */
if (status & STM32F7_I2C_ISR_BERR) {
@@ -1551,10 +1551,8 @@ static irqreturn_t stm32f7_i2c_handle_isr_errs(struct stm32f7_i2c_dev *i2c_dev,
}
/* Disable dma */
- if (i2c_dev->use_dma) {
- stm32f7_i2c_disable_dma_req(i2c_dev);
- dmaengine_terminate_async(dma->chan_using);
- }
+ if (i2c_dev->use_dma)
+ stm32f7_i2c_dma_callback(i2c_dev);
i2c_dev->master_mode = false;
complete(&i2c_dev->complete);
@@ -1600,7 +1598,6 @@ static irqreturn_t stm32f7_i2c_isr_event_thread(int irq, void *data)
{
struct stm32f7_i2c_dev *i2c_dev = data;
struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg;
- struct stm32_i2c_dma *dma = i2c_dev->dma;
void __iomem *base = i2c_dev->base;
u32 status, mask;
int ret;
@@ -1619,10 +1616,8 @@ static irqreturn_t stm32f7_i2c_isr_event_thread(int irq, void *data)
dev_dbg(i2c_dev->dev, "<%s>: Receive NACK (addr %x)\n",
__func__, f7_msg->addr);
writel_relaxed(STM32F7_I2C_ICR_NACKCF, base + STM32F7_I2C_ICR);
- if (i2c_dev->use_dma) {
- stm32f7_i2c_disable_dma_req(i2c_dev);
- dmaengine_terminate_async(dma->chan_using);
- }
+ if (i2c_dev->use_dma)
+ stm32f7_i2c_dma_callback(i2c_dev);
f7_msg->result = -ENXIO;
}
@@ -1640,8 +1635,7 @@ static irqreturn_t stm32f7_i2c_isr_event_thread(int irq, void *data)
ret = wait_for_completion_timeout(&i2c_dev->dma->dma_complete, HZ);
if (!ret) {
dev_dbg(i2c_dev->dev, "<%s>: Timed out\n", __func__);
- stm32f7_i2c_disable_dma_req(i2c_dev);
- dmaengine_terminate_async(dma->chan_using);
+ stm32f7_i2c_dma_callback(i2c_dev);
f7_msg->result = -ETIMEDOUT;
}
}
--
2.43.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v4 3/3] i2c: stm32f7: support i2c_*_dma_safe_msg_buf APIs
2025-07-04 8:39 [PATCH v4 0/3] Fix STM32 I2C dma operations Clément Le Goffic
2025-07-04 8:39 ` [PATCH v4 1/3] i2c: stm32: fix the device used for the DMA map Clément Le Goffic
2025-07-04 8:39 ` [PATCH v4 2/3] i2c: stm32f7: unmap DMA mapped buffer Clément Le Goffic
@ 2025-07-04 8:39 ` Clément Le Goffic
2025-07-07 10:12 ` [PATCH v4 0/3] Fix STM32 I2C dma operations Alain Volmat
2025-07-09 14:22 ` Andi Shyti
4 siblings, 0 replies; 6+ messages in thread
From: Clément Le Goffic @ 2025-07-04 8:39 UTC (permalink / raw)
To: Pierre-Yves MORDRET, Alain Volmat, Andi Shyti, Maxime Coquelin,
Alexandre Torgue, Sumit Semwal, Christian König,
M'boumba Cedric Madianga, Wolfram Sang
Cc: Pierre-Yves MORDRET, linux-i2c, linux-stm32, linux-arm-kernel,
linux-kernel, linux-media, dri-devel, linaro-mm-sig,
Clément Le Goffic
`i2c_*_dma_safe_msg_buf` APIs operate on a `struct i2c_msg`.
The get operation make sure the I2C buffer is DMA'able according to its
buffer length, or if the memory use is DMA coherent for example and
return a valid pointer for safe DMA access to be used.
The put operation release the pointer.
Prefer using generic API's than relying on private tests.
Acked-by: Alain Volmat <alain.volmat@foss.st.com>
Signed-off-by: Clément Le Goffic <clement.legoffic@foss.st.com>
---
drivers/i2c/busses/i2c-stm32f7.c | 32 +++++++++++++++++++++-----------
1 file changed, 21 insertions(+), 11 deletions(-)
diff --git a/drivers/i2c/busses/i2c-stm32f7.c b/drivers/i2c/busses/i2c-stm32f7.c
index 73a7b8894c0d..994232646789 100644
--- a/drivers/i2c/busses/i2c-stm32f7.c
+++ b/drivers/i2c/busses/i2c-stm32f7.c
@@ -741,11 +741,14 @@ static void stm32f7_i2c_dma_callback(void *arg)
{
struct stm32f7_i2c_dev *i2c_dev = arg;
struct stm32_i2c_dma *dma = i2c_dev->dma;
+ struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg;
stm32f7_i2c_disable_dma_req(i2c_dev);
dmaengine_terminate_async(dma->chan_using);
dma_unmap_single(i2c_dev->dev, dma->dma_buf, dma->dma_len,
dma->dma_data_dir);
+ if (!f7_msg->smbus)
+ i2c_put_dma_safe_msg_buf(f7_msg->buf, i2c_dev->msg, true);
complete(&dma->dma_complete);
}
@@ -881,6 +884,7 @@ static void stm32f7_i2c_xfer_msg(struct stm32f7_i2c_dev *i2c_dev,
{
struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg;
void __iomem *base = i2c_dev->base;
+ u8 *dma_buf;
u32 cr1, cr2;
int ret;
@@ -930,17 +934,23 @@ static void stm32f7_i2c_xfer_msg(struct stm32f7_i2c_dev *i2c_dev,
/* Configure DMA or enable RX/TX interrupt */
i2c_dev->use_dma = false;
- if (i2c_dev->dma && f7_msg->count >= STM32F7_I2C_DMA_LEN_MIN
- && !i2c_dev->atomic) {
- ret = stm32_i2c_prep_dma_xfer(i2c_dev->dev, i2c_dev->dma,
- msg->flags & I2C_M_RD,
- f7_msg->count, f7_msg->buf,
- stm32f7_i2c_dma_callback,
- i2c_dev);
- if (!ret)
- i2c_dev->use_dma = true;
- else
- dev_warn(i2c_dev->dev, "can't use DMA\n");
+ if (i2c_dev->dma && !i2c_dev->atomic) {
+ dma_buf = i2c_get_dma_safe_msg_buf(msg, STM32F7_I2C_DMA_LEN_MIN);
+ if (dma_buf) {
+ f7_msg->buf = dma_buf;
+ ret = stm32_i2c_prep_dma_xfer(i2c_dev->dev, i2c_dev->dma,
+ msg->flags & I2C_M_RD,
+ f7_msg->count, f7_msg->buf,
+ stm32f7_i2c_dma_callback,
+ i2c_dev);
+ if (ret) {
+ dev_warn(i2c_dev->dev, "can't use DMA\n");
+ i2c_put_dma_safe_msg_buf(f7_msg->buf, msg, false);
+ f7_msg->buf = msg->buf;
+ } else {
+ i2c_dev->use_dma = true;
+ }
+ }
}
if (!i2c_dev->use_dma) {
--
2.43.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v4 0/3] Fix STM32 I2C dma operations
2025-07-04 8:39 [PATCH v4 0/3] Fix STM32 I2C dma operations Clément Le Goffic
` (2 preceding siblings ...)
2025-07-04 8:39 ` [PATCH v4 3/3] i2c: stm32f7: support i2c_*_dma_safe_msg_buf APIs Clément Le Goffic
@ 2025-07-07 10:12 ` Alain Volmat
2025-07-09 14:22 ` Andi Shyti
4 siblings, 0 replies; 6+ messages in thread
From: Alain Volmat @ 2025-07-07 10:12 UTC (permalink / raw)
To: Clément Le Goffic
Cc: Pierre-Yves MORDRET, Andi Shyti, Maxime Coquelin,
Alexandre Torgue, Sumit Semwal, Christian König,
M'boumba Cedric Madianga, Wolfram Sang, Pierre-Yves MORDRET,
linux-i2c, linux-stm32, linux-arm-kernel, linux-kernel,
linux-media, dri-devel, linaro-mm-sig
Hi Clément,
On Fri, Jul 04, 2025 at 10:39:13AM +0200, Clément Le Goffic wrote:
> This patch series aims to fix some issues inside the driver's DMA
> handling.
> It also uses newer I2C DMA API.
>
> Signed-off-by: Clément Le Goffic <clement.legoffic@foss.st.com>
> ---
> Changes in v4:
> - Patch[1]: Remove all `chan_dev` variable occurrencies
> - Patch[2]:
> - Refine commit message
> - Use the dma_callback to factorize the code
> - Patch[3]: Refine commit message
> - Link to v3: https://lore.kernel.org/r/20250630-i2c-upstream-v3-0-7a23ab26683a@foss.st.com
>
> Changes in v3:
> - Add Alain Volmat's "Acked-by" on patch 1 and 2
> - Link to v2: https://lore.kernel.org/r/20250627-i2c-upstream-v2-0-8c14523481dc@foss.st.com
>
> Changes in v2:
> - Fix the dev used in dma_unmap also in the error path of
> `stm32_i2c_prep_dma_xfer`
> - Add a dma_unmap_single also in the ITs error handler
> - Add Alain Volmat's "Acked-by" on patch 3
> - Link to v1: https://lore.kernel.org/r/20250616-i2c-upstream-v1-0-42d3d5374e65@foss.st.com
>
> ---
> Clément Le Goffic (3):
> i2c: stm32: fix the device used for the DMA map
> i2c: stm32f7: unmap DMA mapped buffer
> i2c: stm32f7: support i2c_*_dma_safe_msg_buf APIs
>
> drivers/i2c/busses/i2c-stm32.c | 8 +++---
> drivers/i2c/busses/i2c-stm32f7.c | 56 +++++++++++++++++++++-------------------
> 2 files changed, 33 insertions(+), 31 deletions(-)
> ---
Thanks for this new version of the serie.
This all looks good to me. My Acked-by are already set since v3 so
nothing more from me.
Regards,
Alain
> base-commit: d0b3b7b22dfa1f4b515fd3a295b3fd958f9e81af
> change-id: 20250527-i2c-upstream-e5b69501359a
>
> Best regards,
> --
> Clément Le Goffic <clement.legoffic@foss.st.com>
>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v4 0/3] Fix STM32 I2C dma operations
2025-07-04 8:39 [PATCH v4 0/3] Fix STM32 I2C dma operations Clément Le Goffic
` (3 preceding siblings ...)
2025-07-07 10:12 ` [PATCH v4 0/3] Fix STM32 I2C dma operations Alain Volmat
@ 2025-07-09 14:22 ` Andi Shyti
4 siblings, 0 replies; 6+ messages in thread
From: Andi Shyti @ 2025-07-09 14:22 UTC (permalink / raw)
To: Clément Le Goffic
Cc: Pierre-Yves MORDRET, Alain Volmat, Maxime Coquelin,
Alexandre Torgue, Sumit Semwal, Christian König,
M'boumba Cedric Madianga, Wolfram Sang, Pierre-Yves MORDRET,
linux-i2c, linux-stm32, linux-arm-kernel, linux-kernel,
linux-media, dri-devel, linaro-mm-sig
Hi Clement,
Thanks for following up on the reviews.
> Clément Le Goffic (3):
> i2c: stm32: fix the device used for the DMA map
> i2c: stm32f7: unmap DMA mapped buffer
I applied the two above in i2c/i2c-host-fixes. I'm not sure we
need the "Fixes:" tag in the first patch, though, as we are not
fixing a real bug. But I'm keeping it there for the time being.
> i2c: stm32f7: support i2c_*_dma_safe_msg_buf APIs
This one depends on the previous two to be appliex, so that for
now I added it in i2c/i2c-host-next. I will place it in the
proper branch after the weekly pull request.
Thanks,
Andi
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2025-07-09 14:22 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-04 8:39 [PATCH v4 0/3] Fix STM32 I2C dma operations Clément Le Goffic
2025-07-04 8:39 ` [PATCH v4 1/3] i2c: stm32: fix the device used for the DMA map Clément Le Goffic
2025-07-04 8:39 ` [PATCH v4 2/3] i2c: stm32f7: unmap DMA mapped buffer Clément Le Goffic
2025-07-04 8:39 ` [PATCH v4 3/3] i2c: stm32f7: support i2c_*_dma_safe_msg_buf APIs Clément Le Goffic
2025-07-07 10:12 ` [PATCH v4 0/3] Fix STM32 I2C dma operations Alain Volmat
2025-07-09 14:22 ` Andi Shyti
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).