From: Jarkko Nikula <jarkko.nikula@linux.intel.com>
To: Frank Li <Frank.li@nxp.com>
Cc: linux-i3c@lists.infradead.org,
Alexandre Belloni <alexandre.belloni@bootlin.com>
Subject: Re: [PATCH v2 1/4] i3c: master: Add helpers for DMA mapping and bounce buffer handling
Date: Tue, 19 Aug 2025 09:08:36 +0300 [thread overview]
Message-ID: <8c3627b9-9730-4ced-aaa1-f9003b4e942f@linux.intel.com> (raw)
In-Reply-To: <aKNPp+xieX4soWCj@lizhi-Precision-Tower-5810>
On 8/18/25 7:07 PM, Frank Li wrote:
> On Fri, Aug 15, 2025 at 05:12:39PM +0300, Jarkko Nikula wrote:
>> Some I3C controllers such as MIPI I3C HCI may pad the last DWORD (32-bit)
>> with stale data from the RX FIFO in DMA transfers if the receive length
>> is not DWORD aligned and when the device DMA is IOMMU mapped.
>>
>> In such a case, a properly sized bounce buffer is required in order to
>> avoid possible data corruption. In a review discussion, proposal was to
>> have a common helpers in I3C core for DMA mapping and bounce buffer
>> handling.
>>
>> Drivers may use the helper i3c_master_dma_map_single() to map a buffer
>> for a DMA transfer. It internally allocates a bounce buffer if buffer is
>> not DMA'able or when the driver requires it for a transfer.
>>
>> Helper i3c_master_dma_unmap_single() does the needed cleanups and
>> data copying from the bounce buffer.
>>
>> Signed-off-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
>> ---
>> drivers/i3c/master.c | 69 ++++++++++++++++++++++++++++++++++++++
>> include/linux/i3c/master.h | 26 ++++++++++++++
>> 2 files changed, 95 insertions(+)
>>
>> diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
>> index 2ef898a8fd80..497bff57248a 100644
>> --- a/drivers/i3c/master.c
>> +++ b/drivers/i3c/master.c
>> @@ -8,6 +8,7 @@
>> #include <linux/atomic.h>
>> #include <linux/bug.h>
>> #include <linux/device.h>
>> +#include <linux/dma-mapping.h>
>> #include <linux/err.h>
>> #include <linux/export.h>
>> #include <linux/kernel.h>
>> @@ -1727,6 +1728,74 @@ int i3c_master_do_daa(struct i3c_master_controller *master)
>> }
>> EXPORT_SYMBOL_GPL(i3c_master_do_daa);
>>
>> +/**
>> + * i3c_master_dma_map_single() - Map buffer for single DMA transfer
>> + * @dev: device object of a device doing DMA
>> + * @buf: destination/source buffer for DMA
>> + * @len: length of transfer
>> + * @need_bounce: true if buffer is not DMA safe and need a bounce buffer
>> + * @dir: DMA direction
>> + *
>> + * Map buffer for a DMA transfer and allocate a bounce buffer if required.
>> + *
>> + * Return: I3C DMA transfer descriptor or NULL in case of error.
>> + */
>> +struct i3c_dma *i3c_master_dma_map_single(struct device *dev, void *buf,
>> + size_t len, bool need_bounce, enum dma_data_direction dir)
>> +{
>> + struct i3c_dma *dma_xfer __free(kfree) = NULL;
>> + void *bounce __free(kfree) = NULL;
>> + void *dma_buf = buf;
>> +
>> + dma_xfer = kzalloc(sizeof(*dma_xfer), GFP_KERNEL);
>> + if (!dma_xfer)
>> + return NULL;
>
> nit: add empty line here
>
>> + dma_xfer->dev = dev;
>> + dma_xfer->buf = buf;
>> + dma_xfer->dir = dir;
>> + dma_xfer->len = len;
>> + dma_xfer->map_len = len;
>> +
>> + if (is_vmalloc_addr(buf))
>> + need_bounce = true;
>> +
>> + if (need_bounce) {
>> + dma_xfer->map_len = ALIGN(len, cache_line_size());
>> + if (dir == DMA_FROM_DEVICE)
>> + bounce = kzalloc(dma_xfer->map_len, GFP_KERNEL);
>> + else
>> + bounce = kmemdup(buf, dma_xfer->map_len, GFP_KERNEL);
>> + if (!bounce)
>> + return NULL;
>> + dma_buf = bounce;
>> + }
>> +
>> + dma_xfer->addr = dma_map_single(dev, dma_buf, dma_xfer->map_len, dir);
>> + if (dma_mapping_error(dev, dma_xfer->addr))
>> + return NULL;
>> +
>> + dma_xfer->bounce_buf = no_free_ptr(bounce);
>> + return no_free_ptr(dma_xfer);
>> +}
>> +EXPORT_SYMBOL_GPL(i3c_master_dma_map_single);
>> +
>> +/**
>> + * i3c_master_dma_unmap_single() - Unmap buffer after DMA
>> + * @dma_xfer: DMA transfer and mapping descriptor
>> + *
>> + * Unmap buffer and cleanup DMA transfer descriptor.
>> + */
>> +void i3c_master_dma_unmap_single(struct i3c_dma *dma_xfer)
>> +{
>> + struct i3c_dma *d __free(kfree) = dma_xfer;
>> + void *bounce __free(kfree) = d->bounce_buf;
>
> This simple free, call free(dma_xfer) after memcpy directly.
>
I'm confused. So should I use __free() infra only in
i3c_master_dma_map_single() and use explicit kfree() for dma_xfer and
bounce_buf here?
--
linux-i3c mailing list
linux-i3c@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-i3c
next prev parent reply other threads:[~2025-08-19 6:08 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-08-15 14:12 [PATCH v2 0/4] i3c: mipi-i3c-hci: Make able to work with IOMMU enabled Jarkko Nikula
2025-08-15 14:12 ` [PATCH v2 1/4] i3c: master: Add helpers for DMA mapping and bounce buffer handling Jarkko Nikula
2025-08-18 16:07 ` Frank Li
2025-08-19 6:08 ` Jarkko Nikula [this message]
2025-08-19 14:26 ` Frank Li
2025-08-15 14:12 ` [PATCH v2 2/4] i3c: mipi-i3c-hci: Use core helpers for DMA mapping and bounce buffering Jarkko Nikula
2025-08-18 16:17 ` Frank Li
2025-08-19 6:15 ` Jarkko Nikula
2025-08-19 14:22 ` Frank Li
2025-08-15 14:12 ` [PATCH v2 3/4] i3c: mipi-i3c-hci: Use physical device pointer with DMA API Jarkko Nikula
2025-08-18 16:28 ` Frank Li
2025-08-19 6:27 ` Jarkko Nikula
2025-08-19 14:14 ` Frank Li
2025-08-15 14:12 ` [PATCH v2 4/4] i3c: mipi-i3c-hci: Use own DMA bounce buffer management for I2C transfers Jarkko Nikula
2025-08-18 16:29 ` Frank Li
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=8c3627b9-9730-4ced-aaa1-f9003b4e942f@linux.intel.com \
--to=jarkko.nikula@linux.intel.com \
--cc=Frank.li@nxp.com \
--cc=alexandre.belloni@bootlin.com \
--cc=linux-i3c@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.