* [PATCH 0/9] dmaengine: Support bus widths of 32 bytes and above
@ 2026-07-30 14:23 Nuno Sá via B4 Relay
2026-07-30 14:23 ` [PATCH 1/9] " Nuno Sá via B4 Relay
` (9 more replies)
0 siblings, 10 replies; 26+ messages in thread
From: Nuno Sá via B4 Relay @ 2026-07-30 14:23 UTC (permalink / raw)
To: dmaengine, linux-iio
Cc: Vinod Koul, Frank Li, Lars-Peter Clausen, Jonathan Cameron,
David Lechner, Andy Shevchenko
The DMA engine slave capabilities advertise the supported source and
destination bus widths through src_addr_widths / dst_addr_widths. These
are plain u32 bitmasks where a set bit's position equals the
corresponding enum dma_slave_buswidth value, e.g.
DMA_SLAVE_BUSWIDTH_4_BYTES sets bit 4.
The consequence is that widths of 32 bytes and above cannot be
represented at all: DMA_SLAVE_BUSWIDTH_32/64/128_BYTES would need bits
32, 64 and 128, which do not fit in a u32. Hardware with wider data
paths is becoming common, so add a representation that can express these
widths while still using enum dma_slave_buswidth.
This series switches consumers and a small set of producers to bitmap
based bus width capabilities. The legacy dma_device u32 fields are kept
for now so the remaining DMA controller drivers can be converted
incrementally. dma_get_slave_caps() folds legacy producer masks into the
new bitmap representation returned to consumers.
Once the remaining producers are converted, the legacy dma_device
src/dst_addr_widths fields can be removed as a final cleanup.
This issue was discussed before here:
https://lore.kernel.org/dmaengine/abkoXXbaxaiqbBuX@vaman/
---
Changes in v1:
- Drop RFC tag.
- Rename the new capability representation and helpers from address
width terminology to bus width terminology.
- Convert all current dma_get_slave_caps() consumers that used the
legacy src/dst_addr_widths fields.
- Convert a small set of DMA controller producers and the stm32-dma3
per-channel capability callback.
- Add helper documentation for the new public API.
- Link to RFC: https://lore.kernel.org/dmaengine/20260616-dmaengine-support-wider-dma-masks-v1-0-da23a8dcb756@analog.com/
---
Nuno Sá (9):
dmaengine: Support bus widths of 32 bytes and above
dmaengine: dma-axi-dmac: Use bus width capability helpers
dmaengine: dw-axi-dmac: Use bus width capability helpers
dmaengine: qcom: gpi: Use bus width capability helpers
dmaengine: stm32-dma3: Use bus width capability helpers
iio: buffer-dmaengine: Use dma_slave_caps bus width accessors
ALSA: pcm_dmaengine: Use dma_slave_caps bus width helpers
spi: dw: Use dma_slave_caps bus width helpers
dmaengine: Drop legacy bus width fields from dma_slave_caps
drivers/dma/dma-axi-dmac.c | 13 +-
drivers/dma/dmaengine.c | 20 +-
drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 39 ++--
drivers/dma/qcom/gpi.c | 11 +-
drivers/dma/stm32/stm32-dma3.c | 32 +--
drivers/iio/buffer/industrialio-buffer-dmaengine.c | 15 +-
drivers/spi/spi-dw-dma.c | 6 +-
drivers/spi/spi-dw.h | 3 +-
include/linux/dmaengine.h | 234 ++++++++++++++++++++-
sound/core/pcm_dmaengine.c | 14 +-
10 files changed, 323 insertions(+), 64 deletions(-)
---
base-commit: 7524fe142b5a772f8421aeee2132cf7e21a00103
change-id: 20260615-dmaengine-support-wider-dma-masks-5aac12497e27
--
Thanks!
- Nuno Sá
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH 1/9] dmaengine: Support bus widths of 32 bytes and above
2026-07-30 14:23 [PATCH 0/9] dmaengine: Support bus widths of 32 bytes and above Nuno Sá via B4 Relay
@ 2026-07-30 14:23 ` Nuno Sá via B4 Relay
2026-07-30 14:38 ` sashiko-bot
2026-07-30 19:16 ` Frank Li
2026-07-30 14:23 ` [PATCH 2/9] dmaengine: dma-axi-dmac: Use bus width capability helpers Nuno Sá via B4 Relay
` (8 subsequent siblings)
9 siblings, 2 replies; 26+ messages in thread
From: Nuno Sá via B4 Relay @ 2026-07-30 14:23 UTC (permalink / raw)
To: dmaengine, linux-iio
Cc: Vinod Koul, Frank Li, Lars-Peter Clausen, Jonathan Cameron,
David Lechner, Andy Shevchenko
From: Nuno Sá <nuno.sa@analog.com>
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. To allow DMA controller producers to be converted incrementally,
keep the legacy dma_device u32 fields alongside the new bitmaps:
producers using the new helpers populate the bitmap and mirror the low
32 bits back into the legacy field, while dma_get_slave_caps() folds a
legacy-only producer's u32 into the returned bitmap.
Add helpers for producers and consumers so users do not need to depend
on the bitmap layout directly. Once the remaining producers are
converted, the legacy dma_device u32 fields can be dropped.
Signed-off-by: Nuno Sá <nuno.sa@analog.com>
---
drivers/dma/dmaengine.c | 18 ++++
include/linux/dmaengine.h | 246 ++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 254 insertions(+), 10 deletions(-)
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
index 9049171df857..7be23ba769d0 100644
--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -593,7 +593,25 @@ int dma_get_slave_caps(struct dma_chan *chan, struct dma_slave_caps *caps)
return -ENXIO;
caps->src_addr_widths = device->src_addr_widths;
+ if (bitmap_empty(device->src_bus_widths, DMA_SLAVE_BUSWIDTH_MAX)) {
+ bitmap_zero(caps->src_bus_widths, DMA_SLAVE_BUSWIDTH_MAX);
+ bitmap_from_arr32(caps->src_bus_widths,
+ &device->src_addr_widths, 32);
+ } else {
+ bitmap_copy(caps->src_bus_widths, device->src_bus_widths,
+ DMA_SLAVE_BUSWIDTH_MAX);
+ }
+
caps->dst_addr_widths = device->dst_addr_widths;
+ if (bitmap_empty(device->dst_bus_widths, DMA_SLAVE_BUSWIDTH_MAX)) {
+ bitmap_zero(caps->dst_bus_widths, DMA_SLAVE_BUSWIDTH_MAX);
+ bitmap_from_arr32(caps->dst_bus_widths,
+ &device->dst_addr_widths, 32);
+ } else {
+ bitmap_copy(caps->dst_bus_widths, device->dst_bus_widths,
+ DMA_SLAVE_BUSWIDTH_MAX);
+ }
+
caps->directions = device->directions;
caps->min_burst = device->min_burst;
caps->max_burst = device->max_burst;
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index b3d251c9734e..cea57b166dcb 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -5,6 +5,7 @@
#ifndef LINUX_DMAENGINE_H
#define LINUX_DMAENGINE_H
+#include <linux/bitops.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/uio.h>
@@ -391,8 +392,12 @@ enum dma_slave_buswidth {
DMA_SLAVE_BUSWIDTH_32_BYTES = 32,
DMA_SLAVE_BUSWIDTH_64_BYTES = 64,
DMA_SLAVE_BUSWIDTH_128_BYTES = 128,
+ DMA_SLAVE_BUSWIDTH_MAX
};
+#define DECLARE_DMA_BUS_WIDTHS(name) \
+ DECLARE_BITMAP(name, DMA_SLAVE_BUSWIDTH_MAX)
+
/**
* struct dma_slave_config - dma slave channel runtime config
* @direction: whether the data shall go in or out on this slave
@@ -487,10 +492,12 @@ enum dma_residue_granularity {
/**
* struct dma_slave_caps - expose capabilities of a slave channel only
- * @src_addr_widths: bit mask of src addr widths the channel supports.
+ * @src_bus_widths: bitmap of source bus widths the channel supports.
* Width is specified in bytes, e.g. for a channel supporting
- * a width of 4 the mask should have BIT(4) set.
- * @dst_addr_widths: bit mask of dst addr widths the channel supports
+ * a width of 4 the bitmap should have bit 4 set.
+ * @src_addr_widths: legacy bit mask of source bus widths the channel supports.
+ * @dst_bus_widths: bitmap of destination bus widths the channel supports.
+ * @dst_addr_widths: legacy bit mask of destination bus widths the channel supports.
* @directions: bit mask of slave directions the channel supports.
* Since the enum dma_transfer_direction is not defined as bit flag for
* each type, the dma controller should set BIT(<TYPE>) and same
@@ -509,8 +516,14 @@ enum dma_residue_granularity {
* resubmitted multiple times
*/
struct dma_slave_caps {
- u32 src_addr_widths;
- u32 dst_addr_widths;
+ struct {
+ DECLARE_DMA_BUS_WIDTHS(src_bus_widths);
+ u32 src_addr_widths;
+ };
+ struct {
+ DECLARE_DMA_BUS_WIDTHS(dst_bus_widths);
+ u32 dst_addr_widths;
+ };
u32 directions;
u32 min_burst;
u32 max_burst;
@@ -803,10 +816,12 @@ struct dma_filter {
* @dev: struct device reference for dma mapping api
* @owner: owner module (automatically set based on the provided dev)
* @chan_ida: unique channel ID
- * @src_addr_widths: bit mask of src addr widths the device supports
+ * @src_bus_widths: bitmap of source bus widths the device supports.
* Width is specified in bytes, e.g. for a device supporting
- * a width of 4 the mask should have BIT(4) set.
- * @dst_addr_widths: bit mask of dst addr widths the device supports
+ * a width of 4 the bitmap should have bit 4 set.
+ * @src_addr_widths: legacy bit mask of source bus widths the device supports.
+ * @dst_bus_widths: bitmap of destination bus widths the device supports.
+ * @dst_addr_widths: legacy bit mask of destination bus widths the device supports.
* @directions: bit mask of slave directions the device supports.
* Since the enum dma_transfer_direction is not defined as bit flag for
* each type, the dma controller should set BIT(<TYPE>) and same
@@ -887,8 +902,14 @@ struct dma_device {
struct module *owner;
struct ida chan_ida;
- u32 src_addr_widths;
- u32 dst_addr_widths;
+ struct {
+ DECLARE_DMA_BUS_WIDTHS(src_bus_widths);
+ u32 src_addr_widths;
+ };
+ struct {
+ DECLARE_DMA_BUS_WIDTHS(dst_bus_widths);
+ u32 dst_addr_widths;
+ };
u32 directions;
u32 min_burst;
u32 max_burst;
@@ -1678,4 +1699,209 @@ static inline struct device *dmaengine_get_dma_device(struct dma_chan *chan)
return chan->device->dev;
}
+static inline enum dma_slave_buswidth
+__dma_slave_caps_get_width_min(const unsigned long *bus_widths)
+{
+ enum dma_slave_buswidth width = find_first_bit(bus_widths,
+ DMA_SLAVE_BUSWIDTH_MAX);
+
+ if (width == DMA_SLAVE_BUSWIDTH_MAX)
+ return DMA_SLAVE_BUSWIDTH_UNDEFINED;
+
+ return width;
+}
+
+/**
+ * dma_slave_caps_get_src_width_min - get the minimum source bus width
+ * @caps: DMA slave capabilities
+ *
+ * Return: the minimum supported source bus width, or
+ * %DMA_SLAVE_BUSWIDTH_UNDEFINED if no source bus width is advertised.
+ */
+static inline enum dma_slave_buswidth
+dma_slave_caps_get_src_width_min(const struct dma_slave_caps *caps)
+{
+ return __dma_slave_caps_get_width_min(caps->src_bus_widths);
+}
+
+/**
+ * dma_slave_caps_get_dst_width_min - get the minimum destination bus width
+ * @caps: DMA slave capabilities
+ *
+ * Return: the minimum supported destination bus width, or
+ * %DMA_SLAVE_BUSWIDTH_UNDEFINED if no destination bus width is advertised.
+ */
+static inline enum dma_slave_buswidth
+dma_slave_caps_get_dst_width_min(const struct dma_slave_caps *caps)
+{
+ return __dma_slave_caps_get_width_min(caps->dst_bus_widths);
+}
+
+/**
+ * dma_slave_caps_copy_src_widths - copy source bus width capabilities
+ * @caps: DMA slave capabilities
+ * @bus_widths: destination bitmap declared with DECLARE_DMA_BUS_WIDTHS()
+ */
+static inline void
+dma_slave_caps_copy_src_widths(const struct dma_slave_caps *caps,
+ unsigned long *bus_widths)
+{
+ bitmap_copy(bus_widths, caps->src_bus_widths, DMA_SLAVE_BUSWIDTH_MAX);
+}
+
+/**
+ * dma_slave_caps_copy_dst_widths - copy destination bus width capabilities
+ * @caps: DMA slave capabilities
+ * @bus_widths: destination bitmap declared with DECLARE_DMA_BUS_WIDTHS()
+ */
+static inline void
+dma_slave_caps_copy_dst_widths(const struct dma_slave_caps *caps,
+ unsigned long *bus_widths)
+{
+ bitmap_copy(bus_widths, caps->dst_bus_widths, DMA_SLAVE_BUSWIDTH_MAX);
+}
+
+/**
+ * dma_slave_caps_intersect_widths - intersect destination and source widths
+ * @dst_caps: DMA slave capabilities providing destination bus widths
+ * @src_caps: DMA slave capabilities providing source bus widths
+ * @bus_widths: destination bitmap declared with DECLARE_DMA_BUS_WIDTHS()
+ *
+ * Return: true if the resulting bitmap contains at least one common bus width,
+ * false otherwise.
+ */
+static inline bool
+dma_slave_caps_intersect_widths(const struct dma_slave_caps *dst_caps,
+ const struct dma_slave_caps *src_caps,
+ unsigned long *bus_widths)
+{
+ return bitmap_and(bus_widths, dst_caps->dst_bus_widths,
+ src_caps->src_bus_widths, DMA_SLAVE_BUSWIDTH_MAX);
+}
+
+/**
+ * dma_slave_caps_clear_src_width - clear a source bus width capability
+ * @caps: DMA slave capabilities
+ * @width: source bus width to clear
+ */
+static inline void
+dma_slave_caps_clear_src_width(struct dma_slave_caps *caps,
+ enum dma_slave_buswidth width)
+{
+ __clear_bit(width, caps->src_bus_widths);
+ if (width < DMA_SLAVE_BUSWIDTH_32_BYTES)
+ caps->src_addr_widths &= ~BIT(width);
+}
+
+/**
+ * dma_slave_caps_clear_dst_width - clear a destination bus width capability
+ * @caps: DMA slave capabilities
+ * @width: destination bus width to clear
+ */
+static inline void
+dma_slave_caps_clear_dst_width(struct dma_slave_caps *caps,
+ enum dma_slave_buswidth width)
+{
+ __clear_bit(width, caps->dst_bus_widths);
+ if (width < DMA_SLAVE_BUSWIDTH_32_BYTES)
+ caps->dst_addr_widths &= ~BIT(width);
+}
+
+static inline int __dma_set_bus_widths(unsigned long *bus_widths,
+ const enum dma_slave_buswidth *widths,
+ unsigned int n_widths)
+{
+ for (unsigned int i = 0; i < n_widths; i++) {
+ switch (widths[i]) {
+ case DMA_SLAVE_BUSWIDTH_UNDEFINED:
+ case DMA_SLAVE_BUSWIDTH_1_BYTE:
+ case DMA_SLAVE_BUSWIDTH_2_BYTES:
+ case DMA_SLAVE_BUSWIDTH_3_BYTES:
+ case DMA_SLAVE_BUSWIDTH_4_BYTES:
+ case DMA_SLAVE_BUSWIDTH_8_BYTES:
+ case DMA_SLAVE_BUSWIDTH_16_BYTES:
+ case DMA_SLAVE_BUSWIDTH_32_BYTES:
+ case DMA_SLAVE_BUSWIDTH_64_BYTES:
+ case DMA_SLAVE_BUSWIDTH_128_BYTES:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ __set_bit(widths[i], bus_widths);
+ }
+
+ return 0;
+}
+
+/**
+ * dma_set_src_bus_widths - set supported source bus widths for a DMA device
+ * @device: DMA device
+ * @widths: array of supported source bus widths
+ * @n_widths: number of entries in @widths
+ *
+ * Return: 0 on success, -EINVAL if @widths contains an invalid bus width.
+ */
+static inline int dma_set_src_bus_widths(struct dma_device *device,
+ const enum dma_slave_buswidth *widths,
+ unsigned int n_widths)
+{
+ int ret;
+
+ ret = __dma_set_bus_widths(device->src_bus_widths, widths, n_widths);
+ if (ret)
+ return ret;
+
+ device->src_addr_widths = bitmap_read(device->src_bus_widths, 0, 32);
+ return 0;
+}
+
+/**
+ * dma_set_dst_bus_widths - set supported destination bus widths for a DMA device
+ * @device: DMA device
+ * @widths: array of supported destination bus widths
+ * @n_widths: number of entries in @widths
+ *
+ * Return: 0 on success, -EINVAL if @widths contains an invalid bus width.
+ */
+static inline int dma_set_dst_bus_widths(struct dma_device *device,
+ const enum dma_slave_buswidth *widths,
+ unsigned int n_widths)
+{
+ int ret;
+
+ ret = __dma_set_bus_widths(device->dst_bus_widths, widths, n_widths);
+ if (ret)
+ return ret;
+
+ device->dst_addr_widths = bitmap_read(device->dst_bus_widths, 0, 32);
+ return 0;
+}
+
+/**
+ * dma_set_src_bus_width - set a single supported source bus width
+ * @device: DMA device
+ * @width: supported source bus width
+ *
+ * Return: 0 on success, -EINVAL if @width is invalid.
+ */
+static inline int dma_set_src_bus_width(struct dma_device *device,
+ enum dma_slave_buswidth width)
+{
+ return dma_set_src_bus_widths(device, &width, 1);
+}
+
+/**
+ * dma_set_dst_bus_width - set a single supported destination bus width
+ * @device: DMA device
+ * @width: supported destination bus width
+ *
+ * Return: 0 on success, -EINVAL if @width is invalid.
+ */
+static inline int dma_set_dst_bus_width(struct dma_device *device,
+ enum dma_slave_buswidth width)
+{
+ return dma_set_dst_bus_widths(device, &width, 1);
+}
+
#endif /* DMAENGINE_H */
--
2.55.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 2/9] dmaengine: dma-axi-dmac: Use bus width capability helpers
2026-07-30 14:23 [PATCH 0/9] dmaengine: Support bus widths of 32 bytes and above Nuno Sá via B4 Relay
2026-07-30 14:23 ` [PATCH 1/9] " Nuno Sá via B4 Relay
@ 2026-07-30 14:23 ` Nuno Sá via B4 Relay
2026-07-30 14:39 ` sashiko-bot
2026-07-30 19:23 ` Frank Li
2026-07-30 14:23 ` [PATCH 3/9] dmaengine: dw-axi-dmac: " Nuno Sá via B4 Relay
` (7 subsequent siblings)
9 siblings, 2 replies; 26+ messages in thread
From: Nuno Sá via B4 Relay @ 2026-07-30 14:23 UTC (permalink / raw)
To: dmaengine, linux-iio
Cc: Vinod Koul, Frank Li, Lars-Peter Clausen, Jonathan Cameron,
David Lechner, Andy Shevchenko
From: Nuno Sá <nuno.sa@analog.com>
Advertise the source and destination bus widths through the new
dma_set_{src,dst}_bus_width() helpers instead of open-coding the legacy
BIT() mask. This moves the driver onto the representation that can
express widths of 32 bytes and above while keeping the legacy u32 fields
populated during the transition.
While at it, give the channel width members their proper
enum dma_slave_buswidth type.
Signed-off-by: Nuno Sá <nuno.sa@analog.com>
---
drivers/dma/dma-axi-dmac.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/drivers/dma/dma-axi-dmac.c b/drivers/dma/dma-axi-dmac.c
index d47ff27e1408..26912330e3c8 100644
--- a/drivers/dma/dma-axi-dmac.c
+++ b/drivers/dma/dma-axi-dmac.c
@@ -152,8 +152,8 @@ struct axi_dmac_chan {
struct list_head active_descs;
enum dma_transfer_direction direction;
- unsigned int src_width;
- unsigned int dest_width;
+ enum dma_slave_buswidth src_width;
+ enum dma_slave_buswidth dest_width;
unsigned int src_type;
unsigned int dest_type;
@@ -1262,8 +1262,13 @@ static int axi_dmac_probe(struct platform_device *pdev)
dma_dev->device_terminate_all = axi_dmac_terminate_all;
dma_dev->device_synchronize = axi_dmac_synchronize;
dma_dev->dev = &pdev->dev;
- dma_dev->src_addr_widths = BIT(dmac->chan.src_width);
- dma_dev->dst_addr_widths = BIT(dmac->chan.dest_width);
+ ret = dma_set_src_bus_width(dma_dev, dmac->chan.src_width);
+ if (ret)
+ return ret;
+
+ ret = dma_set_dst_bus_width(dma_dev, dmac->chan.dest_width);
+ if (ret)
+ return ret;
dma_dev->directions = BIT(dmac->chan.direction);
dma_dev->residue_granularity = DMA_RESIDUE_GRANULARITY_DESCRIPTOR;
dma_dev->max_sg_burst = 31; /* 31 SGs maximum in one burst */
--
2.55.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 3/9] dmaengine: dw-axi-dmac: Use bus width capability helpers
2026-07-30 14:23 [PATCH 0/9] dmaengine: Support bus widths of 32 bytes and above Nuno Sá via B4 Relay
2026-07-30 14:23 ` [PATCH 1/9] " Nuno Sá via B4 Relay
2026-07-30 14:23 ` [PATCH 2/9] dmaengine: dma-axi-dmac: Use bus width capability helpers Nuno Sá via B4 Relay
@ 2026-07-30 14:23 ` Nuno Sá via B4 Relay
2026-07-30 14:36 ` sashiko-bot
2026-07-30 19:24 ` Frank Li
2026-07-30 14:23 ` [PATCH 4/9] dmaengine: qcom: gpi: " Nuno Sá via B4 Relay
` (6 subsequent siblings)
9 siblings, 2 replies; 26+ messages in thread
From: Nuno Sá via B4 Relay @ 2026-07-30 14:23 UTC (permalink / raw)
To: dmaengine, linux-iio
Cc: Vinod Koul, Frank Li, Lars-Peter Clausen, Jonathan Cameron,
David Lechner, Andy Shevchenko
From: Nuno Sá <nuno.sa@analog.com>
Advertise the supported bus widths through dma_set_src_bus_widths()
and dma_set_dst_bus_widths() instead of assigning the legacy u32 masks
directly. This keeps the driver using the new bitmap representation
while preserving legacy fields during the transition.
Signed-off-by: Nuno Sá <nuno.sa@analog.com>
---
drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 39 +++++++++++++++-----------
1 file changed, 23 insertions(+), 16 deletions(-)
diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
index bcefaff03b5c..69cac7e3625f 100644
--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
@@ -33,20 +33,6 @@
#include "../dmaengine.h"
#include "../virt-dma.h"
-/*
- * The set of bus widths supported by the DMA controller. DW AXI DMAC supports
- * master data bus width up to 512 bits (for both AXI master interfaces), but
- * it depends on IP block configuration.
- */
-#define AXI_DMA_BUSWIDTHS \
- (DMA_SLAVE_BUSWIDTH_1_BYTE | \
- DMA_SLAVE_BUSWIDTH_2_BYTES | \
- DMA_SLAVE_BUSWIDTH_4_BYTES | \
- DMA_SLAVE_BUSWIDTH_8_BYTES | \
- DMA_SLAVE_BUSWIDTH_16_BYTES | \
- DMA_SLAVE_BUSWIDTH_32_BYTES | \
- DMA_SLAVE_BUSWIDTH_64_BYTES)
-
#define AXI_DMA_FLAG_HAS_APB_REGS BIT(0)
#define AXI_DMA_FLAG_HAS_RESETS BIT(1)
#define AXI_DMA_FLAG_USE_CFG2 BIT(2)
@@ -1482,6 +1468,20 @@ static int dw_probe(struct platform_device *pdev)
unsigned int flags;
u32 i;
int ret;
+ /*
+ * The set of bus widths supported by the DMA controller. DW AXI DMAC
+ * supports master data bus width up to 512 bits (for both AXI master
+ * interfaces), but it depends on IP block configuration.
+ */
+ enum dma_slave_buswidth axi_dma_buswidths[] = {
+ DMA_SLAVE_BUSWIDTH_1_BYTE,
+ DMA_SLAVE_BUSWIDTH_2_BYTES,
+ DMA_SLAVE_BUSWIDTH_4_BYTES,
+ DMA_SLAVE_BUSWIDTH_8_BYTES,
+ DMA_SLAVE_BUSWIDTH_16_BYTES,
+ DMA_SLAVE_BUSWIDTH_32_BYTES,
+ DMA_SLAVE_BUSWIDTH_64_BYTES,
+ };
chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
if (!chip)
@@ -1565,8 +1565,15 @@ static int dw_probe(struct platform_device *pdev)
/* DMA capabilities */
dw->dma.max_burst = hdata->axi_rw_burst_len;
- dw->dma.src_addr_widths = AXI_DMA_BUSWIDTHS;
- dw->dma.dst_addr_widths = AXI_DMA_BUSWIDTHS;
+ ret = dma_set_src_bus_widths(&dw->dma, axi_dma_buswidths,
+ ARRAY_SIZE(axi_dma_buswidths));
+ if (ret)
+ return ret;
+
+ ret = dma_set_dst_bus_widths(&dw->dma, axi_dma_buswidths,
+ ARRAY_SIZE(axi_dma_buswidths));
+ if (ret)
+ return ret;
dw->dma.directions = BIT(DMA_MEM_TO_MEM);
dw->dma.directions |= BIT(DMA_MEM_TO_DEV) | BIT(DMA_DEV_TO_MEM);
dw->dma.residue_granularity = DMA_RESIDUE_GRANULARITY_BURST;
--
2.55.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 4/9] dmaengine: qcom: gpi: Use bus width capability helpers
2026-07-30 14:23 [PATCH 0/9] dmaengine: Support bus widths of 32 bytes and above Nuno Sá via B4 Relay
` (2 preceding siblings ...)
2026-07-30 14:23 ` [PATCH 3/9] dmaengine: dw-axi-dmac: " Nuno Sá via B4 Relay
@ 2026-07-30 14:23 ` Nuno Sá via B4 Relay
2026-07-30 14:43 ` sashiko-bot
2026-07-30 19:25 ` Frank Li
2026-07-30 14:23 ` [PATCH 5/9] dmaengine: stm32-dma3: " Nuno Sá via B4 Relay
` (5 subsequent siblings)
9 siblings, 2 replies; 26+ messages in thread
From: Nuno Sá via B4 Relay @ 2026-07-30 14:23 UTC (permalink / raw)
To: dmaengine, linux-iio
Cc: Vinod Koul, Frank Li, Lars-Peter Clausen, Jonathan Cameron,
David Lechner, Andy Shevchenko
From: Nuno Sá <nuno.sa@analog.com>
Advertise the single supported source and destination bus width through
the new dma_set_src_bus_width() and dma_set_dst_bus_width() helpers
instead of assigning the legacy u32 fields directly.
Signed-off-by: Nuno Sá <nuno.sa@analog.com>
---
drivers/dma/qcom/gpi.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/drivers/dma/qcom/gpi.c b/drivers/dma/qcom/gpi.c
index a5055a6273af..fd45cadce91f 100644
--- a/drivers/dma/qcom/gpi.c
+++ b/drivers/dma/qcom/gpi.c
@@ -2265,8 +2265,15 @@ static int gpi_probe(struct platform_device *pdev)
/* configure dmaengine apis */
gpi_dev->dma_device.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
gpi_dev->dma_device.residue_granularity = DMA_RESIDUE_GRANULARITY_DESCRIPTOR;
- gpi_dev->dma_device.src_addr_widths = DMA_SLAVE_BUSWIDTH_8_BYTES;
- gpi_dev->dma_device.dst_addr_widths = DMA_SLAVE_BUSWIDTH_8_BYTES;
+ ret = dma_set_src_bus_width(&gpi_dev->dma_device,
+ DMA_SLAVE_BUSWIDTH_8_BYTES);
+ if (ret)
+ return ret;
+
+ ret = dma_set_dst_bus_width(&gpi_dev->dma_device,
+ DMA_SLAVE_BUSWIDTH_8_BYTES);
+ if (ret)
+ return ret;
gpi_dev->dma_device.device_alloc_chan_resources = gpi_alloc_chan_resources;
gpi_dev->dma_device.device_free_chan_resources = gpi_free_chan_resources;
gpi_dev->dma_device.device_tx_status = dma_cookie_status;
--
2.55.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 5/9] dmaengine: stm32-dma3: Use bus width capability helpers
2026-07-30 14:23 [PATCH 0/9] dmaengine: Support bus widths of 32 bytes and above Nuno Sá via B4 Relay
` (3 preceding siblings ...)
2026-07-30 14:23 ` [PATCH 4/9] dmaengine: qcom: gpi: " Nuno Sá via B4 Relay
@ 2026-07-30 14:23 ` Nuno Sá via B4 Relay
2026-07-30 14:35 ` sashiko-bot
2026-07-30 19:26 ` Frank Li
2026-07-30 14:23 ` [PATCH 6/9] iio: buffer-dmaengine: Use dma_slave_caps bus width accessors Nuno Sá via B4 Relay
` (4 subsequent siblings)
9 siblings, 2 replies; 26+ messages in thread
From: Nuno Sá via B4 Relay @ 2026-07-30 14:23 UTC (permalink / raw)
To: dmaengine, linux-iio
Cc: Vinod Koul, Frank Li, Lars-Peter Clausen, Jonathan Cameron,
David Lechner, Andy Shevchenko
From: Nuno Sá <nuno.sa@analog.com>
Advertise the controller-wide bus width capabilities through the new
dma_set_src_bus_widths() and dma_set_dst_bus_widths() helpers.
Also update the per-channel capability callback to clear unsupported
widths through the dma_slave_caps helpers so the bitmap and
transitional legacy fields stay in sync.
Signed-off-by: Nuno Sá <nuno.sa@analog.com>
---
drivers/dma/stm32/stm32-dma3.c | 32 ++++++++++++++++++++------------
1 file changed, 20 insertions(+), 12 deletions(-)
diff --git a/drivers/dma/stm32/stm32-dma3.c b/drivers/dma/stm32/stm32-dma3.c
index 4724e7fa0008..b0365a5b341d 100644
--- a/drivers/dma/stm32/stm32-dma3.c
+++ b/drivers/dma/stm32/stm32-dma3.c
@@ -1469,14 +1469,14 @@ static void stm32_dma3_caps(struct dma_chan *c, struct dma_slave_caps *caps)
if (!chan->fifo_size) {
caps->max_burst = 0;
- caps->src_addr_widths &= ~BIT(DMA_SLAVE_BUSWIDTH_8_BYTES);
- caps->dst_addr_widths &= ~BIT(DMA_SLAVE_BUSWIDTH_8_BYTES);
+ dma_slave_caps_clear_src_width(caps, DMA_SLAVE_BUSWIDTH_8_BYTES);
+ dma_slave_caps_clear_dst_width(caps, DMA_SLAVE_BUSWIDTH_8_BYTES);
} else {
/* Burst transfer should not exceed half of the fifo size */
caps->max_burst = chan->max_burst;
if (caps->max_burst < DMA_SLAVE_BUSWIDTH_8_BYTES) {
- caps->src_addr_widths &= ~BIT(DMA_SLAVE_BUSWIDTH_8_BYTES);
- caps->dst_addr_widths &= ~BIT(DMA_SLAVE_BUSWIDTH_8_BYTES);
+ dma_slave_caps_clear_src_width(caps, DMA_SLAVE_BUSWIDTH_8_BYTES);
+ dma_slave_caps_clear_dst_width(caps, DMA_SLAVE_BUSWIDTH_8_BYTES);
}
}
}
@@ -1737,6 +1737,12 @@ static int stm32_dma3_probe(struct platform_device *pdev)
u32 master_ports, chan_reserved, i, verr;
u64 hwcfgr;
int ret;
+ enum dma_slave_buswidth stm32_dma3_buswidths[] = {
+ DMA_SLAVE_BUSWIDTH_1_BYTE,
+ DMA_SLAVE_BUSWIDTH_2_BYTES,
+ DMA_SLAVE_BUSWIDTH_4_BYTES,
+ DMA_SLAVE_BUSWIDTH_8_BYTES,
+ };
ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL);
if (!ddata)
@@ -1775,14 +1781,16 @@ static int stm32_dma3_probe(struct platform_device *pdev)
* channel, and can only access address at even boundaries, multiple of the buswidth.
*/
dma_dev->copy_align = DMAENGINE_ALIGN_8_BYTES;
- dma_dev->src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
- BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |
- BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) |
- BIT(DMA_SLAVE_BUSWIDTH_8_BYTES);
- dma_dev->dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
- BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |
- BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) |
- BIT(DMA_SLAVE_BUSWIDTH_8_BYTES);
+ ret = dma_set_src_bus_widths(dma_dev, stm32_dma3_buswidths,
+ ARRAY_SIZE(stm32_dma3_buswidths));
+ if (ret)
+ return ret;
+
+ ret = dma_set_dst_bus_widths(dma_dev, stm32_dma3_buswidths,
+ ARRAY_SIZE(stm32_dma3_buswidths));
+ if (ret)
+ return ret;
+
dma_dev->directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV) | BIT(DMA_MEM_TO_MEM);
dma_dev->descriptor_reuse = true;
--
2.55.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 6/9] iio: buffer-dmaengine: Use dma_slave_caps bus width accessors
2026-07-30 14:23 [PATCH 0/9] dmaengine: Support bus widths of 32 bytes and above Nuno Sá via B4 Relay
` (4 preceding siblings ...)
2026-07-30 14:23 ` [PATCH 5/9] dmaengine: stm32-dma3: " Nuno Sá via B4 Relay
@ 2026-07-30 14:23 ` Nuno Sá via B4 Relay
2026-07-30 19:27 ` Frank Li
2026-07-30 14:23 ` [PATCH 7/9] ALSA: pcm_dmaengine: Use dma_slave_caps bus width helpers Nuno Sá via B4 Relay
` (3 subsequent siblings)
9 siblings, 1 reply; 26+ messages in thread
From: Nuno Sá via B4 Relay @ 2026-07-30 14:23 UTC (permalink / raw)
To: dmaengine, linux-iio
Cc: Vinod Koul, Frank Li, Lars-Peter Clausen, Jonathan Cameron,
David Lechner, Andy Shevchenko
From: Nuno Sá <nuno.sa@analog.com>
Query the minimum supported source and destination bus widths through
the new dma_slave_caps_get_{src,dst}_width_min() helpers rather than
decoding the raw legacy u32 width masks. This keeps the buffer working
with DMA controllers that advertise bus widths via the new bitmap
representation.
Signed-off-by: Nuno Sá <nuno.sa@analog.com>
---
drivers/iio/buffer/industrialio-buffer-dmaengine.c | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/drivers/iio/buffer/industrialio-buffer-dmaengine.c b/drivers/iio/buffer/industrialio-buffer-dmaengine.c
index 98acce909854..855e3662cd3d 100644
--- a/drivers/iio/buffer/industrialio-buffer-dmaengine.c
+++ b/drivers/iio/buffer/industrialio-buffer-dmaengine.c
@@ -229,14 +229,13 @@ static struct iio_buffer *iio_dmaengine_buffer_alloc(struct dma_chan *chan)
return ERR_PTR(-ENOMEM);
/* Needs to be aligned to the maximum of the minimums */
- if (caps.src_addr_widths)
- src_width = __ffs(caps.src_addr_widths);
- else
- src_width = 1;
- if (caps.dst_addr_widths)
- dest_width = __ffs(caps.dst_addr_widths);
- else
- dest_width = 1;
+ src_width = dma_slave_caps_get_src_width_min(&caps);
+ if (src_width == DMA_SLAVE_BUSWIDTH_UNDEFINED)
+ src_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
+ dest_width = dma_slave_caps_get_dst_width_min(&caps);
+ if (dest_width == DMA_SLAVE_BUSWIDTH_UNDEFINED)
+ dest_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
+
width = max(src_width, dest_width);
INIT_LIST_HEAD(&dmaengine_buffer->active);
--
2.55.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 7/9] ALSA: pcm_dmaengine: Use dma_slave_caps bus width helpers
2026-07-30 14:23 [PATCH 0/9] dmaengine: Support bus widths of 32 bytes and above Nuno Sá via B4 Relay
` (5 preceding siblings ...)
2026-07-30 14:23 ` [PATCH 6/9] iio: buffer-dmaengine: Use dma_slave_caps bus width accessors Nuno Sá via B4 Relay
@ 2026-07-30 14:23 ` Nuno Sá via B4 Relay
2026-07-30 19:30 ` Frank Li
2026-07-30 14:23 ` [PATCH 8/9] spi: dw: " Nuno Sá via B4 Relay
` (2 subsequent siblings)
9 siblings, 1 reply; 26+ messages in thread
From: Nuno Sá via B4 Relay @ 2026-07-30 14:23 UTC (permalink / raw)
To: dmaengine, linux-iio
Cc: Vinod Koul, Frank Li, Lars-Peter Clausen, Jonathan Cameron,
David Lechner, Andy Shevchenko
From: Nuno Sá <nuno.sa@analog.com>
Use the dma_slave_caps bus width helpers instead of reading the legacy
src_addr_widths and dst_addr_widths masks directly.
Keep the existing default assumption of 1, 2 and 4 byte widths when the
DMA channel does not report slave capabilities.
Signed-off-by: Nuno Sá <nuno.sa@analog.com>
---
sound/core/pcm_dmaengine.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/sound/core/pcm_dmaengine.c b/sound/core/pcm_dmaengine.c
index 1306b04be171..37468f4643bc 100644
--- a/sound/core/pcm_dmaengine.c
+++ b/sound/core/pcm_dmaengine.c
@@ -409,15 +409,17 @@ int snd_dmaengine_pcm_refine_runtime_hwparams(
struct dma_chan *chan)
{
struct dma_slave_caps dma_caps;
- u32 addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
- BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |
- BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
+ DECLARE_DMA_BUS_WIDTHS(bus_widths) = {};
snd_pcm_format_t i;
int ret = 0;
if (!hw || !chan || !dma_data)
return -EINVAL;
+ __set_bit(DMA_SLAVE_BUSWIDTH_1_BYTE, bus_widths);
+ __set_bit(DMA_SLAVE_BUSWIDTH_2_BYTES, bus_widths);
+ __set_bit(DMA_SLAVE_BUSWIDTH_4_BYTES, bus_widths);
+
ret = dma_get_slave_caps(chan, &dma_caps);
if (ret == 0) {
if (dma_caps.cmd_pause && dma_caps.cmd_resume)
@@ -426,9 +428,9 @@ int snd_dmaengine_pcm_refine_runtime_hwparams(
hw->info |= SNDRV_PCM_INFO_BATCH;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- addr_widths = dma_caps.dst_addr_widths;
+ dma_slave_caps_copy_dst_widths(&dma_caps, bus_widths);
else
- addr_widths = dma_caps.src_addr_widths;
+ dma_slave_caps_copy_src_widths(&dma_caps, bus_widths);
}
/*
@@ -460,7 +462,7 @@ int snd_dmaengine_pcm_refine_runtime_hwparams(
case 24:
case 32:
case 64:
- if (addr_widths & (1 << (bits / 8)))
+ if (test_bit(bits / 8, bus_widths))
hw->formats |= pcm_format_to_bits(i);
break;
default:
--
2.55.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 8/9] spi: dw: Use dma_slave_caps bus width helpers
2026-07-30 14:23 [PATCH 0/9] dmaengine: Support bus widths of 32 bytes and above Nuno Sá via B4 Relay
` (6 preceding siblings ...)
2026-07-30 14:23 ` [PATCH 7/9] ALSA: pcm_dmaengine: Use dma_slave_caps bus width helpers Nuno Sá via B4 Relay
@ 2026-07-30 14:23 ` Nuno Sá via B4 Relay
2026-07-30 14:43 ` sashiko-bot
2026-07-30 19:31 ` Frank Li
2026-07-30 14:23 ` [PATCH 9/9] dmaengine: Drop legacy bus width fields from dma_slave_caps Nuno Sá via B4 Relay
2026-07-30 19:05 ` [PATCH 0/9] dmaengine: Support bus widths of 32 bytes and above Frank Li
9 siblings, 2 replies; 26+ messages in thread
From: Nuno Sá via B4 Relay @ 2026-07-30 14:23 UTC (permalink / raw)
To: dmaengine, linux-iio
Cc: Vinod Koul, Frank Li, Lars-Peter Clausen, Jonathan Cameron,
David Lechner, Andy Shevchenko
From: Nuno Sá <nuno.sa@analog.com>
Store the common TX destination and RX source bus widths in a
driver-owned DMA bus width bitmap and populate it through the
dma_slave_caps helper.
This avoids depending on the legacy src_addr_widths and dst_addr_widths
masks returned by dma_get_slave_caps().
Signed-off-by: Nuno Sá <nuno.sa@analog.com>
---
drivers/spi/spi-dw-dma.c | 6 +++---
drivers/spi/spi-dw.h | 3 ++-
2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/spi/spi-dw-dma.c b/drivers/spi/spi-dw-dma.c
index fe726b9b1780..2e23ead4a94f 100644
--- a/drivers/spi/spi-dw-dma.c
+++ b/drivers/spi/spi-dw-dma.c
@@ -100,10 +100,10 @@ static int dw_spi_dma_caps_init(struct dw_spi *dws)
/*
* Assuming both channels belong to the same DMA controller hence the
- * peripheral side address width capabilities most likely would be
+ * peripheral side bus width capabilities most likely would be
* the same.
*/
- dws->dma_addr_widths = tx.dst_addr_widths & rx.src_addr_widths;
+ dma_slave_caps_intersect_widths(&tx, &rx, dws->dma_bus_widths);
return 0;
}
@@ -253,7 +253,7 @@ static bool dw_spi_can_dma(struct spi_controller *ctlr,
dma_bus_width = dw_spi_dma_convert_width(dws->n_bytes);
- return dws->dma_addr_widths & BIT(dma_bus_width);
+ return test_bit(dma_bus_width, dws->dma_bus_widths);
}
static int dw_spi_dma_wait(struct dw_spi *dws, unsigned int len, u32 speed)
diff --git a/drivers/spi/spi-dw.h b/drivers/spi/spi-dw.h
index 9cc79c566a70..9111ffc5e9d7 100644
--- a/drivers/spi/spi-dw.h
+++ b/drivers/spi/spi-dw.h
@@ -10,6 +10,7 @@
#include <linux/scatterlist.h>
#include <linux/spi/spi-mem.h>
#include <linux/bitfield.h>
+#include <linux/dmaengine.h>
/* Synopsys DW SSI IP-core virtual IDs */
#define DW_PSSI_ID 0
@@ -190,7 +191,7 @@ struct dw_spi {
struct dma_chan *rxchan;
u32 rxburst;
u32 dma_sg_burst;
- u32 dma_addr_widths;
+ DECLARE_DMA_BUS_WIDTHS(dma_bus_widths);
unsigned long dma_chan_busy;
dma_addr_t dma_addr; /* phy address of the Data register */
const struct dw_spi_dma_ops *dma_ops;
--
2.55.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 9/9] dmaengine: Drop legacy bus width fields from dma_slave_caps
2026-07-30 14:23 [PATCH 0/9] dmaengine: Support bus widths of 32 bytes and above Nuno Sá via B4 Relay
` (7 preceding siblings ...)
2026-07-30 14:23 ` [PATCH 8/9] spi: dw: " Nuno Sá via B4 Relay
@ 2026-07-30 14:23 ` Nuno Sá via B4 Relay
2026-07-30 19:34 ` Frank Li
2026-07-30 19:05 ` [PATCH 0/9] dmaengine: Support bus widths of 32 bytes and above Frank Li
9 siblings, 1 reply; 26+ messages in thread
From: Nuno Sá via B4 Relay @ 2026-07-30 14:23 UTC (permalink / raw)
To: dmaengine, linux-iio
Cc: Vinod Koul, Frank Li, Lars-Peter Clausen, Jonathan Cameron,
David Lechner, Andy Shevchenko
From: Nuno Sá <nuno.sa@analog.com>
All users of dma_get_slave_caps() that inspect bus width capabilities
now use bitmap helpers.
Remove the legacy fields from struct dma_slave_caps and stop copying the
dma_device legacy masks into them.
Keep folding legacy dma_device masks into the returned bitmaps so
unconverted DMA controller producers continue to work during the
transition.
Signed-off-by: Nuno Sá <nuno.sa@analog.com>
---
drivers/dma/dmaengine.c | 2 --
include/linux/dmaengine.h | 16 ++--------------
2 files changed, 2 insertions(+), 16 deletions(-)
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
index 7be23ba769d0..ee0b8bfc7c97 100644
--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -592,7 +592,6 @@ int dma_get_slave_caps(struct dma_chan *chan, struct dma_slave_caps *caps)
if (!device->directions)
return -ENXIO;
- caps->src_addr_widths = device->src_addr_widths;
if (bitmap_empty(device->src_bus_widths, DMA_SLAVE_BUSWIDTH_MAX)) {
bitmap_zero(caps->src_bus_widths, DMA_SLAVE_BUSWIDTH_MAX);
bitmap_from_arr32(caps->src_bus_widths,
@@ -602,7 +601,6 @@ int dma_get_slave_caps(struct dma_chan *chan, struct dma_slave_caps *caps)
DMA_SLAVE_BUSWIDTH_MAX);
}
- caps->dst_addr_widths = device->dst_addr_widths;
if (bitmap_empty(device->dst_bus_widths, DMA_SLAVE_BUSWIDTH_MAX)) {
bitmap_zero(caps->dst_bus_widths, DMA_SLAVE_BUSWIDTH_MAX);
bitmap_from_arr32(caps->dst_bus_widths,
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index cea57b166dcb..f37a0559ec5f 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -495,9 +495,7 @@ enum dma_residue_granularity {
* @src_bus_widths: bitmap of source bus widths the channel supports.
* Width is specified in bytes, e.g. for a channel supporting
* a width of 4 the bitmap should have bit 4 set.
- * @src_addr_widths: legacy bit mask of source bus widths the channel supports.
* @dst_bus_widths: bitmap of destination bus widths the channel supports.
- * @dst_addr_widths: legacy bit mask of destination bus widths the channel supports.
* @directions: bit mask of slave directions the channel supports.
* Since the enum dma_transfer_direction is not defined as bit flag for
* each type, the dma controller should set BIT(<TYPE>) and same
@@ -516,14 +514,8 @@ enum dma_residue_granularity {
* resubmitted multiple times
*/
struct dma_slave_caps {
- struct {
- DECLARE_DMA_BUS_WIDTHS(src_bus_widths);
- u32 src_addr_widths;
- };
- struct {
- DECLARE_DMA_BUS_WIDTHS(dst_bus_widths);
- u32 dst_addr_widths;
- };
+ DECLARE_DMA_BUS_WIDTHS(src_bus_widths);
+ DECLARE_DMA_BUS_WIDTHS(dst_bus_widths);
u32 directions;
u32 min_burst;
u32 max_burst;
@@ -1789,8 +1781,6 @@ dma_slave_caps_clear_src_width(struct dma_slave_caps *caps,
enum dma_slave_buswidth width)
{
__clear_bit(width, caps->src_bus_widths);
- if (width < DMA_SLAVE_BUSWIDTH_32_BYTES)
- caps->src_addr_widths &= ~BIT(width);
}
/**
@@ -1803,8 +1793,6 @@ dma_slave_caps_clear_dst_width(struct dma_slave_caps *caps,
enum dma_slave_buswidth width)
{
__clear_bit(width, caps->dst_bus_widths);
- if (width < DMA_SLAVE_BUSWIDTH_32_BYTES)
- caps->dst_addr_widths &= ~BIT(width);
}
static inline int __dma_set_bus_widths(unsigned long *bus_widths,
--
2.55.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* Re: [PATCH 5/9] dmaengine: stm32-dma3: Use bus width capability helpers
2026-07-30 14:23 ` [PATCH 5/9] dmaengine: stm32-dma3: " Nuno Sá via B4 Relay
@ 2026-07-30 14:35 ` sashiko-bot
2026-07-30 19:26 ` Frank Li
1 sibling, 0 replies; 26+ messages in thread
From: sashiko-bot @ 2026-07-30 14:35 UTC (permalink / raw)
To: Nuno Sá; +Cc: dmaengine, Frank.Li, vkoul
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] Direct return on error from `dma_set_src_bus_widths()` or `dma_set_dst_bus_widths()` bypasses clock cleanup, causing a resource leak.
--
--- Patch [5]: [PATCH 5/9] dmaengine: stm32-dma3: Use bus width capability helpers ---
Please note that the format of this report has been altered due to recitation
restrictions. The original patch code is not quoted directly, and findings are
summarized in a free-form text format.
commit 843bd75e7b8b643c8fda123b493184a039d48a35
Author: Nuno Sá <nuno.sa@analog.com>
dmaengine: stm32-dma3: Use bus width capability helpers
This commit advertises the controller-wide bus width capabilities through the
new dma_set_src_bus_widths() and dma_set_dst_bus_widths() helpers. It also
updates the per-channel capability callback to clear unsupported widths
through the dma_slave_caps helpers.
[Severity: Medium]
In the stm32_dma3_probe() function, the patch adds calls to
dma_set_src_bus_widths() and dma_set_dst_bus_widths(). If either of these
helper functions returns an error, the code now does a direct return with the
error code.
Does this direct return bypass the clock cleanup?
Earlier in the probe function, the clock is prepared and enabled via
clk_prepare_enable(ddata->clk). If an error occurs later, the normal error
handling path is to goto err_clk_disable to ensure the clock is properly
disabled. Returning directly here leaves the hardware clock prepared and
enabled, causing a resource leak.
Should these return statements be changed to goto err_clk_disable instead?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260730-dmaengine-support-wider-dma-masks-v1-0-3732f1f9d9ca@analog.com?part=5
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 3/9] dmaengine: dw-axi-dmac: Use bus width capability helpers
2026-07-30 14:23 ` [PATCH 3/9] dmaengine: dw-axi-dmac: " Nuno Sá via B4 Relay
@ 2026-07-30 14:36 ` sashiko-bot
2026-07-30 19:24 ` Frank Li
1 sibling, 0 replies; 26+ messages in thread
From: sashiko-bot @ 2026-07-30 14:36 UTC (permalink / raw)
To: Nuno Sá; +Cc: Frank.Li, dmaengine, vkoul
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] This problem wasn't introduced by this patch, but the probe function contains a high-severity race condition. Early IRQ registration via `devm_request_irq()` with `IRQF_SHARED` before channel registers are initialized and clocks are enabled exposes a fatal race condition.
--
--- Patch [3]: [PATCH 3/9] dmaengine: dw-axi-dmac: Use bus width capability helpers ---
commit b49303c13707fb73ed2de7d6198eee4906bb5793
Author: Nuno Sá <nuno.sa@analog.com>
dmaengine: dw-axi-dmac: Use bus width capability helpers
Advertise the supported bus widths through dma_set_src_bus_widths()
and dma_set_dst_bus_widths() instead of assigning the legacy u32 masks
directly. This keeps the driver using the new bitmap representation
while preserving legacy fields during the transition.
> diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
> index bcefaff03b5c6..69cac7e3625f0 100644
> --- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
> +++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
[ ... ]
> @@ -1482,6 +1468,20 @@ static int dw_probe(struct platform_device *pdev)
> unsigned int flags;
> u32 i;
> int ret;
> + /*
> + * The set of bus widths supported by the DMA controller. DW AXI DMAC
> + * supports master data bus width up to 512 bits (for both AXI master
> + * interfaces), but it depends on IP block configuration.
> + */
[Severity: High]
This isn't a bug introduced by this patch, but while reviewing dw_probe()
I noticed a potential race condition involving early IRQ registration.
If a shared interrupt line fires immediately after devm_request_irq() is
called in axi_req_irqs(), the handler dw_axi_dma_interrupt() will execute.
Could this attempt to read from chip->regs before clocks are enabled via
axi_dma_resume(), potentially causing an external abort?
Additionally, the interrupt handler iterates over dw->chan before
chan->chan_regs is initialized in the subsequent channel initialization loop
in dw_probe():
dw_axi_dma_interrupt() {
...
for (i = 0; i < dw->hdata->nr_channels; i++) {
chan = &dw->chan[i];
status = axi_chan_irq_read(chan);
axi_chan_irq_clear(chan, status);
...
}
Can this cause axi_chan_irq_read() to dereference a NULL pointer when
accessing chan->chan_regs?
[ ... ]
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260730-dmaengine-support-wider-dma-masks-v1-0-3732f1f9d9ca@analog.com?part=3
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 1/9] dmaengine: Support bus widths of 32 bytes and above
2026-07-30 14:23 ` [PATCH 1/9] " Nuno Sá via B4 Relay
@ 2026-07-30 14:38 ` sashiko-bot
2026-07-30 19:16 ` Frank Li
1 sibling, 0 replies; 26+ messages in thread
From: sashiko-bot @ 2026-07-30 14:38 UTC (permalink / raw)
To: Nuno Sá; +Cc: Frank.Li, dmaengine, vkoul
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] Legacy `device_caps()` callbacks cause desynchronization between the legacy `u32` capability masks and the newly introduced bitmap fields in `struct dma_slave_caps`, leading to unsupported bus widths being falsely advertised to consumers.
--
--- Patch [1]: [PATCH 1/9] dmaengine: Support bus widths of 32 bytes and above ---
commit 2d5a426ace9eaa0310bd634be5edc8e4ed522c24
Author: Nuno Sá <nuno.sa@analog.com>
dmaengine: Support bus widths of 32 bytes and above
Introduces bitmap-based bus width capabilities that span the full enum
range to support widths of 32 bytes and above. Retains the legacy u32
fields alongside the new bitmaps to allow incremental conversion of
producers.
> diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
> index 9049171df8578..7be23ba769d0d 100644
> --- a/drivers/dma/dmaengine.c
> +++ b/drivers/dma/dmaengine.c
> @@ -593,7 +593,25 @@ int dma_get_slave_caps(struct dma_chan *chan, struct dma_slave_caps *caps)
[ ... ]
> caps->dst_addr_widths = device->dst_addr_widths;
> + if (bitmap_empty(device->dst_bus_widths, DMA_SLAVE_BUSWIDTH_MAX)) {
> + bitmap_zero(caps->dst_bus_widths, DMA_SLAVE_BUSWIDTH_MAX);
> + bitmap_from_arr32(caps->dst_bus_widths,
> + &device->dst_addr_widths, 32);
> + } else {
> + bitmap_copy(caps->dst_bus_widths, device->dst_bus_widths,
> + DMA_SLAVE_BUSWIDTH_MAX);
> + }
> +
> caps->directions = device->directions;
> caps->min_burst = device->min_burst;
> caps->max_burst = device->max_burst;
[Severity: High]
Does this setup cause a desynchronization between the new bitmaps and the
legacy u32 fields after device_caps() is invoked?
Looking at the end of dma_get_slave_caps() in drivers/dma/dmaengine.c:
if (device->device_caps)
device->device_caps(chan, caps);
return 0;
Legacy drivers dynamically modify the u32 fields in their device_caps()
callback. For example, stm32_dma3_caps() in drivers/dma/stm32/stm32-dma3.c
modifies the capabilities:
caps->src_addr_widths &= ~BIT(DMA_SLAVE_BUSWIDTH_8_BYTES);
Since the new bitmaps are initialized before device_caps() is called, and
there is no re-synchronization of the legacy u32 fields back to the bitmaps
after it returns, won't consumers querying capabilities using new helpers
like dma_slave_caps_intersect_widths() read the unmodified, stale bitmaps?
Could this result in consumer drivers configuring a DMA transfer with an
unsupported bus width?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260730-dmaengine-support-wider-dma-masks-v1-0-3732f1f9d9ca@analog.com?part=1
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 2/9] dmaengine: dma-axi-dmac: Use bus width capability helpers
2026-07-30 14:23 ` [PATCH 2/9] dmaengine: dma-axi-dmac: Use bus width capability helpers Nuno Sá via B4 Relay
@ 2026-07-30 14:39 ` sashiko-bot
2026-07-30 19:23 ` Frank Li
1 sibling, 0 replies; 26+ messages in thread
From: sashiko-bot @ 2026-07-30 14:39 UTC (permalink / raw)
To: Nuno Sá; +Cc: dmaengine, Frank.Li, vkoul
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] dma_dev->copy_align is incorrectly populated with a linear byte width rather than a logarithmic one, causing undefined behavior for bus widths >= 32 bytes.
--
--- Patch [2]: [PATCH 2/9] dmaengine: dma-axi-dmac: Use bus width capability helpers ---
commit 99138308c2fc808f6bee3d2ac55aef702ecbd98a
Author: Nuno Sá <nuno.sa@analog.com>
dmaengine: dma-axi-dmac: Use bus width capability helpers
This patch updates the driver to use the dma_set_src_bus_width() and
dma_set_dst_bus_width() helpers instead of open-coding the legacy BIT()
mask. This allows the driver to express bus widths of 32 bytes and above
while keeping the legacy u32 fields populated.
> diff --git a/drivers/dma/dma-axi-dmac.c b/drivers/dma/dma-axi-dmac.c
> index d47ff27e1408f..26912330e3c83 100644
> --- a/drivers/dma/dma-axi-dmac.c
> +++ b/drivers/dma/dma-axi-dmac.c
[ ... ]
> @@ -1262,8 +1262,13 @@ static int axi_dmac_probe(struct platform_device *pdev)
> dma_dev->device_terminate_all = axi_dmac_terminate_all;
> dma_dev->device_synchronize = axi_dmac_synchronize;
> dma_dev->dev = &pdev->dev;
> - dma_dev->src_addr_widths = BIT(dmac->chan.src_width);
> - dma_dev->dst_addr_widths = BIT(dmac->chan.dest_width);
> + ret = dma_set_src_bus_width(dma_dev, dmac->chan.src_width);
> + if (ret)
> + return ret;
> +
> + ret = dma_set_dst_bus_width(dma_dev, dmac->chan.dest_width);
> + if (ret)
> + return ret;
[Severity: High]
This is a pre-existing issue, but since this patch enables bus widths of 32
bytes and above, does it expose an undefined behavior in the generic DMA
framework?
Further down in axi_dmac_probe(), copy_align is assigned a linear byte width:
drivers/dma/dma-axi-dmac.c:axi_dmac_probe() {
...
dma_dev->copy_align = (dmac->chan.address_align_mask + 1);
...
}
The copy_align field is expected to be a logarithmic value based on enum
dmaengine_alignment. When a bus width of 32 bytes or more is configured,
copy_align becomes 32 or greater.
Functions in the generic DMA framework use this value as a shift amount.
For example:
include/linux/dmaengine.h:dmaengine_check_align() {
...
return !(((1 << align) - 1) & (off1 | off2 | len));
}
If align is 32 or greater, shifting a 32-bit integer by that amount causes
undefined behavior. Should copy_align be updated to use a logarithmic
value to avoid this issue now that larger bus widths are supported?
> dma_dev->directions = BIT(dmac->chan.direction);
> dma_dev->residue_granularity = DMA_RESIDUE_GRANULARITY_DESCRIPTOR;
> dma_dev->max_sg_burst = 31; /* 31 SGs maximum in one burst */
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260730-dmaengine-support-wider-dma-masks-v1-0-3732f1f9d9ca@analog.com?part=2
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 8/9] spi: dw: Use dma_slave_caps bus width helpers
2026-07-30 14:23 ` [PATCH 8/9] spi: dw: " Nuno Sá via B4 Relay
@ 2026-07-30 14:43 ` sashiko-bot
2026-07-30 19:31 ` Frank Li
1 sibling, 0 replies; 26+ messages in thread
From: sashiko-bot @ 2026-07-30 14:43 UTC (permalink / raw)
To: Nuno Sá; +Cc: dmaengine, vkoul, Frank.Li
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] `dw_spi_can_dma` relies on a stale `dws->n_bytes` value, which may cause incorrect DMA fallback or unsupported DMA configuration.
--
--- Patch [8]: [PATCH 8/9] spi: dw: Use dma_slave_caps bus width helpers ---
commit cd2773a5f68d147fd25b2ce32d4b2dd68d630ea4
Author: Nuno Sá <nuno.sa@analog.com>
spi: dw: Use dma_slave_caps bus width helpers
Store the common TX destination and RX source bus widths in a driver-owned
DMA bus width bitmap and populate it through the dma_slave_caps helper.
This avoids depending on the legacy addr_widths masks.
> diff --git a/drivers/spi/spi-dw-dma.c b/drivers/spi/spi-dw-dma.c
> index fe726b9b1780d..2e23ead4a94f9 100644
> --- a/drivers/spi/spi-dw-dma.c
> +++ b/drivers/spi/spi-dw-dma.c
[ ... ]
> @@ -253,7 +253,7 @@ static bool dw_spi_can_dma(struct spi_controller *ctlr,
>
> dma_bus_width = dw_spi_dma_convert_width(dws->n_bytes);
>
[Severity: High]
This is a pre-existing issue, but does dw_spi_can_dma() rely on a stale
dws->n_bytes value here?
The dws->n_bytes field holds the word size of the previous transfer. Should
dw_spi_can_dma() compute the bus width directly from xfer->bits_per_word to
correctly evaluate the DMA capability for the current transfer?
If a device uses different bus widths for successive SPI transfers, an
earlier transfer might use a bus width supported by the DMA controller, but
a later transfer uses an unsupported width. This would cause
dw_spi_can_dma() to incorrectly allow the second transfer to be DMA mapped
because it checks the stale dws->n_bytes from the first transfer.
When the SPI core later executes dw_spi_transfer_one() for the second
transfer, dws->n_bytes is updated to the actual unsupported width, and
dw_spi_dma_setup() attempts to configure the DMA engine with it, causing
dmaengine_slave_config() to fail and aborting the transfer.
> - return dws->dma_addr_widths & BIT(dma_bus_width);
> + return test_bit(dma_bus_width, dws->dma_bus_widths);
> }
>
> static int dw_spi_dma_wait(struct dw_spi *dws, unsigned int len, u32 speed)
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260730-dmaengine-support-wider-dma-masks-v1-0-3732f1f9d9ca@analog.com?part=8
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 4/9] dmaengine: qcom: gpi: Use bus width capability helpers
2026-07-30 14:23 ` [PATCH 4/9] dmaengine: qcom: gpi: " Nuno Sá via B4 Relay
@ 2026-07-30 14:43 ` sashiko-bot
2026-07-30 19:25 ` Frank Li
1 sibling, 0 replies; 26+ messages in thread
From: sashiko-bot @ 2026-07-30 14:43 UTC (permalink / raw)
To: Nuno Sá; +Cc: vkoul, Frank.Li, dmaengine
Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider:
Pre-existing issues:
- [High] Missing dma_async_device_unregister() in the probe error path and lack of a .remove callback leads to Use-After-Free.
- [High] Error cleanup paths in gpi_ch_init() reset the wrong channel.
- [Medium] Out-of-bounds bitwise shift when processing the `dma-channels` property.
- [Medium] DMA coherent memory allocated for channel rings is leaked if channel initialization fails.
- [Medium] Potential integer overflow in devm_kzalloc when allocating gpiis array.
--
--- Patch [4]: [PATCH 4/9] dmaengine: qcom: gpi: Use bus width capability helpers ---
commit 359e67a23cc93b4c7bc48fb679da1cdd39760273
Author: Nuno Sá <nuno.sa@analog.com>
dmaengine: qcom: gpi: Use bus width capability helpers
Advertise the single supported source and destination bus width through
the new dma_set_src_bus_width() and dma_set_dst_bus_width() helpers
instead of assigning the legacy u32 fields directly.
> diff --git a/drivers/dma/qcom/gpi.c b/drivers/dma/qcom/gpi.c
> index a5055a6273af6..fd45cadce91fd 100644
> --- a/drivers/dma/qcom/gpi.c
> +++ b/drivers/dma/qcom/gpi.c
[ ... ]
> @@ -1994,11 +1994,11 @@ static int gpi_ch_init(struct gchan *gchan)
>
> error_start_chan:
> for (i = i - 1; i >= 0; i--) {
> gpi_stop_chan(&gpii->gchan[i]);
> gpi_send_cmd(gpii, gchan, GPI_CH_CMD_RESET);
^^^^^
[Severity: High]
This is a pre-existing issue, but does this pass the correct channel to
gpi_send_cmd()? It looks like the error cleanup paths are passing the
function parameter gchan instead of the iterated channel &gpii->gchan[i],
which might leave previously started channels running while resetting the
wrong one.
> }
> i = 2;
> error_alloc_chan:
> for (i = i - 1; i >= 0; i--)
> gpi_reset_chan(gchan, GPI_CH_CMD_DE_ALLOC);
^^^^^
[Severity: High]
This is a pre-existing issue, but does this also reset the wrong channel
for the same reason?
[ ... ]
> @@ -2058,11 +2058,11 @@ static int gpi_alloc_chan_resources(struct dma_chan *chan)
>
> /* allocate memory for transfer ring */
> ret = gpi_alloc_ring(&gchan->ch_ring, CHAN_TRES,
> sizeof(struct gpi_tre), gpii);
> if (ret)
> goto xfer_alloc_err;
>
> ret = gpi_ch_init(gchan);
>
> mutex_unlock(&gpii->ctrl_lock);
>
> return ret;
[Severity: Medium]
This is a pre-existing issue, but does this error path leak the DMA coherent
memory allocated for gchan->ch_ring if gpi_ch_init() fails? It looks like it
exits without calling gpi_free_ring().
[ ... ]
> @@ -2218,17 +2218,17 @@ static int gpi_probe(struct platform_device *pdev)
>
> gpi_dev->gpiis = devm_kzalloc(gpi_dev->dev, sizeof(*gpi_dev->gpiis) *
> gpi_dev->max_gpii, GFP_KERNEL);
[Severity: Medium]
This is a pre-existing issue, but can this unchecked multiplication overflow
before being passed to devm_kzalloc()?
If a malformed Device Tree provides an excessively large max_gpii value, this
could result in a significantly smaller allocation and out-of-bounds writes in
the initialization loop. Should this use devm_kcalloc() instead?
> if (!gpi_dev->gpiis)
> return -ENOMEM;
>
> /* setup all the supported gpii */
> INIT_LIST_HEAD(&gpi_dev->dma_device.channels);
> for (i = 0; i < gpi_dev->max_gpii; i++) {
> struct gpii *gpii = &gpi_dev->gpiis[i];
> int chan;
>
> if (!((1 << i) & gpi_dev->gpii_mask))
> continue;
[Severity: Medium]
This is a pre-existing issue, but can this bitwise shift (1 << i) overflow a
32-bit integer if i >= 32? Since max_gpii is parsed from the Device Tree
without bounds checking, it seems this could invoke undefined behavior.
[ ... ]
> /* configure dmaengine apis */
> gpi_dev->dma_device.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
> gpi_dev->dma_device.residue_granularity = DMA_RESIDUE_GRANULARITY_DESCRIPTOR;
> - gpi_dev->dma_device.src_addr_widths = DMA_SLAVE_BUSWIDTH_8_BYTES;
> - gpi_dev->dma_device.dst_addr_widths = DMA_SLAVE_BUSWIDTH_8_BYTES;
> + ret = dma_set_src_bus_width(&gpi_dev->dma_device,
> + DMA_SLAVE_BUSWIDTH_8_BYTES);
> + if (ret)
> + return ret;
> +
> + ret = dma_set_dst_bus_width(&gpi_dev->dma_device,
> + DMA_SLAVE_BUSWIDTH_8_BYTES);
> + if (ret)
> + return ret;
> gpi_dev->dma_device.device_alloc_chan_resources = gpi_alloc_chan_resources;
[ ... ]
> ret = of_dma_controller_register(gpi_dev->dev->of_node,
> gpi_of_dma_xlate, gpi_dev);
> if (ret) {
> dev_err(gpi_dev->dev, "of_dma_controller_reg failed ret:%d", ret);
> return ret;
> }
>
> return ret;
> }
[Severity: High]
This isn't a bug introduced by this patch, but does the probe function return
here without unregistering the previously registered DMA device?
If of_dma_controller_register() fails, dma_async_device_unregister() is
missing, which could leave dangling pointers in the DMA and OF framework lists,
causing a Use-After-Free.
[ ... ]
> @@ -2319,9 +2319,9 @@ static const struct of_device_id gpi_of_match[] = {
> MODULE_DEVICE_TABLE(of, gpi_of_match);
>
> static struct platform_driver gpi_driver = {
> .probe = gpi_probe,
> .driver = {
> .name = KBUILD_MODNAME,
> .of_match_table = gpi_of_match,
> },
> };
[Severity: High]
This is a pre-existing issue, but does this platform driver lack a .remove
callback?
Without it, sysfs unbind invokes devres cleanup while leaving the DMA device
registered, which can lead to a Use-After-Free.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260730-dmaengine-support-wider-dma-masks-v1-0-3732f1f9d9ca@analog.com?part=4
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 0/9] dmaengine: Support bus widths of 32 bytes and above
2026-07-30 14:23 [PATCH 0/9] dmaengine: Support bus widths of 32 bytes and above Nuno Sá via B4 Relay
` (8 preceding siblings ...)
2026-07-30 14:23 ` [PATCH 9/9] dmaengine: Drop legacy bus width fields from dma_slave_caps Nuno Sá via B4 Relay
@ 2026-07-30 19:05 ` Frank Li
9 siblings, 0 replies; 26+ messages in thread
From: Frank Li @ 2026-07-30 19:05 UTC (permalink / raw)
To: nuno.sa
Cc: dmaengine, linux-iio, Vinod Koul, Frank Li, Lars-Peter Clausen,
Jonathan Cameron, David Lechner, Andy Shevchenko
On Thu, Jul 30, 2026 at 03:23:07PM +0100, Nuno Sá via B4 Relay wrote:
> [You don't often get email from devnull+nuno.sa.analog.com@kernel.org. Learn why this is important at https://aka.ms/LearnAboutSenderIdentification ]
>
> The DMA engine slave capabilities advertise the supported source and
> destination bus widths through src_addr_widths / dst_addr_widths. These
> are plain u32 bitmasks where a set bit's position equals the
> corresponding enum dma_slave_buswidth value, e.g.
> DMA_SLAVE_BUSWIDTH_4_BYTES sets bit 4.
>
> The consequence is that widths of 32 bytes and above cannot be
> represented at all: DMA_SLAVE_BUSWIDTH_32/64/128_BYTES would need bits
> 32, 64 and 128, which do not fit in a u32. Hardware with wider data
> paths is becoming common, so add a representation that can express these
> widths while still using enum dma_slave_buswidth.
>
> This series switches consumers and a small set of producers to bitmap
> based bus width capabilities. The legacy dma_device u32 fields are kept
> for now so the remaining DMA controller drivers can be converted
> incrementally. dma_get_slave_caps() folds legacy producer masks into the
> new bitmap representation returned to consumers.
>
> Once the remaining producers are converted, the legacy dma_device
> src/dst_addr_widths fields can be removed as a final cleanup.
>
> This issue was discussed before here:
>
> https://lore.kernel.org/dmaengine/abkoXXbaxaiqbBuX@vaman/
>
> ---
> Changes in v1:
this should be v2, RFC is v1
Frank
> - Drop RFC tag.
> - Rename the new capability representation and helpers from address
> width terminology to bus width terminology.
> - Convert all current dma_get_slave_caps() consumers that used the
> legacy src/dst_addr_widths fields.
> - Convert a small set of DMA controller producers and the stm32-dma3
> per-channel capability callback.
> - Add helper documentation for the new public API.
> - Link to RFC: https://lore.kernel.org/dmaengine/20260616-dmaengine-support-wider-dma-masks-v1-0-da23a8dcb756@analog.com/
>
> ---
> Nuno Sá (9):
> dmaengine: Support bus widths of 32 bytes and above
> dmaengine: dma-axi-dmac: Use bus width capability helpers
> dmaengine: dw-axi-dmac: Use bus width capability helpers
> dmaengine: qcom: gpi: Use bus width capability helpers
> dmaengine: stm32-dma3: Use bus width capability helpers
> iio: buffer-dmaengine: Use dma_slave_caps bus width accessors
> ALSA: pcm_dmaengine: Use dma_slave_caps bus width helpers
> spi: dw: Use dma_slave_caps bus width helpers
> dmaengine: Drop legacy bus width fields from dma_slave_caps
>
> drivers/dma/dma-axi-dmac.c | 13 +-
> drivers/dma/dmaengine.c | 20 +-
> drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 39 ++--
> drivers/dma/qcom/gpi.c | 11 +-
> drivers/dma/stm32/stm32-dma3.c | 32 +--
> drivers/iio/buffer/industrialio-buffer-dmaengine.c | 15 +-
> drivers/spi/spi-dw-dma.c | 6 +-
> drivers/spi/spi-dw.h | 3 +-
> include/linux/dmaengine.h | 234 ++++++++++++++++++++-
> sound/core/pcm_dmaengine.c | 14 +-
> 10 files changed, 323 insertions(+), 64 deletions(-)
> ---
> base-commit: 7524fe142b5a772f8421aeee2132cf7e21a00103
> change-id: 20260615-dmaengine-support-wider-dma-masks-5aac12497e27
> --
>
> Thanks!
> - Nuno Sá
>
>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 1/9] dmaengine: Support bus widths of 32 bytes and above
2026-07-30 14:23 ` [PATCH 1/9] " Nuno Sá via B4 Relay
2026-07-30 14:38 ` sashiko-bot
@ 2026-07-30 19:16 ` Frank Li
1 sibling, 0 replies; 26+ messages in thread
From: Frank Li @ 2026-07-30 19:16 UTC (permalink / raw)
To: nuno.sa
Cc: dmaengine, linux-iio, Vinod Koul, Frank Li, Lars-Peter Clausen,
Jonathan Cameron, David Lechner, Andy Shevchenko
On Thu, Jul 30, 2026 at 03:23:08PM +0100, Nuno Sá via B4 Relay wrote:
> [You don't often get email from devnull+nuno.sa.analog.com@kernel.org. Learn why this is important at https://aka.ms/LearnAboutSenderIdentification ]
>
> From: Nuno Sá <nuno.sa@analog.com>
>
> 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. To allow DMA controller producers to be converted incrementally,
> keep the legacy dma_device u32 fields alongside the new bitmaps:
> producers using the new helpers populate the bitmap and mirror the low
> 32 bits back into the legacy field, while dma_get_slave_caps() folds a
> legacy-only producer's u32 into the returned bitmap.
>
> Add helpers for producers and consumers so users do not need to depend
> on the bitmap layout directly. Once the remaining producers are
> converted, the legacy dma_device u32 fields can be dropped.
>
> Signed-off-by: Nuno Sá <nuno.sa@analog.com>
> ---
Reviewed-by: Frank Li <Frank.Li@nxp.com>
> drivers/dma/dmaengine.c | 18 ++++
> include/linux/dmaengine.h | 246 ++++++++++++++++++++++++++++++++++++++++++++--
> 2 files changed, 254 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
> index 9049171df857..7be23ba769d0 100644
> --- a/drivers/dma/dmaengine.c
> +++ b/drivers/dma/dmaengine.c
> @@ -593,7 +593,25 @@ int dma_get_slave_caps(struct dma_chan *chan, struct dma_slave_caps *caps)
> return -ENXIO;
>
> caps->src_addr_widths = device->src_addr_widths;
> + if (bitmap_empty(device->src_bus_widths, DMA_SLAVE_BUSWIDTH_MAX)) {
> + bitmap_zero(caps->src_bus_widths, DMA_SLAVE_BUSWIDTH_MAX);
> + bitmap_from_arr32(caps->src_bus_widths,
> + &device->src_addr_widths, 32);
> + } else {
> + bitmap_copy(caps->src_bus_widths, device->src_bus_widths,
> + DMA_SLAVE_BUSWIDTH_MAX);
> + }
> +
> caps->dst_addr_widths = device->dst_addr_widths;
> + if (bitmap_empty(device->dst_bus_widths, DMA_SLAVE_BUSWIDTH_MAX)) {
> + bitmap_zero(caps->dst_bus_widths, DMA_SLAVE_BUSWIDTH_MAX);
> + bitmap_from_arr32(caps->dst_bus_widths,
> + &device->dst_addr_widths, 32);
> + } else {
> + bitmap_copy(caps->dst_bus_widths, device->dst_bus_widths,
> + DMA_SLAVE_BUSWIDTH_MAX);
> + }
> +
> caps->directions = device->directions;
> caps->min_burst = device->min_burst;
> caps->max_burst = device->max_burst;
> diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
> index b3d251c9734e..cea57b166dcb 100644
> --- a/include/linux/dmaengine.h
> +++ b/include/linux/dmaengine.h
> @@ -5,6 +5,7 @@
> #ifndef LINUX_DMAENGINE_H
> #define LINUX_DMAENGINE_H
>
> +#include <linux/bitops.h>
> #include <linux/device.h>
> #include <linux/err.h>
> #include <linux/uio.h>
> @@ -391,8 +392,12 @@ enum dma_slave_buswidth {
> DMA_SLAVE_BUSWIDTH_32_BYTES = 32,
> DMA_SLAVE_BUSWIDTH_64_BYTES = 64,
> DMA_SLAVE_BUSWIDTH_128_BYTES = 128,
> + DMA_SLAVE_BUSWIDTH_MAX
> };
>
> +#define DECLARE_DMA_BUS_WIDTHS(name) \
> + DECLARE_BITMAP(name, DMA_SLAVE_BUSWIDTH_MAX)
> +
> /**
> * struct dma_slave_config - dma slave channel runtime config
> * @direction: whether the data shall go in or out on this slave
> @@ -487,10 +492,12 @@ enum dma_residue_granularity {
>
> /**
> * struct dma_slave_caps - expose capabilities of a slave channel only
> - * @src_addr_widths: bit mask of src addr widths the channel supports.
> + * @src_bus_widths: bitmap of source bus widths the channel supports.
> * Width is specified in bytes, e.g. for a channel supporting
> - * a width of 4 the mask should have BIT(4) set.
> - * @dst_addr_widths: bit mask of dst addr widths the channel supports
> + * a width of 4 the bitmap should have bit 4 set.
> + * @src_addr_widths: legacy bit mask of source bus widths the channel supports.
> + * @dst_bus_widths: bitmap of destination bus widths the channel supports.
> + * @dst_addr_widths: legacy bit mask of destination bus widths the channel supports.
> * @directions: bit mask of slave directions the channel supports.
> * Since the enum dma_transfer_direction is not defined as bit flag for
> * each type, the dma controller should set BIT(<TYPE>) and same
> @@ -509,8 +516,14 @@ enum dma_residue_granularity {
> * resubmitted multiple times
> */
> struct dma_slave_caps {
> - u32 src_addr_widths;
> - u32 dst_addr_widths;
> + struct {
> + DECLARE_DMA_BUS_WIDTHS(src_bus_widths);
> + u32 src_addr_widths;
> + };
> + struct {
> + DECLARE_DMA_BUS_WIDTHS(dst_bus_widths);
> + u32 dst_addr_widths;
> + };
> u32 directions;
> u32 min_burst;
> u32 max_burst;
> @@ -803,10 +816,12 @@ struct dma_filter {
> * @dev: struct device reference for dma mapping api
> * @owner: owner module (automatically set based on the provided dev)
> * @chan_ida: unique channel ID
> - * @src_addr_widths: bit mask of src addr widths the device supports
> + * @src_bus_widths: bitmap of source bus widths the device supports.
> * Width is specified in bytes, e.g. for a device supporting
> - * a width of 4 the mask should have BIT(4) set.
> - * @dst_addr_widths: bit mask of dst addr widths the device supports
> + * a width of 4 the bitmap should have bit 4 set.
> + * @src_addr_widths: legacy bit mask of source bus widths the device supports.
> + * @dst_bus_widths: bitmap of destination bus widths the device supports.
> + * @dst_addr_widths: legacy bit mask of destination bus widths the device supports.
> * @directions: bit mask of slave directions the device supports.
> * Since the enum dma_transfer_direction is not defined as bit flag for
> * each type, the dma controller should set BIT(<TYPE>) and same
> @@ -887,8 +902,14 @@ struct dma_device {
> struct module *owner;
> struct ida chan_ida;
>
> - u32 src_addr_widths;
> - u32 dst_addr_widths;
> + struct {
> + DECLARE_DMA_BUS_WIDTHS(src_bus_widths);
> + u32 src_addr_widths;
> + };
> + struct {
> + DECLARE_DMA_BUS_WIDTHS(dst_bus_widths);
> + u32 dst_addr_widths;
> + };
> u32 directions;
> u32 min_burst;
> u32 max_burst;
> @@ -1678,4 +1699,209 @@ static inline struct device *dmaengine_get_dma_device(struct dma_chan *chan)
> return chan->device->dev;
> }
>
> +static inline enum dma_slave_buswidth
> +__dma_slave_caps_get_width_min(const unsigned long *bus_widths)
> +{
> + enum dma_slave_buswidth width = find_first_bit(bus_widths,
> + DMA_SLAVE_BUSWIDTH_MAX);
> +
> + if (width == DMA_SLAVE_BUSWIDTH_MAX)
> + return DMA_SLAVE_BUSWIDTH_UNDEFINED;
> +
> + return width;
> +}
> +
> +/**
> + * dma_slave_caps_get_src_width_min - get the minimum source bus width
> + * @caps: DMA slave capabilities
> + *
> + * Return: the minimum supported source bus width, or
> + * %DMA_SLAVE_BUSWIDTH_UNDEFINED if no source bus width is advertised.
> + */
> +static inline enum dma_slave_buswidth
> +dma_slave_caps_get_src_width_min(const struct dma_slave_caps *caps)
> +{
> + return __dma_slave_caps_get_width_min(caps->src_bus_widths);
> +}
> +
> +/**
> + * dma_slave_caps_get_dst_width_min - get the minimum destination bus width
> + * @caps: DMA slave capabilities
> + *
> + * Return: the minimum supported destination bus width, or
> + * %DMA_SLAVE_BUSWIDTH_UNDEFINED if no destination bus width is advertised.
> + */
> +static inline enum dma_slave_buswidth
> +dma_slave_caps_get_dst_width_min(const struct dma_slave_caps *caps)
> +{
> + return __dma_slave_caps_get_width_min(caps->dst_bus_widths);
> +}
> +
> +/**
> + * dma_slave_caps_copy_src_widths - copy source bus width capabilities
> + * @caps: DMA slave capabilities
> + * @bus_widths: destination bitmap declared with DECLARE_DMA_BUS_WIDTHS()
> + */
> +static inline void
> +dma_slave_caps_copy_src_widths(const struct dma_slave_caps *caps,
> + unsigned long *bus_widths)
> +{
> + bitmap_copy(bus_widths, caps->src_bus_widths, DMA_SLAVE_BUSWIDTH_MAX);
> +}
> +
> +/**
> + * dma_slave_caps_copy_dst_widths - copy destination bus width capabilities
> + * @caps: DMA slave capabilities
> + * @bus_widths: destination bitmap declared with DECLARE_DMA_BUS_WIDTHS()
> + */
> +static inline void
> +dma_slave_caps_copy_dst_widths(const struct dma_slave_caps *caps,
> + unsigned long *bus_widths)
> +{
> + bitmap_copy(bus_widths, caps->dst_bus_widths, DMA_SLAVE_BUSWIDTH_MAX);
> +}
> +
> +/**
> + * dma_slave_caps_intersect_widths - intersect destination and source widths
> + * @dst_caps: DMA slave capabilities providing destination bus widths
> + * @src_caps: DMA slave capabilities providing source bus widths
> + * @bus_widths: destination bitmap declared with DECLARE_DMA_BUS_WIDTHS()
> + *
> + * Return: true if the resulting bitmap contains at least one common bus width,
> + * false otherwise.
> + */
> +static inline bool
> +dma_slave_caps_intersect_widths(const struct dma_slave_caps *dst_caps,
> + const struct dma_slave_caps *src_caps,
> + unsigned long *bus_widths)
> +{
> + return bitmap_and(bus_widths, dst_caps->dst_bus_widths,
> + src_caps->src_bus_widths, DMA_SLAVE_BUSWIDTH_MAX);
> +}
> +
> +/**
> + * dma_slave_caps_clear_src_width - clear a source bus width capability
> + * @caps: DMA slave capabilities
> + * @width: source bus width to clear
> + */
> +static inline void
> +dma_slave_caps_clear_src_width(struct dma_slave_caps *caps,
> + enum dma_slave_buswidth width)
> +{
> + __clear_bit(width, caps->src_bus_widths);
> + if (width < DMA_SLAVE_BUSWIDTH_32_BYTES)
> + caps->src_addr_widths &= ~BIT(width);
> +}
> +
> +/**
> + * dma_slave_caps_clear_dst_width - clear a destination bus width capability
> + * @caps: DMA slave capabilities
> + * @width: destination bus width to clear
> + */
> +static inline void
> +dma_slave_caps_clear_dst_width(struct dma_slave_caps *caps,
> + enum dma_slave_buswidth width)
> +{
> + __clear_bit(width, caps->dst_bus_widths);
> + if (width < DMA_SLAVE_BUSWIDTH_32_BYTES)
> + caps->dst_addr_widths &= ~BIT(width);
> +}
> +
> +static inline int __dma_set_bus_widths(unsigned long *bus_widths,
> + const enum dma_slave_buswidth *widths,
> + unsigned int n_widths)
> +{
> + for (unsigned int i = 0; i < n_widths; i++) {
> + switch (widths[i]) {
> + case DMA_SLAVE_BUSWIDTH_UNDEFINED:
> + case DMA_SLAVE_BUSWIDTH_1_BYTE:
> + case DMA_SLAVE_BUSWIDTH_2_BYTES:
> + case DMA_SLAVE_BUSWIDTH_3_BYTES:
> + case DMA_SLAVE_BUSWIDTH_4_BYTES:
> + case DMA_SLAVE_BUSWIDTH_8_BYTES:
> + case DMA_SLAVE_BUSWIDTH_16_BYTES:
> + case DMA_SLAVE_BUSWIDTH_32_BYTES:
> + case DMA_SLAVE_BUSWIDTH_64_BYTES:
> + case DMA_SLAVE_BUSWIDTH_128_BYTES:
> + break;
> + default:
> + return -EINVAL;
> + }
> +
> + __set_bit(widths[i], bus_widths);
> + }
> +
> + return 0;
> +}
> +
> +/**
> + * dma_set_src_bus_widths - set supported source bus widths for a DMA device
> + * @device: DMA device
> + * @widths: array of supported source bus widths
> + * @n_widths: number of entries in @widths
> + *
> + * Return: 0 on success, -EINVAL if @widths contains an invalid bus width.
> + */
> +static inline int dma_set_src_bus_widths(struct dma_device *device,
> + const enum dma_slave_buswidth *widths,
> + unsigned int n_widths)
> +{
> + int ret;
> +
> + ret = __dma_set_bus_widths(device->src_bus_widths, widths, n_widths);
> + if (ret)
> + return ret;
> +
> + device->src_addr_widths = bitmap_read(device->src_bus_widths, 0, 32);
> + return 0;
> +}
> +
> +/**
> + * dma_set_dst_bus_widths - set supported destination bus widths for a DMA device
> + * @device: DMA device
> + * @widths: array of supported destination bus widths
> + * @n_widths: number of entries in @widths
> + *
> + * Return: 0 on success, -EINVAL if @widths contains an invalid bus width.
> + */
> +static inline int dma_set_dst_bus_widths(struct dma_device *device,
> + const enum dma_slave_buswidth *widths,
> + unsigned int n_widths)
> +{
> + int ret;
> +
> + ret = __dma_set_bus_widths(device->dst_bus_widths, widths, n_widths);
> + if (ret)
> + return ret;
> +
> + device->dst_addr_widths = bitmap_read(device->dst_bus_widths, 0, 32);
> + return 0;
> +}
> +
> +/**
> + * dma_set_src_bus_width - set a single supported source bus width
> + * @device: DMA device
> + * @width: supported source bus width
> + *
> + * Return: 0 on success, -EINVAL if @width is invalid.
> + */
> +static inline int dma_set_src_bus_width(struct dma_device *device,
> + enum dma_slave_buswidth width)
> +{
> + return dma_set_src_bus_widths(device, &width, 1);
> +}
> +
> +/**
> + * dma_set_dst_bus_width - set a single supported destination bus width
> + * @device: DMA device
> + * @width: supported destination bus width
> + *
> + * Return: 0 on success, -EINVAL if @width is invalid.
> + */
> +static inline int dma_set_dst_bus_width(struct dma_device *device,
> + enum dma_slave_buswidth width)
> +{
> + return dma_set_dst_bus_widths(device, &width, 1);
> +}
> +
> #endif /* DMAENGINE_H */
>
> --
> 2.55.0
>
>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 2/9] dmaengine: dma-axi-dmac: Use bus width capability helpers
2026-07-30 14:23 ` [PATCH 2/9] dmaengine: dma-axi-dmac: Use bus width capability helpers Nuno Sá via B4 Relay
2026-07-30 14:39 ` sashiko-bot
@ 2026-07-30 19:23 ` Frank Li
1 sibling, 0 replies; 26+ messages in thread
From: Frank Li @ 2026-07-30 19:23 UTC (permalink / raw)
To: nuno.sa
Cc: dmaengine, linux-iio, Vinod Koul, Frank Li, Lars-Peter Clausen,
Jonathan Cameron, David Lechner, Andy Shevchenko
On Thu, Jul 30, 2026 at 03:23:09PM +0100, Nuno Sá via B4 Relay wrote:
> [You don't often get email from devnull+nuno.sa.analog.com@kernel.org. Learn why this is important at https://aka.ms/LearnAboutSenderIdentification ]
>
> From: Nuno Sá <nuno.sa@analog.com>
>
> Advertise the source and destination bus widths through the new
> dma_set_{src,dst}_bus_width() helpers instead of open-coding the legacy
> BIT() mask. This moves the driver onto the representation that can
> express widths of 32 bytes and above while keeping the legacy u32 fields
> populated during the transition.
>
> While at it, give the channel width members their proper
> enum dma_slave_buswidth type.
>
> Signed-off-by: Nuno Sá <nuno.sa@analog.com>
> ---
Reviewed-by: Frank Li <Frank.Li@nxp.com>
> drivers/dma/dma-axi-dmac.c | 13 +++++++++----
> 1 file changed, 9 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/dma/dma-axi-dmac.c b/drivers/dma/dma-axi-dmac.c
> index d47ff27e1408..26912330e3c8 100644
> --- a/drivers/dma/dma-axi-dmac.c
> +++ b/drivers/dma/dma-axi-dmac.c
> @@ -152,8 +152,8 @@ struct axi_dmac_chan {
> struct list_head active_descs;
> enum dma_transfer_direction direction;
>
> - unsigned int src_width;
> - unsigned int dest_width;
> + enum dma_slave_buswidth src_width;
> + enum dma_slave_buswidth dest_width;
> unsigned int src_type;
> unsigned int dest_type;
>
> @@ -1262,8 +1262,13 @@ static int axi_dmac_probe(struct platform_device *pdev)
> dma_dev->device_terminate_all = axi_dmac_terminate_all;
> dma_dev->device_synchronize = axi_dmac_synchronize;
> dma_dev->dev = &pdev->dev;
> - dma_dev->src_addr_widths = BIT(dmac->chan.src_width);
> - dma_dev->dst_addr_widths = BIT(dmac->chan.dest_width);
> + ret = dma_set_src_bus_width(dma_dev, dmac->chan.src_width);
> + if (ret)
> + return ret;
> +
> + ret = dma_set_dst_bus_width(dma_dev, dmac->chan.dest_width);
> + if (ret)
> + return ret;
> dma_dev->directions = BIT(dmac->chan.direction);
> dma_dev->residue_granularity = DMA_RESIDUE_GRANULARITY_DESCRIPTOR;
> dma_dev->max_sg_burst = 31; /* 31 SGs maximum in one burst */
>
> --
> 2.55.0
>
>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 3/9] dmaengine: dw-axi-dmac: Use bus width capability helpers
2026-07-30 14:23 ` [PATCH 3/9] dmaengine: dw-axi-dmac: " Nuno Sá via B4 Relay
2026-07-30 14:36 ` sashiko-bot
@ 2026-07-30 19:24 ` Frank Li
1 sibling, 0 replies; 26+ messages in thread
From: Frank Li @ 2026-07-30 19:24 UTC (permalink / raw)
To: nuno.sa
Cc: dmaengine, linux-iio, Vinod Koul, Frank Li, Lars-Peter Clausen,
Jonathan Cameron, David Lechner, Andy Shevchenko
On Thu, Jul 30, 2026 at 03:23:10PM +0100, Nuno Sá via B4 Relay wrote:
> [You don't often get email from devnull+nuno.sa.analog.com@kernel.org. Learn why this is important at https://aka.ms/LearnAboutSenderIdentification ]
>
> From: Nuno Sá <nuno.sa@analog.com>
>
> Advertise the supported bus widths through dma_set_src_bus_widths()
> and dma_set_dst_bus_widths() instead of assigning the legacy u32 masks
> directly. This keeps the driver using the new bitmap representation
> while preserving legacy fields during the transition.
>
> Signed-off-by: Nuno Sá <nuno.sa@analog.com>
> ---
Reviewed-by: Frank Li <Frank.Li@nxp.com>
> drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 39 +++++++++++++++-----------
> 1 file changed, 23 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
> index bcefaff03b5c..69cac7e3625f 100644
> --- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
> +++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
> @@ -33,20 +33,6 @@
> #include "../dmaengine.h"
> #include "../virt-dma.h"
>
> -/*
> - * The set of bus widths supported by the DMA controller. DW AXI DMAC supports
> - * master data bus width up to 512 bits (for both AXI master interfaces), but
> - * it depends on IP block configuration.
> - */
> -#define AXI_DMA_BUSWIDTHS \
> - (DMA_SLAVE_BUSWIDTH_1_BYTE | \
> - DMA_SLAVE_BUSWIDTH_2_BYTES | \
> - DMA_SLAVE_BUSWIDTH_4_BYTES | \
> - DMA_SLAVE_BUSWIDTH_8_BYTES | \
> - DMA_SLAVE_BUSWIDTH_16_BYTES | \
> - DMA_SLAVE_BUSWIDTH_32_BYTES | \
> - DMA_SLAVE_BUSWIDTH_64_BYTES)
> -
> #define AXI_DMA_FLAG_HAS_APB_REGS BIT(0)
> #define AXI_DMA_FLAG_HAS_RESETS BIT(1)
> #define AXI_DMA_FLAG_USE_CFG2 BIT(2)
> @@ -1482,6 +1468,20 @@ static int dw_probe(struct platform_device *pdev)
> unsigned int flags;
> u32 i;
> int ret;
> + /*
> + * The set of bus widths supported by the DMA controller. DW AXI DMAC
> + * supports master data bus width up to 512 bits (for both AXI master
> + * interfaces), but it depends on IP block configuration.
> + */
> + enum dma_slave_buswidth axi_dma_buswidths[] = {
> + DMA_SLAVE_BUSWIDTH_1_BYTE,
> + DMA_SLAVE_BUSWIDTH_2_BYTES,
> + DMA_SLAVE_BUSWIDTH_4_BYTES,
> + DMA_SLAVE_BUSWIDTH_8_BYTES,
> + DMA_SLAVE_BUSWIDTH_16_BYTES,
> + DMA_SLAVE_BUSWIDTH_32_BYTES,
> + DMA_SLAVE_BUSWIDTH_64_BYTES,
> + };
>
> chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
> if (!chip)
> @@ -1565,8 +1565,15 @@ static int dw_probe(struct platform_device *pdev)
>
> /* DMA capabilities */
> dw->dma.max_burst = hdata->axi_rw_burst_len;
> - dw->dma.src_addr_widths = AXI_DMA_BUSWIDTHS;
> - dw->dma.dst_addr_widths = AXI_DMA_BUSWIDTHS;
> + ret = dma_set_src_bus_widths(&dw->dma, axi_dma_buswidths,
> + ARRAY_SIZE(axi_dma_buswidths));
> + if (ret)
> + return ret;
> +
> + ret = dma_set_dst_bus_widths(&dw->dma, axi_dma_buswidths,
> + ARRAY_SIZE(axi_dma_buswidths));
> + if (ret)
> + return ret;
> dw->dma.directions = BIT(DMA_MEM_TO_MEM);
> dw->dma.directions |= BIT(DMA_MEM_TO_DEV) | BIT(DMA_DEV_TO_MEM);
> dw->dma.residue_granularity = DMA_RESIDUE_GRANULARITY_BURST;
>
> --
> 2.55.0
>
>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 4/9] dmaengine: qcom: gpi: Use bus width capability helpers
2026-07-30 14:23 ` [PATCH 4/9] dmaengine: qcom: gpi: " Nuno Sá via B4 Relay
2026-07-30 14:43 ` sashiko-bot
@ 2026-07-30 19:25 ` Frank Li
1 sibling, 0 replies; 26+ messages in thread
From: Frank Li @ 2026-07-30 19:25 UTC (permalink / raw)
To: nuno.sa
Cc: dmaengine, linux-iio, Vinod Koul, Frank Li, Lars-Peter Clausen,
Jonathan Cameron, David Lechner, Andy Shevchenko
On Thu, Jul 30, 2026 at 03:23:11PM +0100, Nuno Sá via B4 Relay wrote:
> [You don't often get email from devnull+nuno.sa.analog.com@kernel.org. Learn why this is important at https://aka.ms/LearnAboutSenderIdentification ]
>
> From: Nuno Sá <nuno.sa@analog.com>
>
> Advertise the single supported source and destination bus width through
> the new dma_set_src_bus_width() and dma_set_dst_bus_width() helpers
> instead of assigning the legacy u32 fields directly.
>
> Signed-off-by: Nuno Sá <nuno.sa@analog.com>
> ---
Reviewed-by: Frank Li <Frank.Li@nxp.com>
> drivers/dma/qcom/gpi.c | 11 +++++++++--
> 1 file changed, 9 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/dma/qcom/gpi.c b/drivers/dma/qcom/gpi.c
> index a5055a6273af..fd45cadce91f 100644
> --- a/drivers/dma/qcom/gpi.c
> +++ b/drivers/dma/qcom/gpi.c
> @@ -2265,8 +2265,15 @@ static int gpi_probe(struct platform_device *pdev)
> /* configure dmaengine apis */
> gpi_dev->dma_device.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
> gpi_dev->dma_device.residue_granularity = DMA_RESIDUE_GRANULARITY_DESCRIPTOR;
> - gpi_dev->dma_device.src_addr_widths = DMA_SLAVE_BUSWIDTH_8_BYTES;
> - gpi_dev->dma_device.dst_addr_widths = DMA_SLAVE_BUSWIDTH_8_BYTES;
> + ret = dma_set_src_bus_width(&gpi_dev->dma_device,
> + DMA_SLAVE_BUSWIDTH_8_BYTES);
> + if (ret)
> + return ret;
> +
> + ret = dma_set_dst_bus_width(&gpi_dev->dma_device,
> + DMA_SLAVE_BUSWIDTH_8_BYTES);
> + if (ret)
> + return ret;
> gpi_dev->dma_device.device_alloc_chan_resources = gpi_alloc_chan_resources;
> gpi_dev->dma_device.device_free_chan_resources = gpi_free_chan_resources;
> gpi_dev->dma_device.device_tx_status = dma_cookie_status;
>
> --
> 2.55.0
>
>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 5/9] dmaengine: stm32-dma3: Use bus width capability helpers
2026-07-30 14:23 ` [PATCH 5/9] dmaengine: stm32-dma3: " Nuno Sá via B4 Relay
2026-07-30 14:35 ` sashiko-bot
@ 2026-07-30 19:26 ` Frank Li
1 sibling, 0 replies; 26+ messages in thread
From: Frank Li @ 2026-07-30 19:26 UTC (permalink / raw)
To: nuno.sa
Cc: dmaengine, linux-iio, Vinod Koul, Frank Li, Lars-Peter Clausen,
Jonathan Cameron, David Lechner, Andy Shevchenko
On Thu, Jul 30, 2026 at 03:23:12PM +0100, Nuno Sá via B4 Relay wrote:
> [You don't often get email from devnull+nuno.sa.analog.com@kernel.org. Learn why this is important at https://aka.ms/LearnAboutSenderIdentification ]
>
> From: Nuno Sá <nuno.sa@analog.com>
>
> Advertise the controller-wide bus width capabilities through the new
> dma_set_src_bus_widths() and dma_set_dst_bus_widths() helpers.
>
> Also update the per-channel capability callback to clear unsupported
> widths through the dma_slave_caps helpers so the bitmap and
> transitional legacy fields stay in sync.
>
> Signed-off-by: Nuno Sá <nuno.sa@analog.com>
> ---
Reviewed-by: Frank Li <Frank.Li@nxp.com>
> drivers/dma/stm32/stm32-dma3.c | 32 ++++++++++++++++++++------------
> 1 file changed, 20 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/dma/stm32/stm32-dma3.c b/drivers/dma/stm32/stm32-dma3.c
> index 4724e7fa0008..b0365a5b341d 100644
> --- a/drivers/dma/stm32/stm32-dma3.c
> +++ b/drivers/dma/stm32/stm32-dma3.c
> @@ -1469,14 +1469,14 @@ static void stm32_dma3_caps(struct dma_chan *c, struct dma_slave_caps *caps)
>
> if (!chan->fifo_size) {
> caps->max_burst = 0;
> - caps->src_addr_widths &= ~BIT(DMA_SLAVE_BUSWIDTH_8_BYTES);
> - caps->dst_addr_widths &= ~BIT(DMA_SLAVE_BUSWIDTH_8_BYTES);
> + dma_slave_caps_clear_src_width(caps, DMA_SLAVE_BUSWIDTH_8_BYTES);
> + dma_slave_caps_clear_dst_width(caps, DMA_SLAVE_BUSWIDTH_8_BYTES);
> } else {
> /* Burst transfer should not exceed half of the fifo size */
> caps->max_burst = chan->max_burst;
> if (caps->max_burst < DMA_SLAVE_BUSWIDTH_8_BYTES) {
> - caps->src_addr_widths &= ~BIT(DMA_SLAVE_BUSWIDTH_8_BYTES);
> - caps->dst_addr_widths &= ~BIT(DMA_SLAVE_BUSWIDTH_8_BYTES);
> + dma_slave_caps_clear_src_width(caps, DMA_SLAVE_BUSWIDTH_8_BYTES);
> + dma_slave_caps_clear_dst_width(caps, DMA_SLAVE_BUSWIDTH_8_BYTES);
> }
> }
> }
> @@ -1737,6 +1737,12 @@ static int stm32_dma3_probe(struct platform_device *pdev)
> u32 master_ports, chan_reserved, i, verr;
> u64 hwcfgr;
> int ret;
> + enum dma_slave_buswidth stm32_dma3_buswidths[] = {
> + DMA_SLAVE_BUSWIDTH_1_BYTE,
> + DMA_SLAVE_BUSWIDTH_2_BYTES,
> + DMA_SLAVE_BUSWIDTH_4_BYTES,
> + DMA_SLAVE_BUSWIDTH_8_BYTES,
> + };
>
> ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL);
> if (!ddata)
> @@ -1775,14 +1781,16 @@ static int stm32_dma3_probe(struct platform_device *pdev)
> * channel, and can only access address at even boundaries, multiple of the buswidth.
> */
> dma_dev->copy_align = DMAENGINE_ALIGN_8_BYTES;
> - dma_dev->src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
> - BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |
> - BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) |
> - BIT(DMA_SLAVE_BUSWIDTH_8_BYTES);
> - dma_dev->dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
> - BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |
> - BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) |
> - BIT(DMA_SLAVE_BUSWIDTH_8_BYTES);
> + ret = dma_set_src_bus_widths(dma_dev, stm32_dma3_buswidths,
> + ARRAY_SIZE(stm32_dma3_buswidths));
> + if (ret)
> + return ret;
> +
> + ret = dma_set_dst_bus_widths(dma_dev, stm32_dma3_buswidths,
> + ARRAY_SIZE(stm32_dma3_buswidths));
> + if (ret)
> + return ret;
> +
> dma_dev->directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV) | BIT(DMA_MEM_TO_MEM);
>
> dma_dev->descriptor_reuse = true;
>
> --
> 2.55.0
>
>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 6/9] iio: buffer-dmaengine: Use dma_slave_caps bus width accessors
2026-07-30 14:23 ` [PATCH 6/9] iio: buffer-dmaengine: Use dma_slave_caps bus width accessors Nuno Sá via B4 Relay
@ 2026-07-30 19:27 ` Frank Li
0 siblings, 0 replies; 26+ messages in thread
From: Frank Li @ 2026-07-30 19:27 UTC (permalink / raw)
To: nuno.sa
Cc: dmaengine, linux-iio, Vinod Koul, Frank Li, Lars-Peter Clausen,
Jonathan Cameron, David Lechner, Andy Shevchenko
On Thu, Jul 30, 2026 at 03:23:13PM +0100, Nuno Sá via B4 Relay wrote:
> [You don't often get email from devnull+nuno.sa.analog.com@kernel.org. Learn why this is important at https://aka.ms/LearnAboutSenderIdentification ]
>
> From: Nuno Sá <nuno.sa@analog.com>
>
> Query the minimum supported source and destination bus widths through
> the new dma_slave_caps_get_{src,dst}_width_min() helpers rather than
> decoding the raw legacy u32 width masks. This keeps the buffer working
> with DMA controllers that advertise bus widths via the new bitmap
> representation.
>
> Signed-off-by: Nuno Sá <nuno.sa@analog.com>
> ---
Reviewed-by: Frank Li <Frank.Li@nxp.com>
> drivers/iio/buffer/industrialio-buffer-dmaengine.c | 15 +++++++--------
> 1 file changed, 7 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/iio/buffer/industrialio-buffer-dmaengine.c b/drivers/iio/buffer/industrialio-buffer-dmaengine.c
> index 98acce909854..855e3662cd3d 100644
> --- a/drivers/iio/buffer/industrialio-buffer-dmaengine.c
> +++ b/drivers/iio/buffer/industrialio-buffer-dmaengine.c
> @@ -229,14 +229,13 @@ static struct iio_buffer *iio_dmaengine_buffer_alloc(struct dma_chan *chan)
> return ERR_PTR(-ENOMEM);
>
> /* Needs to be aligned to the maximum of the minimums */
> - if (caps.src_addr_widths)
> - src_width = __ffs(caps.src_addr_widths);
> - else
> - src_width = 1;
> - if (caps.dst_addr_widths)
> - dest_width = __ffs(caps.dst_addr_widths);
> - else
> - dest_width = 1;
> + src_width = dma_slave_caps_get_src_width_min(&caps);
> + if (src_width == DMA_SLAVE_BUSWIDTH_UNDEFINED)
> + src_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
> + dest_width = dma_slave_caps_get_dst_width_min(&caps);
> + if (dest_width == DMA_SLAVE_BUSWIDTH_UNDEFINED)
> + dest_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
> +
> width = max(src_width, dest_width);
>
> INIT_LIST_HEAD(&dmaengine_buffer->active);
>
> --
> 2.55.0
>
>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 7/9] ALSA: pcm_dmaengine: Use dma_slave_caps bus width helpers
2026-07-30 14:23 ` [PATCH 7/9] ALSA: pcm_dmaengine: Use dma_slave_caps bus width helpers Nuno Sá via B4 Relay
@ 2026-07-30 19:30 ` Frank Li
0 siblings, 0 replies; 26+ messages in thread
From: Frank Li @ 2026-07-30 19:30 UTC (permalink / raw)
To: nuno.sa
Cc: dmaengine, linux-iio, Vinod Koul, Frank Li, Lars-Peter Clausen,
Jonathan Cameron, David Lechner, Andy Shevchenko
On Thu, Jul 30, 2026 at 03:23:14PM +0100, Nuno Sá via B4 Relay wrote:
> [You don't often get email from devnull+nuno.sa.analog.com@kernel.org. Learn why this is important at https://aka.ms/LearnAboutSenderIdentification ]
>
> From: Nuno Sá <nuno.sa@analog.com>
>
> Use the dma_slave_caps bus width helpers instead of reading the legacy
> src_addr_widths and dst_addr_widths masks directly.
>
> Keep the existing default assumption of 1, 2 and 4 byte widths when the
> DMA channel does not report slave capabilities.
>
> Signed-off-by: Nuno Sá <nuno.sa@analog.com>
> ---
Reviewed-by: Frank Li <Frank.Li@nxp.com>
> sound/core/pcm_dmaengine.c | 14 ++++++++------
> 1 file changed, 8 insertions(+), 6 deletions(-)
>
> diff --git a/sound/core/pcm_dmaengine.c b/sound/core/pcm_dmaengine.c
> index 1306b04be171..37468f4643bc 100644
> --- a/sound/core/pcm_dmaengine.c
> +++ b/sound/core/pcm_dmaengine.c
> @@ -409,15 +409,17 @@ int snd_dmaengine_pcm_refine_runtime_hwparams(
> struct dma_chan *chan)
> {
> struct dma_slave_caps dma_caps;
> - u32 addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
> - BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |
> - BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
> + DECLARE_DMA_BUS_WIDTHS(bus_widths) = {};
> snd_pcm_format_t i;
> int ret = 0;
>
> if (!hw || !chan || !dma_data)
> return -EINVAL;
>
> + __set_bit(DMA_SLAVE_BUSWIDTH_1_BYTE, bus_widths);
> + __set_bit(DMA_SLAVE_BUSWIDTH_2_BYTES, bus_widths);
> + __set_bit(DMA_SLAVE_BUSWIDTH_4_BYTES, bus_widths);
> +
> ret = dma_get_slave_caps(chan, &dma_caps);
> if (ret == 0) {
> if (dma_caps.cmd_pause && dma_caps.cmd_resume)
> @@ -426,9 +428,9 @@ int snd_dmaengine_pcm_refine_runtime_hwparams(
> hw->info |= SNDRV_PCM_INFO_BATCH;
>
> if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
> - addr_widths = dma_caps.dst_addr_widths;
> + dma_slave_caps_copy_dst_widths(&dma_caps, bus_widths);
> else
> - addr_widths = dma_caps.src_addr_widths;
> + dma_slave_caps_copy_src_widths(&dma_caps, bus_widths);
> }
>
> /*
> @@ -460,7 +462,7 @@ int snd_dmaengine_pcm_refine_runtime_hwparams(
> case 24:
> case 32:
> case 64:
> - if (addr_widths & (1 << (bits / 8)))
> + if (test_bit(bits / 8, bus_widths))
> hw->formats |= pcm_format_to_bits(i);
> break;
> default:
>
> --
> 2.55.0
>
>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 8/9] spi: dw: Use dma_slave_caps bus width helpers
2026-07-30 14:23 ` [PATCH 8/9] spi: dw: " Nuno Sá via B4 Relay
2026-07-30 14:43 ` sashiko-bot
@ 2026-07-30 19:31 ` Frank Li
1 sibling, 0 replies; 26+ messages in thread
From: Frank Li @ 2026-07-30 19:31 UTC (permalink / raw)
To: nuno.sa
Cc: dmaengine, linux-iio, Vinod Koul, Frank Li, Lars-Peter Clausen,
Jonathan Cameron, David Lechner, Andy Shevchenko
On Thu, Jul 30, 2026 at 03:23:15PM +0100, Nuno Sá via B4 Relay wrote:
> [You don't often get email from devnull+nuno.sa.analog.com@kernel.org. Learn why this is important at https://aka.ms/LearnAboutSenderIdentification ]
>
> From: Nuno Sá <nuno.sa@analog.com>
>
> Store the common TX destination and RX source bus widths in a
> driver-owned DMA bus width bitmap and populate it through the
> dma_slave_caps helper.
>
> This avoids depending on the legacy src_addr_widths and dst_addr_widths
> masks returned by dma_get_slave_caps().
>
> Signed-off-by: Nuno Sá <nuno.sa@analog.com>
> ---
Reviewed-by: Frank Li <Frank.Li@nxp.com>
> drivers/spi/spi-dw-dma.c | 6 +++---
> drivers/spi/spi-dw.h | 3 ++-
> 2 files changed, 5 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/spi/spi-dw-dma.c b/drivers/spi/spi-dw-dma.c
> index fe726b9b1780..2e23ead4a94f 100644
> --- a/drivers/spi/spi-dw-dma.c
> +++ b/drivers/spi/spi-dw-dma.c
> @@ -100,10 +100,10 @@ static int dw_spi_dma_caps_init(struct dw_spi *dws)
>
> /*
> * Assuming both channels belong to the same DMA controller hence the
> - * peripheral side address width capabilities most likely would be
> + * peripheral side bus width capabilities most likely would be
> * the same.
> */
> - dws->dma_addr_widths = tx.dst_addr_widths & rx.src_addr_widths;
> + dma_slave_caps_intersect_widths(&tx, &rx, dws->dma_bus_widths);
>
> return 0;
> }
> @@ -253,7 +253,7 @@ static bool dw_spi_can_dma(struct spi_controller *ctlr,
>
> dma_bus_width = dw_spi_dma_convert_width(dws->n_bytes);
>
> - return dws->dma_addr_widths & BIT(dma_bus_width);
> + return test_bit(dma_bus_width, dws->dma_bus_widths);
> }
>
> static int dw_spi_dma_wait(struct dw_spi *dws, unsigned int len, u32 speed)
> diff --git a/drivers/spi/spi-dw.h b/drivers/spi/spi-dw.h
> index 9cc79c566a70..9111ffc5e9d7 100644
> --- a/drivers/spi/spi-dw.h
> +++ b/drivers/spi/spi-dw.h
> @@ -10,6 +10,7 @@
> #include <linux/scatterlist.h>
> #include <linux/spi/spi-mem.h>
> #include <linux/bitfield.h>
> +#include <linux/dmaengine.h>
>
> /* Synopsys DW SSI IP-core virtual IDs */
> #define DW_PSSI_ID 0
> @@ -190,7 +191,7 @@ struct dw_spi {
> struct dma_chan *rxchan;
> u32 rxburst;
> u32 dma_sg_burst;
> - u32 dma_addr_widths;
> + DECLARE_DMA_BUS_WIDTHS(dma_bus_widths);
> unsigned long dma_chan_busy;
> dma_addr_t dma_addr; /* phy address of the Data register */
> const struct dw_spi_dma_ops *dma_ops;
>
> --
> 2.55.0
>
>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 9/9] dmaengine: Drop legacy bus width fields from dma_slave_caps
2026-07-30 14:23 ` [PATCH 9/9] dmaengine: Drop legacy bus width fields from dma_slave_caps Nuno Sá via B4 Relay
@ 2026-07-30 19:34 ` Frank Li
0 siblings, 0 replies; 26+ messages in thread
From: Frank Li @ 2026-07-30 19:34 UTC (permalink / raw)
To: nuno.sa
Cc: dmaengine, linux-iio, Vinod Koul, Frank Li, Lars-Peter Clausen,
Jonathan Cameron, David Lechner, Andy Shevchenko
On Thu, Jul 30, 2026 at 03:23:16PM +0100, Nuno Sá via B4 Relay wrote:
> [You don't often get email from devnull+nuno.sa.analog.com@kernel.org. Learn why this is important at https://aka.ms/LearnAboutSenderIdentification ]
>
> From: Nuno Sá <nuno.sa@analog.com>
>
> All users of dma_get_slave_caps() that inspect bus width capabilities
> now use bitmap helpers.
>
> Remove the legacy fields from struct dma_slave_caps and stop copying the
> dma_device legacy masks into them.
>
> Keep folding legacy dma_device masks into the returned bitmaps so
> unconverted DMA controller producers continue to work during the
> transition.
which one you kept?
Frank
>
> Signed-off-by: Nuno Sá <nuno.sa@analog.com>
> ---
> drivers/dma/dmaengine.c | 2 --
> include/linux/dmaengine.h | 16 ++--------------
> 2 files changed, 2 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
> index 7be23ba769d0..ee0b8bfc7c97 100644
> --- a/drivers/dma/dmaengine.c
> +++ b/drivers/dma/dmaengine.c
> @@ -592,7 +592,6 @@ int dma_get_slave_caps(struct dma_chan *chan, struct dma_slave_caps *caps)
> if (!device->directions)
> return -ENXIO;
>
> - caps->src_addr_widths = device->src_addr_widths;
> if (bitmap_empty(device->src_bus_widths, DMA_SLAVE_BUSWIDTH_MAX)) {
> bitmap_zero(caps->src_bus_widths, DMA_SLAVE_BUSWIDTH_MAX);
> bitmap_from_arr32(caps->src_bus_widths,
> @@ -602,7 +601,6 @@ int dma_get_slave_caps(struct dma_chan *chan, struct dma_slave_caps *caps)
> DMA_SLAVE_BUSWIDTH_MAX);
> }
>
> - caps->dst_addr_widths = device->dst_addr_widths;
> if (bitmap_empty(device->dst_bus_widths, DMA_SLAVE_BUSWIDTH_MAX)) {
> bitmap_zero(caps->dst_bus_widths, DMA_SLAVE_BUSWIDTH_MAX);
> bitmap_from_arr32(caps->dst_bus_widths,
> diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
> index cea57b166dcb..f37a0559ec5f 100644
> --- a/include/linux/dmaengine.h
> +++ b/include/linux/dmaengine.h
> @@ -495,9 +495,7 @@ enum dma_residue_granularity {
> * @src_bus_widths: bitmap of source bus widths the channel supports.
> * Width is specified in bytes, e.g. for a channel supporting
> * a width of 4 the bitmap should have bit 4 set.
> - * @src_addr_widths: legacy bit mask of source bus widths the channel supports.
> * @dst_bus_widths: bitmap of destination bus widths the channel supports.
> - * @dst_addr_widths: legacy bit mask of destination bus widths the channel supports.
> * @directions: bit mask of slave directions the channel supports.
> * Since the enum dma_transfer_direction is not defined as bit flag for
> * each type, the dma controller should set BIT(<TYPE>) and same
> @@ -516,14 +514,8 @@ enum dma_residue_granularity {
> * resubmitted multiple times
> */
> struct dma_slave_caps {
> - struct {
> - DECLARE_DMA_BUS_WIDTHS(src_bus_widths);
> - u32 src_addr_widths;
> - };
> - struct {
> - DECLARE_DMA_BUS_WIDTHS(dst_bus_widths);
> - u32 dst_addr_widths;
> - };
> + DECLARE_DMA_BUS_WIDTHS(src_bus_widths);
> + DECLARE_DMA_BUS_WIDTHS(dst_bus_widths);
> u32 directions;
> u32 min_burst;
> u32 max_burst;
> @@ -1789,8 +1781,6 @@ dma_slave_caps_clear_src_width(struct dma_slave_caps *caps,
> enum dma_slave_buswidth width)
> {
> __clear_bit(width, caps->src_bus_widths);
> - if (width < DMA_SLAVE_BUSWIDTH_32_BYTES)
> - caps->src_addr_widths &= ~BIT(width);
> }
>
> /**
> @@ -1803,8 +1793,6 @@ dma_slave_caps_clear_dst_width(struct dma_slave_caps *caps,
> enum dma_slave_buswidth width)
> {
> __clear_bit(width, caps->dst_bus_widths);
> - if (width < DMA_SLAVE_BUSWIDTH_32_BYTES)
> - caps->dst_addr_widths &= ~BIT(width);
> }
>
> static inline int __dma_set_bus_widths(unsigned long *bus_widths,
>
> --
> 2.55.0
>
>
^ permalink raw reply [flat|nested] 26+ messages in thread
end of thread, other threads:[~2026-07-30 19:35 UTC | newest]
Thread overview: 26+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-30 14:23 [PATCH 0/9] dmaengine: Support bus widths of 32 bytes and above Nuno Sá via B4 Relay
2026-07-30 14:23 ` [PATCH 1/9] " Nuno Sá via B4 Relay
2026-07-30 14:38 ` sashiko-bot
2026-07-30 19:16 ` Frank Li
2026-07-30 14:23 ` [PATCH 2/9] dmaengine: dma-axi-dmac: Use bus width capability helpers Nuno Sá via B4 Relay
2026-07-30 14:39 ` sashiko-bot
2026-07-30 19:23 ` Frank Li
2026-07-30 14:23 ` [PATCH 3/9] dmaengine: dw-axi-dmac: " Nuno Sá via B4 Relay
2026-07-30 14:36 ` sashiko-bot
2026-07-30 19:24 ` Frank Li
2026-07-30 14:23 ` [PATCH 4/9] dmaengine: qcom: gpi: " Nuno Sá via B4 Relay
2026-07-30 14:43 ` sashiko-bot
2026-07-30 19:25 ` Frank Li
2026-07-30 14:23 ` [PATCH 5/9] dmaengine: stm32-dma3: " Nuno Sá via B4 Relay
2026-07-30 14:35 ` sashiko-bot
2026-07-30 19:26 ` Frank Li
2026-07-30 14:23 ` [PATCH 6/9] iio: buffer-dmaengine: Use dma_slave_caps bus width accessors Nuno Sá via B4 Relay
2026-07-30 19:27 ` Frank Li
2026-07-30 14:23 ` [PATCH 7/9] ALSA: pcm_dmaengine: Use dma_slave_caps bus width helpers Nuno Sá via B4 Relay
2026-07-30 19:30 ` Frank Li
2026-07-30 14:23 ` [PATCH 8/9] spi: dw: " Nuno Sá via B4 Relay
2026-07-30 14:43 ` sashiko-bot
2026-07-30 19:31 ` Frank Li
2026-07-30 14:23 ` [PATCH 9/9] dmaengine: Drop legacy bus width fields from dma_slave_caps Nuno Sá via B4 Relay
2026-07-30 19:34 ` Frank Li
2026-07-30 19:05 ` [PATCH 0/9] dmaengine: Support bus widths of 32 bytes and above Frank Li
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).