[PATCH v5 1/9] dmaengine: Support bus widths of 32 bytes and above
Nuno Sá
nuno.sa at analog.com
Mon Oct 12 03:33:45 PDT 2026
On Fri, Oct 09, 2026 at 02:33:09PM -0500, Frank Li wrote:
> On Fri, Oct 09, 2026 at 04:52:53PM +0100, Nuno Sá wrote:
> > The src_addr_widths and dst_addr_widths capability masks encode each
> > supported width as a bit whose position equals the corresponding
> > enum dma_slave_buswidth value (e.g. DMA_SLAVE_BUSWIDTH_4_BYTES sets bit
> > 4). As these masks are plain u32, widths of 32 bytes and above
> > (DMA_SLAVE_BUSWIDTH_32/64/128_BYTES map to bits 32, 64 and 128) cannot
> > be represented at all.
> >
> > Introduce bitmap-based bus width capabilities that span the full enum
> > range, through a new dma_buswidth_mask_t type modeled after
> > dma_cap_mask_t. To allow DMA controller drivers to be converted
> > incrementally, the legacy dma_device u32 fields are kept alongside the
> > new masks and the core folds a legacy-only driver's u32 into the mask
> > when the device is registered, so consumers only ever have to look at
> > the mask.
> >
> > The fold is bidirectional while both representations coexist. A driver
> > that only fills in the legacy u32 gets its mask derived from it, so the
> > consumers already converted see it. A driver that only fills in the mask
> > gets its legacy u32 derived from the mask, so the consumers not
> > converted yet, which read the legacy dma_slave_caps fields, keep working.
> >
> > On top of that, dma_get_slave_caps() derives the legacy dma_slave_caps
> > masks from the new ones when a device_caps() callback adjusted them, so
> > that a converted controller narrowing its per-channel capabilities is
> > still seen by the consumers not converted yet, while a driver adjusting
> > the legacy masks directly keeps working.
> >
> > Signed-off-by: Nuno Sá <nuno.sa at analog.com>
> >
> > ---
> >
> > Andy, did not take your tag given that you're the one asking for the
> > split and since we ended up not doing it, not sure if the tag is
> > to be kept :)
> > ---
> > drivers/dma/dmaengine.c | 51 +++++++++++-
> > include/linux/dmaengine.h | 208 +++++++++++++++++++++++++++++++++++++++++++---
> > 2 files changed, 246 insertions(+), 13 deletions(-)
> >
> > diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
> > index c5fef57b5adf..4ba9d6c7448a 100644
> > --- a/drivers/dma/dmaengine.c
> > +++ b/drivers/dma/dmaengine.c
> > @@ -33,6 +33,7 @@
> >
> > #include <linux/acpi.h>
> > #include <linux/acpi_dma.h>
> > +#include <linux/bitmap.h>
> > #include <linux/device.h>
> > #include <linux/dma-mapping.h>
> > #include <linux/dmaengine.h>
> > @@ -592,8 +593,11 @@ int dma_get_slave_caps(struct dma_chan *chan, struct dma_slave_caps *caps)
> > if (!device->directions)
> > return -ENXIO;
> >
> > + dma_bus_width_copy(caps->src_bus_widths, device->src_bus_widths);
> > + dma_bus_width_copy(caps->dst_bus_widths, device->dst_bus_widths);
> > caps->src_addr_widths = device->src_addr_widths;
> > caps->dst_addr_widths = device->dst_addr_widths;
> > +
>
> Remove this empty change.
ack
>
> > caps->directions = device->directions;
> > caps->min_burst = device->min_burst;
> > caps->max_burst = device->max_burst;
> > @@ -611,9 +615,31 @@ int dma_get_slave_caps(struct dma_chan *chan, struct dma_slave_caps *caps)
> > * callback to override the generic capabilities with
> > * channel-specific ones.
> > */
> > - if (device->device_caps)
> > + if (device->device_caps) {
> > device->device_caps(chan, caps);
> ...
> > + * Return: 0 on success, -EINVAL if @widths contains an invalid bus width. Note
> > + * that the bus widths validated before the failing one are still set.
> > + */
> > +#define dma_bus_width_set_many(mask, widths, n_widths) \
> > + __dma_bus_width_set_many(&(mask), (widths), (n_widths))
>
> This is not good to get first argument pointer here, which will cause
> confused. check others.
>
> #define dma_bus_width_set_many(mask, widths, n_widths) \
> __dma_bus_width_set_many((mask), (widths), (n_widths))
>
Sure, but FWIW, I just followed the same style of the dma_caps macros.
- Nuno Sá
> Frank
More information about the linux-arm-kernel
mailing list