DMA Engine development
 help / color / mirror / Atom feed
* Re: [PATCHv3] dmaengine: hsu: use kzalloc_flex()
From: Andy Shevchenko @ 2026-03-31  4:22 UTC (permalink / raw)
  To: Rosen Penev
  Cc: dmaengine, Andy Shevchenko, Vinod Koul, Frank Li, Kees Cook,
	Gustavo A. R. Silva,
	open list:INTEL MID (Mobile Internet Device) PLATFORM,
	open list:KERNEL HARDENING (not covered by other areas):Keyword:b__counted_by(_le|_be)?b
In-Reply-To: <20260330204357.4476-1-rosenp@gmail.com>

On Mon, Mar 30, 2026 at 11:44 PM Rosen Penev <rosenp@gmail.com> wrote:
>
> Simplifies allocations by using a flexible array member in this struct.
>
> Remove hsu_dma_alloc_desc(). It now offers no readability advantages in
> this single usage.
>
> Add __counted_by to get extra runtime analysis. Assign counting variable
> after allocation as required by __counted_by.
>
> Apply the exact same treatment to struct hsu_dma and devm_kzalloc().
>
> Signed-off-by: Rosen Penev <rosenp@gmail.com>
> ---
>  v3: update description.
>  v2: address review comments.

Wait a bit, I still get it unclear. Let's continue the discussion in v2.

-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply

* [PATCH] dmaengine: st_fdma: simplify allocation
From: Rosen Penev @ 2026-03-30 21:15 UTC (permalink / raw)
  To: dmaengine
  Cc: Patrice Chotard, Vinod Koul, Frank Li, Kees Cook,
	Gustavo A. R. Silva, moderated list:ARM/STI ARCHITECTURE,
	open list,
	open list:KERNEL HARDENING (not covered by other areas):Keyword:b__counted_by(_le|_be)?b

Use a flexible array member to combine kzalloc and kcalloc to a single
allocation.

Add __counted_by for extra runtime analysis. Assign counting variable
after allocation as required by __counted_by.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
---
 drivers/dma/st_fdma.c | 27 ++++++++-------------------
 drivers/dma/st_fdma.h |  4 ++--
 2 files changed, 10 insertions(+), 21 deletions(-)

diff --git a/drivers/dma/st_fdma.c b/drivers/dma/st_fdma.c
index d9547017f3bd..3ec0d6731b8d 100644
--- a/drivers/dma/st_fdma.c
+++ b/drivers/dma/st_fdma.c
@@ -710,16 +710,6 @@ static const struct of_device_id st_fdma_match[] = {
 };
 MODULE_DEVICE_TABLE(of, st_fdma_match);
 
-static int st_fdma_parse_dt(struct platform_device *pdev,
-			const struct st_fdma_driverdata *drvdata,
-			struct st_fdma_dev *fdev)
-{
-	snprintf(fdev->fw_name, FW_NAME_SIZE, "fdma_%s_%d.elf",
-		drvdata->name, drvdata->id);
-
-	return of_property_read_u32(pdev->dev.of_node, "dma-channels",
-				    &fdev->nr_channels);
-}
 #define FDMA_DMA_BUSWIDTHS	(BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \
 				 BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \
 				 BIT(DMA_SLAVE_BUSWIDTH_3_BYTES) | \
@@ -742,27 +732,26 @@ static int st_fdma_probe(struct platform_device *pdev)
 	struct st_fdma_dev *fdev;
 	struct device_node *np = pdev->dev.of_node;
 	const struct st_fdma_driverdata *drvdata;
+	u32 nr_channels;
 	int ret, i;
 
 	drvdata = device_get_match_data(&pdev->dev);
 
-	fdev = devm_kzalloc(&pdev->dev, sizeof(*fdev), GFP_KERNEL);
-	if (!fdev)
-		return -ENOMEM;
-
-	ret = st_fdma_parse_dt(pdev, drvdata, fdev);
+	ret = of_property_read_u32(pdev->dev.of_node, "dma-channels", &nr_channels);
 	if (ret) {
 		dev_err(&pdev->dev, "unable to find platform data\n");
-		goto err;
+		return ret;
 	}
 
-	fdev->chans = devm_kcalloc(&pdev->dev, fdev->nr_channels,
-				   sizeof(struct st_fdma_chan), GFP_KERNEL);
-	if (!fdev->chans)
+	fdev = devm_kzalloc(&pdev->dev, struct_size(fdev, chans, nr_channels), GFP_KERNEL);
+	if (!fdev)
 		return -ENOMEM;
 
+	fdev->nr_channels = nr_channels;
 	fdev->dev = &pdev->dev;
 	fdev->drvdata = drvdata;
+	snprintf(fdev->fw_name, FW_NAME_SIZE, "fdma_%s_%d.elf", drvdata->name, drvdata->id);
+
 	platform_set_drvdata(pdev, fdev);
 
 	fdev->irq = platform_get_irq(pdev, 0);
diff --git a/drivers/dma/st_fdma.h b/drivers/dma/st_fdma.h
index f1e746f7bc7d..27ded555879f 100644
--- a/drivers/dma/st_fdma.h
+++ b/drivers/dma/st_fdma.h
@@ -136,13 +136,13 @@ struct st_fdma_dev {
 
 	int irq;
 
-	struct st_fdma_chan *chans;
-
 	spinlock_t dreq_lock;
 	unsigned long dreq_mask;
 
 	u32 nr_channels;
 	char fw_name[FW_NAME_SIZE];
+
+	struct st_fdma_chan chans[] __counted_by(nr_channels);
 };
 
 /* Peripheral Registers*/
-- 
2.53.0


^ permalink raw reply related

* [PATCH] dmaengine: dw-axi-dmac: simplify allocation
From: Rosen Penev @ 2026-03-30 21:11 UTC (permalink / raw)
  To: dmaengine
  Cc: Eugeniy Paltsev, Vinod Koul, Frank Li, Kees Cook,
	Gustavo A. R. Silva, open list,
	open list:KERNEL HARDENING (not covered by other areas):Keyword:b__counted_by(_le|_be)?b

Use a flexible array member with kzalloc_flex to combine allocations.

Add __counted_by for extra runtime analysis.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
---
 drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 8 +-------
 drivers/dma/dw-axi-dmac/dw-axi-dmac.h          | 4 ++--
 2 files changed, 3 insertions(+), 9 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 4d53f077e9d2..d3ca202dc478 100644
--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
@@ -294,15 +294,10 @@ static struct axi_dma_desc *axi_desc_alloc(u32 num)
 {
 	struct axi_dma_desc *desc;
 
-	desc = kzalloc_obj(*desc, GFP_NOWAIT);
+	desc = kzalloc_flex(*desc, hw_desc, num, GFP_NOWAIT);
 	if (!desc)
 		return NULL;
 
-	desc->hw_desc = kzalloc_objs(*desc->hw_desc, num, GFP_NOWAIT);
-	if (!desc->hw_desc) {
-		kfree(desc);
-		return NULL;
-	}
 	desc->nr_hw_descs = num;
 
 	return desc;
@@ -339,7 +334,6 @@ static void axi_desc_put(struct axi_dma_desc *desc)
 		dma_pool_free(chan->desc_pool, hw_desc->lli, hw_desc->llp);
 	}
 
-	kfree(desc->hw_desc);
 	kfree(desc);
 	atomic_sub(descs_put, &chan->descs_allocated);
 	dev_vdbg(chan2dev(chan), "%s: %d descs put, %d still allocated\n",
diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
index 67cc199e24d1..a04a4e03eb3d 100644
--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
@@ -98,14 +98,14 @@ struct axi_dma_hw_desc {
 };
 
 struct axi_dma_desc {
-	struct axi_dma_hw_desc	*hw_desc;
-
 	struct virt_dma_desc		vd;
 	struct axi_dma_chan		*chan;
 	u32				completed_blocks;
 	u32				length;
 	u32				period_len;
 	u32				nr_hw_descs;
+
+	struct axi_dma_hw_desc		hw_desc[] __counted_by(nr_hw_descs);
 };
 
 struct axi_dma_chan_config {
-- 
2.53.0


^ permalink raw reply related

* [PATCHv3] dmaengine: hsu: use kzalloc_flex()
From: Rosen Penev @ 2026-03-30 20:43 UTC (permalink / raw)
  To: dmaengine
  Cc: Andy Shevchenko, Vinod Koul, Frank Li, Kees Cook,
	Gustavo A. R. Silva,
	open list:INTEL MID (Mobile Internet Device) PLATFORM,
	open list:KERNEL HARDENING (not covered by other areas):Keyword:b__counted_by(_le|_be)?b

Simplifies allocations by using a flexible array member in this struct.

Remove hsu_dma_alloc_desc(). It now offers no readability advantages in
this single usage.

Add __counted_by to get extra runtime analysis. Assign counting variable
after allocation as required by __counted_by.

Apply the exact same treatment to struct hsu_dma and devm_kzalloc().

Signed-off-by: Rosen Penev <rosenp@gmail.com>
---
 v3: update description.
 v2: address review comments.
 drivers/dma/hsu/hsu.c | 45 ++++++++++++-------------------------------
 drivers/dma/hsu/hsu.h |  4 ++--
 2 files changed, 14 insertions(+), 35 deletions(-)

diff --git a/drivers/dma/hsu/hsu.c b/drivers/dma/hsu/hsu.c
index f62d60d7bc6b..78a2352ada8c 100644
--- a/drivers/dma/hsu/hsu.c
+++ b/drivers/dma/hsu/hsu.c
@@ -241,28 +241,10 @@ int hsu_dma_do_irq(struct hsu_dma_chip *chip, unsigned short nr, u32 status)
 }
 EXPORT_SYMBOL_GPL(hsu_dma_do_irq);

-static struct hsu_dma_desc *hsu_dma_alloc_desc(unsigned int nents)
-{
-	struct hsu_dma_desc *desc;
-
-	desc = kzalloc_obj(*desc, GFP_NOWAIT);
-	if (!desc)
-		return NULL;
-
-	desc->sg = kzalloc_objs(*desc->sg, nents, GFP_NOWAIT);
-	if (!desc->sg) {
-		kfree(desc);
-		return NULL;
-	}
-
-	return desc;
-}
-
 static void hsu_dma_desc_free(struct virt_dma_desc *vdesc)
 {
 	struct hsu_dma_desc *desc = to_hsu_dma_desc(vdesc);

-	kfree(desc->sg);
 	kfree(desc);
 }

@@ -276,10 +258,15 @@ static struct dma_async_tx_descriptor *hsu_dma_prep_slave_sg(
 	struct scatterlist *sg;
 	unsigned int i;

-	desc = hsu_dma_alloc_desc(sg_len);
+	desc = kzalloc_flex(*desc, sg, sg_len, GFP_NOWAIT);
 	if (!desc)
 		return NULL;

+	desc->nents = sg_len;
+	desc->direction = direction;
+	/* desc->active = 0 by kzalloc */
+	desc->status = DMA_IN_PROGRESS;
+
 	for_each_sg(sgl, sg, sg_len, i) {
 		desc->sg[i].addr = sg_dma_address(sg);
 		desc->sg[i].len = sg_dma_len(sg);
@@ -287,11 +274,6 @@ static struct dma_async_tx_descriptor *hsu_dma_prep_slave_sg(
 		desc->length += sg_dma_len(sg);
 	}

-	desc->nents = sg_len;
-	desc->direction = direction;
-	/* desc->active = 0 by kzalloc */
-	desc->status = DMA_IN_PROGRESS;
-
 	return vchan_tx_prep(&hsuc->vchan, &desc->vdesc, flags);
 }

@@ -428,22 +410,19 @@ int hsu_dma_probe(struct hsu_dma_chip *chip)
 {
 	struct hsu_dma *hsu;
 	void __iomem *addr = chip->regs + chip->offset;
+	unsigned short nr_channels;
 	unsigned short i;
 	int ret;

-	hsu = devm_kzalloc(chip->dev, sizeof(*hsu), GFP_KERNEL);
+	/* Calculate nr_channels from the IO space length */
+	nr_channels = (chip->length - chip->offset) / HSU_DMA_CHAN_LENGTH;
+	hsu = devm_kzalloc(chip->dev, struct_size(hsu, chan, nr_channels), GFP_KERNEL);
 	if (!hsu)
 		return -ENOMEM;

-	chip->hsu = hsu;
-
-	/* Calculate nr_channels from the IO space length */
-	hsu->nr_channels = (chip->length - chip->offset) / HSU_DMA_CHAN_LENGTH;
+	hsu->nr_channels = nr_channels;

-	hsu->chan = devm_kcalloc(chip->dev, hsu->nr_channels,
-				 sizeof(*hsu->chan), GFP_KERNEL);
-	if (!hsu->chan)
-		return -ENOMEM;
+	chip->hsu = hsu;

 	INIT_LIST_HEAD(&hsu->dma.channels);
 	for (i = 0; i < hsu->nr_channels; i++) {
diff --git a/drivers/dma/hsu/hsu.h b/drivers/dma/hsu/hsu.h
index 3bca577b98a1..f6ca1014bccf 100644
--- a/drivers/dma/hsu/hsu.h
+++ b/drivers/dma/hsu/hsu.h
@@ -71,11 +71,11 @@ struct hsu_dma_sg {
 struct hsu_dma_desc {
 	struct virt_dma_desc vdesc;
 	enum dma_transfer_direction direction;
-	struct hsu_dma_sg *sg;
 	unsigned int nents;
 	size_t length;
 	unsigned int active;
 	enum dma_status status;
+	struct hsu_dma_sg sg[] __counted_by(nents);
 };

 static inline struct hsu_dma_desc *to_hsu_dma_desc(struct virt_dma_desc *vdesc)
@@ -115,8 +115,8 @@ struct hsu_dma {
 	struct dma_device		dma;

 	/* channels */
-	struct hsu_dma_chan		*chan;
 	unsigned short			nr_channels;
+	struct hsu_dma_chan		chan[] __counted_by(nr_channels);
 };

 static inline struct hsu_dma *to_hsu_dma(struct dma_device *ddev)
--
2.53.0


^ permalink raw reply related

* Re: [PATCHv2] dmaengine: hsu: use kzalloc_flex()
From: Rosen Penev @ 2026-03-30 20:41 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: dmaengine, Andy Shevchenko, Vinod Koul, Frank Li, Kees Cook,
	Gustavo A. R. Silva,
	open list:INTEL MID (Mobile Internet Device) PLATFORM,
	open list:KERNEL HARDENING (not covered by other areas):Keyword:b__counted_by(_le|_be)?b
In-Reply-To: <CAHp75VfXO1acijFMySQTCtYEE9dRyUMk7xJ7ff7m0hgy42g7=A@mail.gmail.com>

On Mon, Mar 30, 2026 at 1:46 AM Andy Shevchenko
<andy.shevchenko@gmail.com> wrote:
>
> On Sat, Mar 28, 2026 at 9:17 PM Rosen Penev <rosenp@gmail.com> wrote:
> >
> > Simplifies allocations by using a flexible array member in this struct.
> >
> > Remove hsu_dma_alloc_desc(). It now offers no readability advantages in
> > this single usage.
> >
> > Add __counted_by to get extra runtime analysis.
>
> > Apply the exact same treatment to struct hsu_dma and devm_kzalloc.
>
> We refer to the functions as func(): devm_kzalloc().
>
> ...
>
> > -       hsu = devm_kzalloc(chip->dev, sizeof(*hsu), GFP_KERNEL);
> > +       /* Calculate nr_channels from the IO space length */
> > +       nr_channels = (chip->length - chip->offset) / HSU_DMA_CHAN_LENGTH;
> > +       hsu = devm_kzalloc(chip->dev, struct_size(hsu, chan, nr_channels), GFP_KERNEL);
> >         if (!hsu)
> >                 return -ENOMEM;
> >
> > -       chip->hsu = hsu;
> > -
> > -       /* Calculate nr_channels from the IO space length */
> > -       hsu->nr_channels = (chip->length - chip->offset) / HSU_DMA_CHAN_LENGTH;
> > +       hsu->nr_channels = nr_channels;
> >
> > -       hsu->chan = devm_kcalloc(chip->dev, hsu->nr_channels,
> > -                                sizeof(*hsu->chan), GFP_KERNEL);
> > -       if (!hsu->chan)
> > -               return -ENOMEM;
> > +       chip->hsu = hsu;
>
> Don't know these _flex() APIs enough, but can we leave the chip->hsu =
> hsu; in the same place as it's now?
__counted_by requires the first assignment after allocation to be the
counting variable. The _flex macros do this automatically for GCC15
and above.
>
> --
> With Best Regards,
> Andy Shevchenko

^ permalink raw reply

* Re: [PATCH 07/22] ASoC: dt-bindings: renesas,rsnd: Add RZ/G3E support
From: Geert Uytterhoeven @ 2026-03-30 18:47 UTC (permalink / raw)
  To: John Madieu
  Cc: Krzysztof Kozlowski, Kuninori Morimoto, Vinod Koul, Mark Brown,
	Rob Herring, Krzysztof Kozlowski, Michael Turquette, Stephen Boyd,
	Conor Dooley, Frank Li, Liam Girdwood, magnus.damm,
	Thomas Gleixner, Jaroslav Kysela, Takashi Iwai, Philipp Zabel,
	Claudiu.Beznea, Biju Das, Fabrizio Castro, Prabhakar Mahadev Lad,
	John Madieu, linux-renesas-soc@vger.kernel.org,
	linux-clk@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org, dmaengine@vger.kernel.org,
	linux-sound@vger.kernel.org
In-Reply-To: <TY6PR01MB173775E9970A41ED3A7FFF1DAFF52A@TY6PR01MB17377.jpnprd01.prod.outlook.com>

Hi John,

On Mon, 30 Mar 2026 at 17:40, John Madieu <john.madieu.xa@bp.renesas.com> wrote:
> > From: Krzysztof Kozlowski <krzk@kernel.org>
> > > RZ/G3E has a different audio architecture from R-Car Gen2/Gen3/Gen4,
> > > with additional clocks and resets:
> > > - Per-SSI ADG clocks (adg.ssi.0-9)
> > > - SCU related clocks (scu, scu_x2, scu_supply)
> > > - SSIF supply clock
> > > - AUDMAC peri-peri clock
> > > - ADG clock
> > > - Additional resets for SCU, ADG, and AUDMAC peri-peri
> > >
> > > RZ/G3E has 5 DMA controllers that can all be used by audio peripherals.
> > > To allow the DMA core to distribute channels across all available
> > > controllers, increase the maximum number of DMA entries in DVC, SRC,
> > > and SSIU sub-nodes so that multiple providers can be listed with
> > > repeated channel names.
> > >
> > > Signed-off-by: John Madieu <john.madieu.xa@bp.renesas.com>

> > > b/Documentation/devicetree/bindings/sound/renesas,rsnd.yaml
> > > index e8a2acb92646..bc8885c4fa24 100644
> > > --- a/Documentation/devicetree/bindings/sound/renesas,rsnd.yaml
> > > +++ b/Documentation/devicetree/bindings/sound/renesas,rsnd.yaml
> > > @@ -58,6 +58,7 @@ properties:
> > >            - renesas,rcar_sound-gen2
> > >            - renesas,rcar_sound-gen3
> > >            - renesas,rcar_sound-gen4
> > > +          - renesas,rcar_sound-r9a09g047     # RZ/G3E
> >
> > Do not use underscores in compatibles. Previously used wrong style is not
> > the excuse here, just like previously poor code, mistakes, bugs,
> > unreadable approches is not justification to repeat the same.
>
> Got it.
>
> > >    reg:
> > >      minItems: 1
> > > @@ -97,20 +98,22 @@ properties:
> > >
> > >    resets:
> > >      minItems: 1
> > > -    maxItems: 11
> > > +    maxItems: 14
> > >
> > >    reset-names:
> > >      minItems: 1
> > > -    maxItems: 11
> > > +    maxItems: 14
> > >
> > >    clocks:
> > >      description: References to SSI/SRC/MIX/CTU/DVC/AUDIO_CLK clocks.
> > >      minItems: 1
> > > -    maxItems: 31
> > > +    maxItems: 47
> > >
> > >    clock-names:
> > >      description: List of necessary clock names.
> > >      # details are defined below
> > > +    minItems: 1
> > > +    maxItems: 47
> > >
> > >    # ports is below
> > >    port:
> > > @@ -136,9 +139,17 @@ properties:
> > >
> > >          properties:
> > >            dmas:
> > > -            maxItems: 1
> > > +            description:
> > > +              Must contain unique DMA specifiers, one per available
> > > +              DMAC. On RZ/G3E, up to 5 for transmission.
> > > +            minItems: 1
> > > +            maxItems: 5
> > >            dma-names:
> > > -            const: tx
> > > +            minItems: 1
> > > +            maxItems: 5
> > > +            items:
> > > +              enum:
> > > +                - tx
> >
> > Multiple levels, multiple if:then: (further) - I don't find this binding
> > manageable/readable. You should split it, with common binding defining
> > common part of hardware or interface if there is such.
>
> I as you suggested, I'll split it. Just to double check, should I fix
> any bug found in there (like existing compatible strings having underscore
> separators) ? Or should I just split and make sure only new SoC support is
> bug free ?

You cannot just change existing compatible values, as they are part
of the DT ABI.

When you split RZ/G3E off into a separate file, please drop the
"rcar"-part[*] in its compatible value, and move the SoC-specific part
right after the comma.  Perhaps "renesas,r9a09g047-sound"?

[*] Disclaimer: I haven't read the RZ/G3E audio chapter yet.

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply

* Re: [PATCH v5 08/10] dmaengine: tegra: Use iommu-map for stream ID
From: Akhil R @ 2026-03-30 18:20 UTC (permalink / raw)
  To: frank.li
  Cc: Frank.Li, akhilrajeev, conor+dt, devicetree, dmaengine, jonathanh,
	krzk+dt, ldewangan, linux-kernel, linux-tegra, p.zabel, robh,
	thierry.reding, vkoul
In-Reply-To: <acq9z3-lqBHY78v3@lizhi-Precision-Tower-5810>

On Mon, 30 Mar 2026 14:15:43 -0400, Frank Li wrote:
> On Mon, Mar 30, 2026 at 11:32:40PM +0530, Akhil R wrote:
>> On Mon, 30 Mar 2026 12:47:24 -0400, Frank Li wrote:
>> > On Mon, Mar 30, 2026 at 08:14:54PM +0530, Akhil R wrote:
>> >> Use 'iommu-map', when provided, to get the stream ID to be programmed
>> >> for each channel. Iterate over the channels registered and configure
>> >> each channel device separately using of_dma_configure_id() to allow
>> >> it to use a separate IOMMU domain for the transfer. However, do this
>> >> in a second loop since the first loop populates the DMA device channels
>> >> list and async_device_register() registers the channels. Both are
>> >> prerequisites for using the channel device in the next loop.
>> >>
>> >> Channels will continue to use the same global stream ID if the
>> >> 'iommu-map' property is not present in the device tree.
>> >>
>> >> Signed-off-by: Akhil R <akhilrajeev@nvidia.com>
>> >> ---
>> > ...
>> >>
>> >> +	/*
>> >> +	 * Configure stream ID for each channel from the channels registered
>> >> +	 * above. This is done in a separate iteration to ensure that only
>> >> +	 * the channels available and registered for the DMA device are used.
>> >> +	 */
>> >> +	list_for_each_entry(chan, &tdma->dma_dev.channels, device_node) {
>> >> +		chdev = &chan->dev->device;
>> >> +		tdc = to_tegra_dma_chan(chan);
>> >> +
>> >> +		if (use_iommu_map) {
>> >> +			chdev->bus = pdev->dev.bus;
>> >> +			dma_coerce_mask_and_coherent(chdev, DMA_BIT_MASK(cdata->addr_bits));
>> >> +
>> >> +			ret = of_dma_configure_id(chdev, pdev->dev.of_node,
>> >> +						  true, &tdc->id);
>> >> +			if (ret)
>> >> +				return dev_err_probe(chdev, ret,
>> >> +					   "Failed to configure IOMMU for channel %d", tdc->id);
>> >> +
>> >> +			if (!tegra_dev_iommu_get_stream_id(chdev, &stream_id)) {
>> >> +				dev_err(chdev, "Failed to get stream ID for channel %d\n",
>> >> +					tdc->id);
>> >> +				return -EINVAL;
>> >
>> > Can you check similar problem before post patch, here also can use
>> > 	return dev_err_probe()
>>
>> I did notice that, but I thought dev_err_probe is to handle -EPROBE_DEFER
>> and we do not use it when we return a fixed value. It returns -EINVAL here
>> directly.
> 
> even that, still can use return dev_err_probe(chddev, -EINVAL, ...) to
> short your code.

I just saw in the dev_err_probe() description that it is not limited to
-EPROBE_DEFER. Thanks for pointing. I will update the patch.
 
Best Regards,
Akhil

^ permalink raw reply

* Re: [PATCH v5 08/10] dmaengine: tegra: Use iommu-map for stream ID
From: Frank Li @ 2026-03-30 18:15 UTC (permalink / raw)
  To: Akhil R
  Cc: Frank.Li, conor+dt, devicetree, dmaengine, jonathanh, krzk+dt,
	ldewangan, linux-kernel, linux-tegra, p.zabel, robh,
	thierry.reding, vkoul
In-Reply-To: <20260330180240.29906-1-akhilrajeev@nvidia.com>

On Mon, Mar 30, 2026 at 11:32:40PM +0530, Akhil R wrote:
> On Mon, 30 Mar 2026 12:47:24 -0400, Frank Li wrote:
> > On Mon, Mar 30, 2026 at 08:14:54PM +0530, Akhil R wrote:
> >> Use 'iommu-map', when provided, to get the stream ID to be programmed
> >> for each channel. Iterate over the channels registered and configure
> >> each channel device separately using of_dma_configure_id() to allow
> >> it to use a separate IOMMU domain for the transfer. However, do this
> >> in a second loop since the first loop populates the DMA device channels
> >> list and async_device_register() registers the channels. Both are
> >> prerequisites for using the channel device in the next loop.
> >>
> >> Channels will continue to use the same global stream ID if the
> >> 'iommu-map' property is not present in the device tree.
> >>
> >> Signed-off-by: Akhil R <akhilrajeev@nvidia.com>
> >> ---
> > ...
> >>
> >> +	/*
> >> +	 * Configure stream ID for each channel from the channels registered
> >> +	 * above. This is done in a separate iteration to ensure that only
> >> +	 * the channels available and registered for the DMA device are used.
> >> +	 */
> >> +	list_for_each_entry(chan, &tdma->dma_dev.channels, device_node) {
> >> +		chdev = &chan->dev->device;
> >> +		tdc = to_tegra_dma_chan(chan);
> >> +
> >> +		if (use_iommu_map) {
> >> +			chdev->bus = pdev->dev.bus;
> >> +			dma_coerce_mask_and_coherent(chdev, DMA_BIT_MASK(cdata->addr_bits));
> >> +
> >> +			ret = of_dma_configure_id(chdev, pdev->dev.of_node,
> >> +						  true, &tdc->id);
> >> +			if (ret)
> >> +				return dev_err_probe(chdev, ret,
> >> +					   "Failed to configure IOMMU for channel %d", tdc->id);
> >> +
> >> +			if (!tegra_dev_iommu_get_stream_id(chdev, &stream_id)) {
> >> +				dev_err(chdev, "Failed to get stream ID for channel %d\n",
> >> +					tdc->id);
> >> +				return -EINVAL;
> >
> > Can you check similar problem before post patch, here also can use
> > 	return dev_err_probe()
>
> I did notice that, but I thought dev_err_probe is to handle -EPROBE_DEFER
> and we do not use it when we return a fixed value. It returns -EINVAL here
> directly.

even that, still can use return dev_err_probe(chddev, -EINVAL, ...) to
short your code.

Frank

>
> Best Regards,
> Akhil

^ permalink raw reply

* Re: [PATCH v5 08/10] dmaengine: tegra: Use iommu-map for stream ID
From: Akhil R @ 2026-03-30 18:02 UTC (permalink / raw)
  To: frank.li
  Cc: Frank.Li, akhilrajeev, conor+dt, devicetree, dmaengine, jonathanh,
	krzk+dt, ldewangan, linux-kernel, linux-tegra, p.zabel, robh,
	thierry.reding, vkoul
In-Reply-To: <acqpHJM3eilwyMMy@lizhi-Precision-Tower-5810>

On Mon, 30 Mar 2026 12:47:24 -0400, Frank Li wrote:
> On Mon, Mar 30, 2026 at 08:14:54PM +0530, Akhil R wrote:
>> Use 'iommu-map', when provided, to get the stream ID to be programmed
>> for each channel. Iterate over the channels registered and configure
>> each channel device separately using of_dma_configure_id() to allow
>> it to use a separate IOMMU domain for the transfer. However, do this
>> in a second loop since the first loop populates the DMA device channels
>> list and async_device_register() registers the channels. Both are
>> prerequisites for using the channel device in the next loop.
>>
>> Channels will continue to use the same global stream ID if the
>> 'iommu-map' property is not present in the device tree.
>>
>> Signed-off-by: Akhil R <akhilrajeev@nvidia.com>
>> ---
> ...
>>
>> +	/*
>> +	 * Configure stream ID for each channel from the channels registered
>> +	 * above. This is done in a separate iteration to ensure that only
>> +	 * the channels available and registered for the DMA device are used.
>> +	 */
>> +	list_for_each_entry(chan, &tdma->dma_dev.channels, device_node) {
>> +		chdev = &chan->dev->device;
>> +		tdc = to_tegra_dma_chan(chan);
>> +
>> +		if (use_iommu_map) {
>> +			chdev->bus = pdev->dev.bus;
>> +			dma_coerce_mask_and_coherent(chdev, DMA_BIT_MASK(cdata->addr_bits));
>> +
>> +			ret = of_dma_configure_id(chdev, pdev->dev.of_node,
>> +						  true, &tdc->id);
>> +			if (ret)
>> +				return dev_err_probe(chdev, ret,
>> +					   "Failed to configure IOMMU for channel %d", tdc->id);
>> +
>> +			if (!tegra_dev_iommu_get_stream_id(chdev, &stream_id)) {
>> +				dev_err(chdev, "Failed to get stream ID for channel %d\n",
>> +					tdc->id);
>> +				return -EINVAL;
> 
> Can you check similar problem before post patch, here also can use
> 	return dev_err_probe()

I did notice that, but I thought dev_err_probe is to handle -EPROBE_DEFER
and we do not use it when we return a fixed value. It returns -EINVAL here
directly.

Best Regards,
Akhil

^ permalink raw reply

* Re: [PATCH] dmaengine: loongson: loongson2-apb: fix broken bus width validation in ls2x_dmac_detect_burst()
From: David CARLIER @ 2026-03-30 16:57 UTC (permalink / raw)
  To: Frank Li; +Cc: Binbin Zhou, Vinod Koul, Frank Li, Yingkun Meng, dmaengine
In-Reply-To: <acqkrL7CYbr0WmHf@lizhi-Precision-Tower-5810>

Hi,

On Mon, 30 Mar 2026 at 17:28, Frank Li <Frank.li@nxp.com> wrote:
>
> On Wed, Mar 18, 2026 at 04:48:03PM +0000, David Carlier wrote:
> > The bus width validation check in ls2x_dmac_detect_burst() compares raw
> > enum dma_slave_buswidth values (e.g. 4, 8) directly against
> > LDMA_SLAVE_BUSWIDTHS, which is a BIT()-encoded bitmask
> > (BIT(4) | BIT(8) = 0x110). Since 4 & 0x110 == 0 and 8 & 0x110 == 0,
> > the condition is always false for valid bus widths, making the
> > validation dead code.
> >
> > Additionally, the logic was inverted: it rejected configurations where
> > both widths matched valid values, rather than rejecting when neither
> > width is supported.
> >
> > Fix by wrapping the enum values with BIT() before masking (matching the
> > pattern used in sun6i-dma.c) and inverting the logic to reject when
> > neither width is supported by the hardware.
> >
> > Fixes: 71e7d3cb6e55 ("dmaengine: ls2x-apb: New driver for the Loongson LS2X APB DMA controller")
> > Signed-off-by: David Carlier <devnexen@gmail.com>
> > ---
> >  drivers/dma/loongson/loongson2-apb-dma.c | 4 ++--
> >  1 file changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/dma/loongson/loongson2-apb-dma.c b/drivers/dma/loongson/loongson2-apb-dma.c
> > index aceb069e71fc..102c01f993ef 100644
> > --- a/drivers/dma/loongson/loongson2-apb-dma.c
> > +++ b/drivers/dma/loongson/loongson2-apb-dma.c
> > @@ -220,8 +220,8 @@ static size_t ls2x_dmac_detect_burst(struct ls2x_dma_chan *lchan)
> >       u32 maxburst, buswidth;
> >
> >       /* Reject definitely invalid configurations */
> > -     if ((lchan->sconfig.src_addr_width & LDMA_SLAVE_BUSWIDTHS) &&
> > -         (lchan->sconfig.dst_addr_width & LDMA_SLAVE_BUSWIDTHS))
> > +     if (!(BIT(lchan->sconfig.src_addr_width) & LDMA_SLAVE_BUSWIDTHS) &&
> > +         !(BIT(lchan->sconfig.dst_addr_width) & LDMA_SLAVE_BUSWIDTHS))
>
> src_addr_width is enum dma_slave_buswidth, which allow
> DMA_SLAVE_BUSWIDTH_128_BYTES = 128,
>
> BIT(128) will overflow.

Thanks for the review Frank. You're right that BIT() would overflow
for DMA_SLAVE_BUSWIDTH_128_BYTES. While this driver only supports
4-byte and 8-byte widths
  today, relying on BIT() for buswidth validation is fragile. I'll
send a v2 that avoids BIT() altogether — would a direct comparison
against the supported widths work
  for you, or do you have a preferred pattern in mind?

>
> Frank
>
> >               return 0;
> >
> >       if (lchan->sconfig.direction == DMA_MEM_TO_DEV) {
> > --
> > 2.53.0
> >

^ permalink raw reply

* Re: [PATCH v5 08/10] dmaengine: tegra: Use iommu-map for stream ID
From: Frank Li @ 2026-03-30 16:47 UTC (permalink / raw)
  To: Akhil R
  Cc: Vinod Koul, Frank Li, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Thierry Reding, Jonathan Hunter, Laxman Dewangan,
	Philipp Zabel, dmaengine, devicetree, linux-tegra, linux-kernel
In-Reply-To: <20260330144456.13551-9-akhilrajeev@nvidia.com>

On Mon, Mar 30, 2026 at 08:14:54PM +0530, Akhil R wrote:
> Use 'iommu-map', when provided, to get the stream ID to be programmed
> for each channel. Iterate over the channels registered and configure
> each channel device separately using of_dma_configure_id() to allow
> it to use a separate IOMMU domain for the transfer. However, do this
> in a second loop since the first loop populates the DMA device channels
> list and async_device_register() registers the channels. Both are
> prerequisites for using the channel device in the next loop.
>
> Channels will continue to use the same global stream ID if the
> 'iommu-map' property is not present in the device tree.
>
> Signed-off-by: Akhil R <akhilrajeev@nvidia.com>
> ---
...
>
> +	/*
> +	 * Configure stream ID for each channel from the channels registered
> +	 * above. This is done in a separate iteration to ensure that only
> +	 * the channels available and registered for the DMA device are used.
> +	 */
> +	list_for_each_entry(chan, &tdma->dma_dev.channels, device_node) {
> +		chdev = &chan->dev->device;
> +		tdc = to_tegra_dma_chan(chan);
> +
> +		if (use_iommu_map) {
> +			chdev->bus = pdev->dev.bus;
> +			dma_coerce_mask_and_coherent(chdev, DMA_BIT_MASK(cdata->addr_bits));
> +
> +			ret = of_dma_configure_id(chdev, pdev->dev.of_node,
> +						  true, &tdc->id);
> +			if (ret)
> +				return dev_err_probe(chdev, ret,
> +					   "Failed to configure IOMMU for channel %d", tdc->id);
> +
> +			if (!tegra_dev_iommu_get_stream_id(chdev, &stream_id)) {
> +				dev_err(chdev, "Failed to get stream ID for channel %d\n",
> +					tdc->id);
> +				return -EINVAL;

Can you check similar problem before post patch, here also can use
	return dev_err_probe()

Frank
> +			}
> +
> +			chan->dev->chan_dma_dev = true;
> +		}
> +
> +		/* program stream-id for this channel */
> +		tegra_dma_program_sid(tdc, stream_id);
> +		tdc->stream_id = stream_id;
> +	}
> +
>  	ret = devm_of_dma_controller_register(&pdev->dev, pdev->dev.of_node,
>  					      tegra_dma_of_xlate, tdma);
>  	if (ret < 0) {
> --
> 2.50.1
>

^ permalink raw reply

* Re: [PATCHv2] dmaengine: idma64: use kzalloc_flex
From: Frank Li @ 2026-03-30 16:38 UTC (permalink / raw)
  To: Rosen Penev
  Cc: dmaengine, Vinod Koul, Frank Li, Kees Cook, Gustavo A. R. Silva,
	open list,
	open list:KERNEL HARDENING (not covered by other areas):Keyword:b__counted_by(_le|_be)?b
In-Reply-To: <20260321034931.9950-1-rosenp@gmail.com>

On Fri, Mar 20, 2026 at 08:49:31PM -0700, Rosen Penev wrote:
> Simplifies allocations by using a flexible array member in this struct.
>
> Remove idma64_alloc_desc. It now offers no readability advantages in
> this single usage.
>
> Add __counted_by to get extra runtime analysis.
>
> Apply the exact same treatment to struct idma64_dma and devm_kzalloc.
>
> Signed-off-by: Rosen Penev <rosenp@gmail.com>
> ---
>  v2: allocate with GFP_NOWAIT. Was mistakenly removed.
>  drivers/dma/idma64.c | 30 ++++--------------------------
>  drivers/dma/idma64.h |  4 ++--
>  2 files changed, 6 insertions(+), 28 deletions(-)
>
> diff --git a/drivers/dma/idma64.c b/drivers/dma/idma64.c
> index 5fcd1befc92d..d914f50ec309 100644
> --- a/drivers/dma/idma64.c
> +++ b/drivers/dma/idma64.c
> @@ -192,23 +192,6 @@ static irqreturn_t idma64_irq(int irq, void *dev)
>
>  /* ---------------------------------------------------------------------- */
>
> -static struct idma64_desc *idma64_alloc_desc(unsigned int ndesc)
> -{
> -	struct idma64_desc *desc;
> -
> -	desc = kzalloc_obj(*desc, GFP_NOWAIT);
> -	if (!desc)
> -		return NULL;
> -
> -	desc->hw = kzalloc_objs(*desc->hw, ndesc, GFP_NOWAIT);
> -	if (!desc->hw) {
> -		kfree(desc);
> -		return NULL;
> -	}
> -
> -	return desc;
> -}
> -
>  static void idma64_desc_free(struct idma64_chan *idma64c,
>  		struct idma64_desc *desc)
>  {
> @@ -223,7 +206,6 @@ static void idma64_desc_free(struct idma64_chan *idma64c,
>  		} while (i);
>  	}
>
> -	kfree(desc->hw);
>  	kfree(desc);
>  }
>
> @@ -307,10 +289,12 @@ static struct dma_async_tx_descriptor *idma64_prep_slave_sg(
>  	struct scatterlist *sg;
>  	unsigned int i;
>
> -	desc = idma64_alloc_desc(sg_len);
> +	desc = kzalloc_flex(*desc, hw, sg_len, GFP_NOWAIT);
>  	if (!desc)
>  		return NULL;
>
> +	desc->ndesc = sg_len;
> +

This patch is okay, but suggest use sg_nents_for_dma() later

Reviewed-by: Frank Li <Frank.Li@nxp.com>

>

^ permalink raw reply

* Re: [PATCH] dmaengine: loongson: loongson2-apb: fix broken bus width validation in ls2x_dmac_detect_burst()
From: Frank Li @ 2026-03-30 16:28 UTC (permalink / raw)
  To: David Carlier; +Cc: Binbin Zhou, Vinod Koul, Frank Li, Yingkun Meng, dmaengine
In-Reply-To: <20260318164803.14351-1-devnexen@gmail.com>

On Wed, Mar 18, 2026 at 04:48:03PM +0000, David Carlier wrote:
> The bus width validation check in ls2x_dmac_detect_burst() compares raw
> enum dma_slave_buswidth values (e.g. 4, 8) directly against
> LDMA_SLAVE_BUSWIDTHS, which is a BIT()-encoded bitmask
> (BIT(4) | BIT(8) = 0x110). Since 4 & 0x110 == 0 and 8 & 0x110 == 0,
> the condition is always false for valid bus widths, making the
> validation dead code.
>
> Additionally, the logic was inverted: it rejected configurations where
> both widths matched valid values, rather than rejecting when neither
> width is supported.
>
> Fix by wrapping the enum values with BIT() before masking (matching the
> pattern used in sun6i-dma.c) and inverting the logic to reject when
> neither width is supported by the hardware.
>
> Fixes: 71e7d3cb6e55 ("dmaengine: ls2x-apb: New driver for the Loongson LS2X APB DMA controller")
> Signed-off-by: David Carlier <devnexen@gmail.com>
> ---
>  drivers/dma/loongson/loongson2-apb-dma.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/dma/loongson/loongson2-apb-dma.c b/drivers/dma/loongson/loongson2-apb-dma.c
> index aceb069e71fc..102c01f993ef 100644
> --- a/drivers/dma/loongson/loongson2-apb-dma.c
> +++ b/drivers/dma/loongson/loongson2-apb-dma.c
> @@ -220,8 +220,8 @@ static size_t ls2x_dmac_detect_burst(struct ls2x_dma_chan *lchan)
>  	u32 maxburst, buswidth;
>
>  	/* Reject definitely invalid configurations */
> -	if ((lchan->sconfig.src_addr_width & LDMA_SLAVE_BUSWIDTHS) &&
> -	    (lchan->sconfig.dst_addr_width & LDMA_SLAVE_BUSWIDTHS))
> +	if (!(BIT(lchan->sconfig.src_addr_width) & LDMA_SLAVE_BUSWIDTHS) &&
> +	    !(BIT(lchan->sconfig.dst_addr_width) & LDMA_SLAVE_BUSWIDTHS))

src_addr_width is enum dma_slave_buswidth, which allow
DMA_SLAVE_BUSWIDTH_128_BYTES = 128,

BIT(128) will overflow.

Frank

>  		return 0;
>
>  	if (lchan->sconfig.direction == DMA_MEM_TO_DEV) {
> --
> 2.53.0
>

^ permalink raw reply

* Re: [PATCH V2 5/5] dmaengine: xilinx_dma: Add support for reporting transfer size to AXI DMA / MCDMA client when app fields are unavailable
From: Frank Li @ 2026-03-30 16:04 UTC (permalink / raw)
  To: Srinivas Neeli
  Cc: Vinod Koul, git, Frank Li, Michal Simek, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Suraj Gupta,
	Radhey Shyam Pandey, Thomas Gessler, Folker Schwesinger,
	Tomi Valkeinen, Kees Cook, Abin Joseph, dmaengine, devicetree,
	linux-arm-kernel, linux-kernel
In-Reply-To: <20260313062533.421249-6-srinivas.neeli@amd.com>

On Fri, Mar 13, 2026 at 11:55:33AM +0530, Srinivas Neeli wrote:
> From: Suraj Gupta <suraj.gupta2@amd.com>
>
> The AXI4-stream status and control interface is optional in the AXI DMA /
> MCDMA IP design; when it is not present, app fields are not available in
> DMA descriptor. In such cases, the transferred byte count can be
> communicated to the client using the status field (bits 0-25) of
> AXI DMA / MCDMA descriptor.
>
> Add a xferred_bytes field to struct xilinx_dma_tx_descriptor to record the
> number of bytes transferred for each transaction. The value is calculated
> using the existing xilinx_dma_get_residue() function, which traverses all
> hardware descriptors associated with the async transaction descriptor,
> avoiding redundant traversal.

Can you split this change to new patch?

Frank
>
> The driver uses the xlnx,include-stscntrl-strm device tree property to
> determine if the status/control stream interface is present and selects the
> appropriate metadata source accordingly.
>
> Signed-off-by: Suraj Gupta <suraj.gupta2@amd.com>
> ---
>  drivers/dma/xilinx/xilinx_dma.c | 28 ++++++++++++++++++++++++----
>  1 file changed, 24 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c
> index 52203d44e7a4..f5ef03a1297c 100644
> --- a/drivers/dma/xilinx/xilinx_dma.c
> +++ b/drivers/dma/xilinx/xilinx_dma.c
> @@ -380,6 +380,8 @@ struct xilinx_cdma_tx_segment {
>   * @cyclic: Check for cyclic transfers.
>   * @err: Whether the descriptor has an error.
>   * @residue: Residue of the completed descriptor
> + * @xferred_bytes: Number of bytes transferred by this transaction
> + *                 descriptor.
>   */
>  struct xilinx_dma_tx_descriptor {
>  	struct xilinx_dma_chan *chan;
> @@ -389,6 +391,7 @@ struct xilinx_dma_tx_descriptor {
>  	bool cyclic;
>  	bool err;
>  	u32 residue;
> +	u32 xferred_bytes;
>  };
>
>  /**
> @@ -515,6 +518,7 @@ struct xilinx_dma_config {
>   * @mm2s_chan_id: DMA mm2s channel identifier
>   * @max_buffer_len: Max buffer length
>   * @has_axistream_connected: AXI DMA connected to AXI Stream IP
> + * @has_stsctrl_stream: AXI4-stream status and control interface is enabled
>   */
>  struct xilinx_dma_device {
>  	void __iomem *regs;
> @@ -534,6 +538,7 @@ struct xilinx_dma_device {
>  	u32 mm2s_chan_id;
>  	u32 max_buffer_len;
>  	bool has_axistream_connected;
> +	bool has_stsctrl_stream;
>  };
>
>  /* Macros */
> @@ -672,8 +677,12 @@ static void *xilinx_dma_get_metadata_ptr(struct dma_async_tx_descriptor *tx,
>  				       struct xilinx_axidma_tx_segment, node);
>  		metadata_ptr = seg->hw.app;
>  	}
> -	*max_len = *payload_len = sizeof(u32) * XILINX_DMA_NUM_APP_WORDS;
> -	return metadata_ptr;
> +	if (desc->chan->xdev->has_stsctrl_stream) {
> +		*max_len = *payload_len = sizeof(u32) * XILINX_DMA_NUM_APP_WORDS;
> +		return metadata_ptr;
> +	}
> +	*max_len = *payload_len = sizeof(desc->xferred_bytes);
> +	return (void *)&desc->xferred_bytes;
>  }
>
>  static struct dma_descriptor_metadata_ops xilinx_dma_metadata_ops = {
> @@ -864,6 +873,7 @@ xilinx_dma_alloc_tx_descriptor(struct xilinx_dma_chan *chan)
>  		return NULL;
>
>  	desc->chan = chan;
> +	desc->xferred_bytes = 0;
>  	INIT_LIST_HEAD(&desc->segments);
>
>  	return desc;
> @@ -1014,6 +1024,7 @@ static u32 xilinx_dma_get_residue(struct xilinx_dma_chan *chan,
>  	struct xilinx_aximcdma_desc_hw *aximcdma_hw;
>  	struct list_head *entry;
>  	u32 residue = 0;
> +	u32 xferred = 0;
>
>  	list_for_each(entry, &desc->segments) {
>  		if (chan->xdev->dma_config->dmatype == XDMA_TYPE_CDMA) {
> @@ -1031,25 +1042,32 @@ static u32 xilinx_dma_get_residue(struct xilinx_dma_chan *chan,
>  			axidma_hw = &axidma_seg->hw;
>  			residue += (axidma_hw->control - axidma_hw->status) &
>  				   chan->xdev->max_buffer_len;
> +			xferred += axidma_hw->status & chan->xdev->max_buffer_len;
>  		} else {
>  			aximcdma_seg =
>  				list_entry(entry,
>  					   struct xilinx_aximcdma_tx_segment,
>  					   node);
>  			aximcdma_hw = &aximcdma_seg->hw;
> -			if (chan->direction == DMA_DEV_TO_MEM)
> +			if (chan->direction == DMA_DEV_TO_MEM) {
>  				residue +=
>  					(aximcdma_hw->control -
>  					 aximcdma_hw->s2mm_status) &
>  					chan->xdev->max_buffer_len;
> -			else
> +				xferred += aximcdma_hw->s2mm_status &
> +					chan->xdev->max_buffer_len;
> +			} else {
>  				residue +=
>  					(aximcdma_hw->control -
>  					 aximcdma_hw->mm2s_status) &
>  					chan->xdev->max_buffer_len;
> +				xferred += aximcdma_hw->mm2s_status &
> +					chan->xdev->max_buffer_len;
> +			}
>  		}
>  	}
>
> +	desc->xferred_bytes = xferred;
>  	return residue;
>  }
>
> @@ -3284,6 +3302,8 @@ static int xilinx_dma_probe(struct platform_device *pdev)
>  	    xdev->dma_config->dmatype == XDMA_TYPE_AXIMCDMA) {
>  		xdev->has_axistream_connected =
>  			of_property_read_bool(node, "xlnx,axistream-connected");
> +		xdev->has_stsctrl_stream =
> +			of_property_read_bool(node, "xlnx,include-stscntrl-strm");
>  	}
>
>  	if (xdev->dma_config->dmatype == XDMA_TYPE_VDMA) {
> --
> 2.43.0
>

^ permalink raw reply

* Re: [PATCH V2 3/5] dmaengine: xilinx_dma: Extend metadata handling for AXI MCDMA
From: Frank Li @ 2026-03-30 15:58 UTC (permalink / raw)
  To: Srinivas Neeli
  Cc: Vinod Koul, git, Frank Li, Michal Simek, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Suraj Gupta,
	Radhey Shyam Pandey, Thomas Gessler, Folker Schwesinger,
	Tomi Valkeinen, Kees Cook, Abin Joseph, dmaengine, devicetree,
	linux-arm-kernel, linux-kernel
In-Reply-To: <20260313062533.421249-4-srinivas.neeli@amd.com>

On Fri, Mar 13, 2026 at 11:55:31AM +0530, Srinivas Neeli wrote:
> From: Suraj Gupta <suraj.gupta2@amd.com>
>
> Extend probe logic to detect AXI Stream connections for MCDMA. When
> an AXI Stream interface is present, metadata operations are enabled for
> the MCDMA channel. The xilinx_dma_get_metadata_ptr() is enhanced to
> retrieve metadata directly from MCDMA descriptors.

Need extra empty line between paragraph

> Add corresponding channel reference in struct xilinx_dma_tx_descriptor to
> retrieve associated channel.
> These changes ensure proper metadata handling and accurate transfer
> size reporting for MCDMA transfers.
>
> Signed-off-by: Suraj Gupta <suraj.gupta2@amd.com>
> Co-developed-by: Srinivas Neeli <srinivas.neeli@amd.com>
> Signed-off-by: Srinivas Neeli <srinivas.neeli@amd.com>
> ---
>  drivers/dma/xilinx/xilinx_dma.c | 30 +++++++++++++++++++++++++-----
>  1 file changed, 25 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c
> index 00200b4c2372..52203d44e7a4 100644
> --- a/drivers/dma/xilinx/xilinx_dma.c
> +++ b/drivers/dma/xilinx/xilinx_dma.c
> @@ -222,6 +222,8 @@
>  #define XILINX_MCDMA_BD_EOP			BIT(30)
>  #define XILINX_MCDMA_BD_SOP			BIT(31)
>
> +struct xilinx_dma_chan;
> +
>  /**
>   * struct xilinx_vdma_desc_hw - Hardware Descriptor
>   * @next_desc: Next Descriptor Pointer @0x00
> @@ -371,6 +373,7 @@ struct xilinx_cdma_tx_segment {
>
>  /**
>   * struct xilinx_dma_tx_descriptor - Per Transaction structure
> + * @chan: DMA channel for which this descriptor is allocated
>   * @async_tx: Async transaction descriptor
>   * @segments: TX segments list
>   * @node: Node in the channel descriptors list
> @@ -379,6 +382,7 @@ struct xilinx_cdma_tx_segment {
>   * @residue: Residue of the completed descriptor
>   */
>  struct xilinx_dma_tx_descriptor {
> +	struct xilinx_dma_chan *chan;

async_tx already include dma_chan's information.

Frank

^ permalink raw reply

* Re: [PATCH V2 2/5] dmaengine: xilinx_dma: Move descriptors to done list based on completion bit
From: Frank Li @ 2026-03-30 15:54 UTC (permalink / raw)
  To: Srinivas Neeli
  Cc: Vinod Koul, git, Frank Li, Michal Simek, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Suraj Gupta,
	Radhey Shyam Pandey, Thomas Gessler, Folker Schwesinger,
	Tomi Valkeinen, Kees Cook, Abin Joseph, dmaengine, devicetree,
	linux-arm-kernel, linux-kernel
In-Reply-To: <20260313062533.421249-3-srinivas.neeli@amd.com>

On Fri, Mar 13, 2026 at 11:55:30AM +0530, Srinivas Neeli wrote:
> In AXIMCDMA scatter-gather mode, the hardware sets the completion bit when
> a transfer finishes. The driver now checks this bit to free descriptors
> from the active list and move them to the done list.

Add check complete bit because irq may be triggered before a configured
threshold is reached when interrupt delay timeout Dly_IrqEn is enabled.

Frank

> This is required when interrupt delay timeout Dly_IrqEn is enabled,
> as interrupts may be triggered before the configured threshold is reached,
> even if not all descriptors have completed.
>
> Signed-off-by: Srinivas Neeli <srinivas.neeli@amd.com>
> ---
>  drivers/dma/xilinx/xilinx_dma.c | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
>
> diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c
> index 4a83492f2435..00200b4c2372 100644
> --- a/drivers/dma/xilinx/xilinx_dma.c
> +++ b/drivers/dma/xilinx/xilinx_dma.c
> @@ -1762,6 +1762,18 @@ static void xilinx_dma_complete_descriptor(struct xilinx_dma_chan *chan)
>  					      struct xilinx_axidma_tx_segment, node);
>  			if (!(seg->hw.status & XILINX_DMA_BD_COMP_MASK) && chan->has_sg)
>  				break;
> +		} else if (chan->xdev->dma_config->dmatype == XDMA_TYPE_AXIMCDMA) {
> +			struct xilinx_aximcdma_tx_segment *seg;
> +			bool completed;
> +
> +			seg = list_last_entry(&desc->segments,
> +					      struct xilinx_aximcdma_tx_segment,
> +					      node);
> +			completed = (chan->direction == DMA_DEV_TO_MEM) ?
> +				(seg->hw.s2mm_status & XILINX_DMA_BD_COMP_MASK) :
> +				(seg->hw.mm2s_status & XILINX_DMA_BD_COMP_MASK);
> +			if (!completed)
> +				break;
>  		}
>  		if (chan->has_sg && chan->xdev->dma_config->dmatype !=
>  		    XDMA_TYPE_VDMA)
> --
> 2.43.0
>

^ permalink raw reply

* Re: [PATCH V2 1/5] dmaengine: xilinx_dma: Fix MCDMA descriptor fields for MM2S vs S2MM
From: Frank Li @ 2026-03-30 15:46 UTC (permalink / raw)
  To: Srinivas Neeli
  Cc: Vinod Koul, git, Frank Li, Michal Simek, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Suraj Gupta,
	Radhey Shyam Pandey, Thomas Gessler, Folker Schwesinger,
	Tomi Valkeinen, Kees Cook, Abin Joseph, dmaengine, devicetree,
	linux-arm-kernel, linux-kernel
In-Reply-To: <20260313062533.421249-2-srinivas.neeli@amd.com>

On Fri, Mar 13, 2026 at 11:55:29AM +0530, Srinivas Neeli wrote:
> The MCDMA BD format differs between MM2S and S2MM directions, but the

Can you use DMA_DEV_TO_MEM and DMA_MEM_TO_DEV instead of MM2S and S2MM?
or memory to slave, at least first place need extend term MM2S(memory to
slave).

> driver was using generic 'status' and 'sideband_status' fields for both.
> This could lead to incorrect residue calculations when the hardware
> updates direction-specific fields.

driver was using generic 'status' and 'sideband_status' fields for both,
which lead ... (use Affirmative Tone)

>
> Refactor the descriptor structure to use unions with direction-specific
> field names (mm2s_status/s2mm_status, etc.). This ensures the driver

Ensure .. (needn't this)

Frank
> accesses the correct hardware fields based on channel direction and
> matches the hardware documentation.
>
> Fixes: 6ccd692bfb7f ("dmaengine: xilinx_dma: Add Xilinx AXI MCDMA Engine driver support")
> Signed-off-by: Srinivas Neeli <srinivas.neeli@amd.com>
> ---
>  drivers/dma/xilinx/xilinx_dma.c | 29 ++++++++++++++++++++++-------
>  1 file changed, 22 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c
> index b53292e02448..4a83492f2435 100644
> --- a/drivers/dma/xilinx/xilinx_dma.c
> +++ b/drivers/dma/xilinx/xilinx_dma.c
> @@ -275,8 +275,10 @@ struct xilinx_axidma_desc_hw {
>   * @buf_addr_msb: MSB of Buffer address @0x0C
>   * @rsvd: Reserved field @0x10
>   * @control: Control Information field @0x14
> - * @status: Status field @0x18
> - * @sideband_status: Status of sideband signals @0x1C
> + * @mm2s_ctrl_sideband: Sideband control info for mm2s @0x18
> + * @s2mm_status: Status field for s2mm @0x18
> + * @mm2s_status: Status field for mm2s @0x1C
> + * @s2mm_sideband_status: Sideband status for s2mm @0x1C
>   * @app: APP Fields @0x20 - 0x30
>   */
>  struct xilinx_aximcdma_desc_hw {
> @@ -286,8 +288,14 @@ struct xilinx_aximcdma_desc_hw {
>  	u32 buf_addr_msb;
>  	u32 rsvd;
>  	u32 control;
> -	u32 status;
> -	u32 sideband_status;
> +	union {
> +		u32 mm2s_ctrl_sideband;
> +		u32 s2mm_status;
> +	};
> +	union {
> +		u32 mm2s_status;
> +		u32 s2mm_sideband_status;
> +	};
>  	u32 app[XILINX_DMA_NUM_APP_WORDS];
>  } __aligned(64);
>
> @@ -1013,9 +1021,16 @@ static u32 xilinx_dma_get_residue(struct xilinx_dma_chan *chan,
>  					   struct xilinx_aximcdma_tx_segment,
>  					   node);
>  			aximcdma_hw = &aximcdma_seg->hw;
> -			residue +=
> -				(aximcdma_hw->control - aximcdma_hw->status) &
> -				chan->xdev->max_buffer_len;
> +			if (chan->direction == DMA_DEV_TO_MEM)
> +				residue +=
> +					(aximcdma_hw->control -
> +					 aximcdma_hw->s2mm_status) &
> +					chan->xdev->max_buffer_len;
> +			else
> +				residue +=
> +					(aximcdma_hw->control -
> +					 aximcdma_hw->mm2s_status) &
> +					chan->xdev->max_buffer_len;
>  		}
>  	}
>
> --
> 2.43.0
>

^ permalink raw reply

* RE: [PATCH 07/22] ASoC: dt-bindings: renesas,rsnd: Add RZ/G3E support
From: John Madieu @ 2026-03-30 15:39 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Geert Uytterhoeven, Kuninori Morimoto, Vinod Koul, Mark Brown,
	Rob Herring, Krzysztof Kozlowski, Michael Turquette, Stephen Boyd,
	Conor Dooley, Frank Li, Liam Girdwood, magnus.damm,
	Thomas Gleixner, Jaroslav Kysela, Takashi Iwai, Philipp Zabel,
	Claudiu.Beznea, Biju Das, Fabrizio Castro, Prabhakar Mahadev Lad,
	John Madieu, linux-renesas-soc@vger.kernel.org,
	linux-clk@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org, dmaengine@vger.kernel.org,
	linux-sound@vger.kernel.org
In-Reply-To: <20260320-peculiar-cat-of-acumen-c6f6b3@quoll>

Hi Krzysztof,

Thanks for the review.

> -----Original Message-----
> From: Krzysztof Kozlowski <krzk@kernel.org>
> Sent: Friday, March 20, 2026 10:30 AM
> To: John Madieu <john.madieu.xa@bp.renesas.com>
> Subject: Re: [PATCH 07/22] ASoC: dt-bindings: renesas,rsnd: Add RZ/G3E
> support
> 
> On Thu, Mar 19, 2026 at 04:53:19PM +0100, John Madieu wrote:
> > Add support for the RZ/G3E (R9A09G047) SoC audio subsystem.
> >
> > RZ/G3E has a different audio architecture from R-Car Gen2/Gen3/Gen4,
> > with additional clocks and resets:
> > - Per-SSI ADG clocks (adg.ssi.0-9)
> > - SCU related clocks (scu, scu_x2, scu_supply)
> > - SSIF supply clock
> > - AUDMAC peri-peri clock
> > - ADG clock
> > - Additional resets for SCU, ADG, and AUDMAC peri-peri
> >
> > RZ/G3E has 5 DMA controllers that can all be used by audio peripherals.
> > To allow the DMA core to distribute channels across all available
> > controllers, increase the maximum number of DMA entries in DVC, SRC,
> > and SSIU sub-nodes so that multiple providers can be listed with
> > repeated channel names.
> >
> > Signed-off-by: John Madieu <john.madieu.xa@bp.renesas.com>
> > ---
> >  .../bindings/sound/renesas,rsnd.yaml          | 169 +++++++++++++++---
> >  1 file changed, 148 insertions(+), 21 deletions(-)
> >
> > diff --git a/Documentation/devicetree/bindings/sound/renesas,rsnd.yaml
> > b/Documentation/devicetree/bindings/sound/renesas,rsnd.yaml
> > index e8a2acb92646..bc8885c4fa24 100644
> > --- a/Documentation/devicetree/bindings/sound/renesas,rsnd.yaml
> > +++ b/Documentation/devicetree/bindings/sound/renesas,rsnd.yaml
> > @@ -58,6 +58,7 @@ properties:
> >            - renesas,rcar_sound-gen2
> >            - renesas,rcar_sound-gen3
> >            - renesas,rcar_sound-gen4
> > +          - renesas,rcar_sound-r9a09g047     # RZ/G3E
> 
> Do not use underscores in compatibles. Previously used wrong style is not
> the excuse here, just like previously poor code, mistakes, bugs,
> unreadable approches is not justification to repeat the same.
> 

Got it.

> >
> >    reg:
> >      minItems: 1
> > @@ -97,20 +98,22 @@ properties:
> >
> >    resets:
> >      minItems: 1
> > -    maxItems: 11
> > +    maxItems: 14
> >
> >    reset-names:
> >      minItems: 1
> > -    maxItems: 11
> > +    maxItems: 14
> >
> >    clocks:
> >      description: References to SSI/SRC/MIX/CTU/DVC/AUDIO_CLK clocks.
> >      minItems: 1
> > -    maxItems: 31
> > +    maxItems: 47
> >
> >    clock-names:
> >      description: List of necessary clock names.
> >      # details are defined below
> > +    minItems: 1
> > +    maxItems: 47
> >
> >    # ports is below
> >    port:
> > @@ -136,9 +139,17 @@ properties:
> >
> >          properties:
> >            dmas:
> > -            maxItems: 1
> > +            description:
> > +              Must contain unique DMA specifiers, one per available
> > +              DMAC. On RZ/G3E, up to 5 for transmission.
> > +            minItems: 1
> > +            maxItems: 5
> >            dma-names:
> > -            const: tx
> > +            minItems: 1
> > +            maxItems: 5
> > +            items:
> > +              enum:
> > +                - tx
> 
> Multiple levels, multiple if:then: (further) - I don't find this binding
> manageable/readable. You should split it, with common binding defining
> common part of hardware or interface if there is such.

I as you suggested, I'll split it. Just to double check, should I fix
any bug found in there (like existing compatible strings having underscore
separators) ? Or should I just split and make sure only new SoC support is
bug free ?

Regards,
John


> 
> Best regards,
> Krzysztof


^ permalink raw reply

* Re: [PATCH v2 4/4] dmaengine: dma-axi-dmac: Defer freeing DMA descriptors
From: Frank Li @ 2026-03-30 15:24 UTC (permalink / raw)
  To: Nuno Sá
  Cc: dmaengine, linux-kernel, Lars-Peter Clausen, Vinod Koul, Frank Li,
	Eliza Balas
In-Reply-To: <20260327-dma-dmac-handle-vunmap-v2-4-021f95f0e87b@analog.com>

On Fri, Mar 27, 2026 at 04:58:41PM +0000, Nuno Sá wrote:
> From: Eliza Balas <eliza.balas@analog.com>
>
> This IP core can be used in architectures (like Microblaze) where DMA
> descriptors are allocated with vmalloc().

strage, why use vmalloc()?

Frank

>  Hence, given that freeing the
> descriptors happen in softirq context, vunmpap() will BUG().
>
> To solve the above, we setup a work item during allocation of the
> descriptors and schedule in softirq context. Hence, the actual freeing
> happens in threaded context.
>
> Also note that to account for the possible race where the struct axi_dmac
> object is gone between scheduling the work and actually running it, we
> now save and get a reference of struct device when allocating the
> descriptor (given that's all we need in axi_dmac_free_desc()) and
> release it in axi_dmac_free_desc().
>
> Signed-off-by: Eliza Balas <eliza.balas@analog.com>
> Co-developed-by: Nuno Sá <nuno.sa@analog.com>
> Signed-off-by: Nuno Sá <nuno.sa@analog.com>
> ---
>  drivers/dma/dma-axi-dmac.c | 50 ++++++++++++++++++++++++++++++++++------------
>  1 file changed, 37 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/dma/dma-axi-dmac.c b/drivers/dma/dma-axi-dmac.c
> index 70d3ad7e7d37..46f1ead0c7d7 100644
> --- a/drivers/dma/dma-axi-dmac.c
> +++ b/drivers/dma/dma-axi-dmac.c
> @@ -25,6 +25,7 @@
>  #include <linux/regmap.h>
>  #include <linux/slab.h>
>  #include <linux/spinlock.h>
> +#include <linux/workqueue.h>
>
>  #include <dt-bindings/dma/axi-dmac.h>
>
> @@ -133,6 +134,9 @@ struct axi_dmac_sg {
>  struct axi_dmac_desc {
>  	struct virt_dma_desc vdesc;
>  	struct axi_dmac_chan *chan;
> +	struct device *dev;
> +
> +	struct work_struct sched_work;
>
>  	bool cyclic;
>  	bool cyclic_eot;
> @@ -666,6 +670,25 @@ static void axi_dmac_issue_pending(struct dma_chan *c)
>  	spin_unlock_irqrestore(&chan->vchan.lock, flags);
>  }
>
> +static void axi_dmac_free_desc(struct axi_dmac_desc *desc)
> +{
> +	struct axi_dmac_hw_desc *hw = desc->sg[0].hw;
> +	dma_addr_t hw_phys = desc->sg[0].hw_phys;
> +
> +	dma_free_coherent(desc->dev, PAGE_ALIGN(desc->num_sgs * sizeof(*hw)),
> +			  hw, hw_phys);
> +	put_device(desc->dev);
> +	kfree(desc);
> +}
> +
> +static void axi_dmac_free_desc_schedule_work(struct work_struct *work)
> +{
> +	struct axi_dmac_desc *desc = container_of(work, struct axi_dmac_desc,
> +						  sched_work);
> +
> +	axi_dmac_free_desc(desc);
> +}
> +
>  static struct axi_dmac_desc *
>  axi_dmac_alloc_desc(struct axi_dmac_chan *chan, unsigned int num_sgs)
>  {
> @@ -681,6 +704,7 @@ axi_dmac_alloc_desc(struct axi_dmac_chan *chan, unsigned int num_sgs)
>  		return NULL;
>  	desc->num_sgs = num_sgs;
>  	desc->chan = chan;
> +	desc->dev = get_device(dmac->dma_dev.dev);
>
>  	hws = dma_alloc_coherent(dev, PAGE_ALIGN(num_sgs * sizeof(*hws)),
>  				&hw_phys, GFP_ATOMIC);
> @@ -703,21 +727,18 @@ axi_dmac_alloc_desc(struct axi_dmac_chan *chan, unsigned int num_sgs)
>  	/* The last hardware descriptor will trigger an interrupt */
>  	desc->sg[num_sgs - 1].hw->flags = AXI_DMAC_HW_FLAG_LAST | AXI_DMAC_HW_FLAG_IRQ;
>
> +	/*
> +	 * We need to setup a work item because this IP can be used on archs
> +	 * that rely on vmalloced memory for descriptors. And given that freeing
> +	 * the descriptors happens in softirq context, vunmpap() will BUG().
> +	 * Hence, setup the worker so that we can queue it and free the
> +	 * descriptor in threaded context.
> +	 */
> +	INIT_WORK(&desc->sched_work, axi_dmac_free_desc_schedule_work);
> +
>  	return desc;
>  }
>
> -static void axi_dmac_free_desc(struct axi_dmac_desc *desc)
> -{
> -	struct axi_dmac *dmac = chan_to_axi_dmac(desc->chan);
> -	struct device *dev = dmac->dma_dev.dev;
> -	struct axi_dmac_hw_desc *hw = desc->sg[0].hw;
> -	dma_addr_t hw_phys = desc->sg[0].hw_phys;
> -
> -	dma_free_coherent(dev, PAGE_ALIGN(desc->num_sgs * sizeof(*hw)),
> -			  hw, hw_phys);
> -	kfree(desc);
> -}
> -
>  static struct axi_dmac_sg *axi_dmac_fill_linear_sg(struct axi_dmac_chan *chan,
>  	enum dma_transfer_direction direction, dma_addr_t addr,
>  	unsigned int num_periods, unsigned int period_len,
> @@ -958,7 +979,10 @@ static void axi_dmac_free_chan_resources(struct dma_chan *c)
>
>  static void axi_dmac_desc_free(struct virt_dma_desc *vdesc)
>  {
> -	axi_dmac_free_desc(to_axi_dmac_desc(vdesc));
> +	struct axi_dmac_desc *desc = to_axi_dmac_desc(vdesc);
> +
> +	/* See the comment in axi_dmac_alloc_desc() for the why! */
> +	schedule_work(&desc->sched_work);
>  }
>
>  static bool axi_dmac_regmap_rdwr(struct device *dev, unsigned int reg)
>
> --
> 2.53.0
>

^ permalink raw reply

* Re: [PATCH v2 3/4] dmaengine: dma-axi-dmac: fix use-after-free on unbind
From: Frank Li @ 2026-03-30 15:22 UTC (permalink / raw)
  To: Nuno Sá
  Cc: dmaengine, linux-kernel, Lars-Peter Clausen, Vinod Koul, Frank Li
In-Reply-To: <20260327-dma-dmac-handle-vunmap-v2-3-021f95f0e87b@analog.com>

On Fri, Mar 27, 2026 at 04:58:40PM +0000, Nuno Sá wrote:
> The DMA device lifetime can extend beyond the platform driver unbind if
> DMA channels are still referenced by client drivers. This leads to
> use-after-free when the devm-managed memory is freed on unbind but the
> DMA device callbacks still access it.
>
> Fix this by:
>  - Allocating axi_dmac with kzalloc_obj() instead of devm_kzalloc() so
> its lifetime is not tied to the platform device.
>  - Implementing the device_release callback that so that we can free
> the object when reference count gets to 0 (no users).
>  - Adding an 'unbound' flag protected by the vchan lock that is set
> during driver removal, preventing MMIO accesses after the device has been
> unbound.
>
> While at it, explicitly include spinlock.h given it was missing.
>
> Signed-off-by: Nuno Sá <nuno.sa@analog.com>
> ---

Not sure if it similar with
https://lore.kernel.org/dmaengine/20250903-v6-16-topic-sdma-v1-9-ac7bab629e8b@pengutronix.de/

It looks like miss device link between comsumer and provider.

Frank

>  drivers/dma/dma-axi-dmac.c | 70 +++++++++++++++++++++++++++++++++++++++-------
>  1 file changed, 60 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/dma/dma-axi-dmac.c b/drivers/dma/dma-axi-dmac.c
> index 127c3cf80a0e..70d3ad7e7d37 100644
> --- a/drivers/dma/dma-axi-dmac.c
> +++ b/drivers/dma/dma-axi-dmac.c
> @@ -24,6 +24,7 @@
>  #include <linux/platform_device.h>
>  #include <linux/regmap.h>
>  #include <linux/slab.h>
> +#include <linux/spinlock.h>
>
>  #include <dt-bindings/dma/axi-dmac.h>
>
> @@ -174,6 +175,8 @@ struct axi_dmac {
>
>  	struct dma_device dma_dev;
>  	struct axi_dmac_chan chan;
> +
> +	bool unbound;
>  };
>
>  static struct axi_dmac *chan_to_axi_dmac(struct axi_dmac_chan *chan)
> @@ -182,6 +185,11 @@ static struct axi_dmac *chan_to_axi_dmac(struct axi_dmac_chan *chan)
>  		dma_dev);
>  }
>
> +static struct axi_dmac *dev_to_axi_dmac(struct dma_device *dev)
> +{
> +	return container_of(dev, struct axi_dmac, dma_dev);
> +}
> +
>  static struct axi_dmac_chan *to_axi_dmac_chan(struct dma_chan *c)
>  {
>  	return container_of(c, struct axi_dmac_chan, vchan.chan);
> @@ -614,7 +622,12 @@ static int axi_dmac_terminate_all(struct dma_chan *c)
>  	LIST_HEAD(head);
>
>  	spin_lock_irqsave(&chan->vchan.lock, flags);
> -	axi_dmac_write(dmac, AXI_DMAC_REG_CTRL, 0);
> +	/*
> +	 * Only allow the MMIO access if the device is live. Otherwise still
> +	 * go for freeing the descriptors.
> +	 */
> +	if (!dmac->unbound)
> +		axi_dmac_write(dmac, AXI_DMAC_REG_CTRL, 0);
>  	chan->next_desc = NULL;
>  	vchan_get_all_descriptors(&chan->vchan, &head);
>  	list_splice_tail_init(&chan->active_descs, &head);
> @@ -642,9 +655,12 @@ static void axi_dmac_issue_pending(struct dma_chan *c)
>  	if (chan->hw_sg)
>  		ctrl |= AXI_DMAC_CTRL_ENABLE_SG;
>
> -	axi_dmac_write(dmac, AXI_DMAC_REG_CTRL, ctrl);
> -
>  	spin_lock_irqsave(&chan->vchan.lock, flags);
> +	if (dmac->unbound) {
> +		spin_unlock_irqrestore(&chan->vchan.lock, flags);
> +		return;
> +	}
> +	axi_dmac_write(dmac, AXI_DMAC_REG_CTRL, ctrl);
>  	if (vchan_issue_pending(&chan->vchan))
>  		axi_dmac_start_transfer(chan);
>  	spin_unlock_irqrestore(&chan->vchan.lock, flags);
> @@ -1184,6 +1200,14 @@ static int axi_dmac_detect_caps(struct axi_dmac *dmac, unsigned int version)
>  	return 0;
>  }
>
> +static void axi_dmac_release(struct dma_device *dma_dev)
> +{
> +	struct axi_dmac *dmac = dev_to_axi_dmac(dma_dev);
> +
> +	put_device(dma_dev->dev);
> +	kfree(dmac);
> +}
> +
>  static void axi_dmac_tasklet_kill(void *task)
>  {
>  	tasklet_kill(task);
> @@ -1194,16 +1218,27 @@ static void axi_dmac_free_dma_controller(void *of_node)
>  	of_dma_controller_free(of_node);
>  }
>
> +static void axi_dmac_disable(void *__dmac)
> +{
> +	struct axi_dmac *dmac = __dmac;
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&dmac->chan.vchan.lock, flags);
> +	dmac->unbound = true;
> +	spin_unlock_irqrestore(&dmac->chan.vchan.lock, flags);
> +	axi_dmac_write(dmac, AXI_DMAC_REG_CTRL, 0);
> +}
> +
>  static int axi_dmac_probe(struct platform_device *pdev)
>  {
>  	struct dma_device *dma_dev;
> -	struct axi_dmac *dmac;
> +	struct axi_dmac *__dmac;
>  	struct regmap *regmap;
>  	unsigned int version;
>  	u32 irq_mask = 0;
>  	int ret;
>
> -	dmac = devm_kzalloc(&pdev->dev, sizeof(*dmac), GFP_KERNEL);
> +	struct axi_dmac *dmac __free(kfree) = kzalloc_obj(struct axi_dmac);
>  	if (!dmac)
>  		return -ENOMEM;
>
> @@ -1251,6 +1286,7 @@ static int axi_dmac_probe(struct platform_device *pdev)
>  	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);
> +	dma_dev->device_release = axi_dmac_release;
>  	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 */
> @@ -1285,12 +1321,21 @@ static int axi_dmac_probe(struct platform_device *pdev)
>  	if (ret)
>  		return ret;
>
> +	/*
> +	 * From this point on, our dmac object has it's lifetime bounded with
> +	 * dma_dev. Will be freed when dma_dev refcount goes to 0. That means,
> +	 * no more automatic kfree(). Also note that dmac is now NULL so we
> +	 * need __dmac.
> +	 */
> +	__dmac = no_free_ptr(dmac);
> +	get_device(&pdev->dev);
> +
>  	/*
>  	 * Put the action in here so it get's done before unregistering the DMA
>  	 * device.
>  	 */
>  	ret = devm_add_action_or_reset(&pdev->dev, axi_dmac_tasklet_kill,
> -				       &dmac->chan.vchan.task);
> +				       &__dmac->chan.vchan.task);
>  	if (ret)
>  		return ret;
>
> @@ -1304,13 +1349,18 @@ static int axi_dmac_probe(struct platform_device *pdev)
>  	if (ret)
>  		return ret;
>
> -	ret = devm_request_irq(&pdev->dev, dmac->irq, axi_dmac_interrupt_handler,
> -			       IRQF_SHARED, dev_name(&pdev->dev), dmac);
> +	/* So that we can mark the device as unbound and disable it */
> +	ret = devm_add_action_or_reset(&pdev->dev, axi_dmac_disable, __dmac);
>  	if (ret)
>  		return ret;
>
> -	regmap = devm_regmap_init_mmio(&pdev->dev, dmac->base,
> -		 &axi_dmac_regmap_config);
> +	ret = devm_request_irq(&pdev->dev, __dmac->irq, axi_dmac_interrupt_handler,
> +			       IRQF_SHARED, dev_name(&pdev->dev), __dmac);
> +	if (ret)
> +		return ret;
> +
> +	regmap = devm_regmap_init_mmio(&pdev->dev, __dmac->base,
> +				       &axi_dmac_regmap_config);
>
>  	return PTR_ERR_OR_ZERO(regmap);
>  }
>
> --
> 2.53.0
>

^ permalink raw reply

* Re: [PATCH v2 2/4] dmaengine: dma-axi-dmac: Properly free struct axi_dmac_desc
From: Frank Li @ 2026-03-30 15:17 UTC (permalink / raw)
  To: Nuno Sá
  Cc: dmaengine, linux-kernel, Lars-Peter Clausen, Vinod Koul, Frank Li
In-Reply-To: <20260327-dma-dmac-handle-vunmap-v2-2-021f95f0e87b@analog.com>

On Fri, Mar 27, 2026 at 04:58:39PM +0000, Nuno Sá wrote:
> In axi_dmac_prep_peripheral_dma_vec() if we fail after calling
> axi_dmac_alloc_desc(), we need to use axi_dmac_free_desc() to fully free
> the descriptor.

Call axi_dmac_free_desc() instead of kfree() to do fully cleanup at err
handle path.

Frank

>
> Fixes: 74609e568670 ("dmaengine: dma-axi-dmac: Implement device_prep_peripheral_dma_vec")
> Signed-off-by: Nuno Sá <nuno.sa@analog.com>
> ---
>  drivers/dma/dma-axi-dmac.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/dma/dma-axi-dmac.c b/drivers/dma/dma-axi-dmac.c
> index 45c2c8e4bc45..127c3cf80a0e 100644
> --- a/drivers/dma/dma-axi-dmac.c
> +++ b/drivers/dma/dma-axi-dmac.c
> @@ -769,7 +769,7 @@ axi_dmac_prep_peripheral_dma_vec(struct dma_chan *c, const struct dma_vec *vecs,
>  	for (i = 0; i < nb; i++) {
>  		if (!axi_dmac_check_addr(chan, vecs[i].addr) ||
>  		    !axi_dmac_check_len(chan, vecs[i].len)) {
> -			kfree(desc);
> +			axi_dmac_free_desc(desc);
>  			return NULL;
>  		}
>
>
> --
> 2.53.0
>

^ permalink raw reply

* Re: [PATCH v2 1/4] dmaengine: Fix possuible use after free
From: Frank Li @ 2026-03-30 15:15 UTC (permalink / raw)
  To: Nuno Sá
  Cc: dmaengine, linux-kernel, Lars-Peter Clausen, Vinod Koul, Frank Li
In-Reply-To: <20260327-dma-dmac-handle-vunmap-v2-1-021f95f0e87b@analog.com>

On Fri, Mar 27, 2026 at 04:58:38PM +0000, Nuno Sá wrote:

typo at subject possuible

dmaengine: move dma_chan_put() after check dmaengine device's privatecnt

> In dma_release_channel(), we first called dma_chan_put() and then
> checked chan->device->privatecnt for possibly clearing DMA_PRIVATE.
> However, dma_chan_put() will call dma_device_put() which could,
> potentially (if the DMA provider is already gone for example),
> release the last reference of the device and hence freeing
> the it.

Avoid use "we"..

In dma_release_channel(), call dma_chan_put() before check
chan->device->privatecnt, which cause DMA engine device potentially is gone
when the last reference of the device is released.

Fixed it by moving dma_chan_put() after check chan->device->privatecnt.

Frank
>
> Fix it, by doing the check before calling dma_chan_put().
>
> Fixes: 0f571515c332 ("dmaengine: Add privatecnt to revert DMA_PRIVATE property")
> Signed-off-by: Nuno Sá <nuno.sa@analog.com>
> ---
>  drivers/dma/dmaengine.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
> index 405bd2fbb4a3..9049171df857 100644
> --- a/drivers/dma/dmaengine.c
> +++ b/drivers/dma/dmaengine.c
> @@ -905,11 +905,12 @@ void dma_release_channel(struct dma_chan *chan)
>  	mutex_lock(&dma_list_mutex);
>  	WARN_ONCE(chan->client_count != 1,
>  		  "chan reference count %d != 1\n", chan->client_count);
> -	dma_chan_put(chan);
>  	/* drop PRIVATE cap enabled by __dma_request_channel() */
>  	if (--chan->device->privatecnt == 0)
>  		dma_cap_clear(DMA_PRIVATE, chan->device->cap_mask);
>
> +	dma_chan_put(chan);
> +
>  	if (chan->slave) {
>  		sysfs_remove_link(&chan->dev->device.kobj, DMA_SLAVE_NAME);
>  		sysfs_remove_link(&chan->slave->kobj, chan->name);
>
> --
> 2.53.0
>

^ permalink raw reply

* Re: [PATCH] dmaengine: switchtec-dma: fix FIELD_GET misuse when programming SE threshold
From: Frank Li @ 2026-03-30 15:03 UTC (permalink / raw)
  To: David Carlier; +Cc: Kelvin Cao, Logan Gunthorpe, Vinod Koul, dmaengine
In-Reply-To: <20260317083252.13224-1-devnexen@gmail.com>

On Tue, Mar 17, 2026 at 08:32:52AM +0000, David Carlier wrote:
> FIELD_GET(SE_THRESH_MASK, thresh) extracts bits [31:23] from thresh and
> right-shifts them, which is the inverse of the intended operation. Since
> thresh is derived from se_buf_len / 2 (at most 255), bits [31:23] are
> always zero, so the SE threshold is never actually programmed into the
> register.
>
> Use FIELD_PREP() instead to correctly left-shift thresh into bits [31:23]
> of the valid_en_se register, consistent with the FIELD_PREP usage for
> the perf tuner config just above.
>
> Fixes: 30eba9df76ad ("dmaengine: switchtec-dma: Implement hardware initialization and cleanup")
> Signed-off-by: David Carlier <devnexen@gmail.com>
> ---

Reviewed-by: Frank Li <Frank.Li@nxp.com>

>  drivers/dma/switchtec_dma.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/dma/switchtec_dma.c b/drivers/dma/switchtec_dma.c
> index 3ef928640615..71d9868ce613 100644
> --- a/drivers/dma/switchtec_dma.c
> +++ b/drivers/dma/switchtec_dma.c
> @@ -1099,7 +1099,7 @@ static int switchtec_dma_chan_init(struct switchtec_dma_dev *swdma_dev,
>  	dev_dbg(&pdev->dev, "Channel %d: SE buffer count %d\n", i, se_buf_len);
>
>  	thresh = se_buf_len / 2;
> -	valid_en_se |= FIELD_GET(SE_THRESH_MASK, thresh);
> +	valid_en_se |= FIELD_PREP(SE_THRESH_MASK, thresh);
>  	writel(valid_en_se, &swdma_chan->mmio_chan_fw->valid_en_se);
>
>  	/* request irqs */
> --
> 2.53.0
>

^ permalink raw reply

* Re: [PATCH 1/3] dmaengine: dw-axi-dmac: fix Alignment should match open parenthesis
From: Frank Li @ 2026-03-30 15:01 UTC (permalink / raw)
  To: Khairul Anuar Romli
  Cc: Lars-Peter Clausen, Vinod Koul, Frank Li, dmaengine, linux-kernel,
	Markus.Elfring
In-Reply-To: <20260328025706.52722-2-karom.9560@gmail.com>

On Sat, Mar 28, 2026 at 10:56:55AM +0800, Khairul Anuar Romli wrote:
>     checkpatch.pl --strict reports a CHECK warning in dw-axi-dmac.c:
>
>       CHECK: Alignment should match open parenthesis
>
>     This warning occurs when multi-line function calls or expressions have
>     continuation lines that don't properly align with the opening
>     parenthesis position.
>
>     Fixes all instances in dw-axi-dmac.c where continuation lines were
>     indented with an inconsistent number of spaces/tabs that neither
>     matched the parenthesis column nor followed a standard indent pattern.
>     Proper alignment improves code readability and maintainability by
>     making parameter lists visually consistent across the kernel codebase.
>
> Fixes: 0e3b67b348b8 ("dmaengine: Add support for the Analog Devices AXI-DMAC DMA controller")
> Fixes: e3923592f80b ("dmaengine: axi-dmac: populate residue info for completed xfers")
> Fixes: 3f8fd25936ee ("dmaengine: axi-dmac: Allocate hardware descriptors")
> Fixes: 921234e0c5d7 ("dmaengine: axi-dmac: Split too large segments")
> Fixes: a5b982af953b ("dmaengine: axi-dmac: add a check for devm_regmap_init_mmio")

This is code cleanup and not user visiual problem. I think needn't add
fixes tags here.

Frank

> Signed-off-by: Khairul Anuar Romli <karom.9560@gmail.com>
> ---
>  drivers/dma/dma-axi-dmac.c | 28 +++++++++++++++-------------
>  1 file changed, 15 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/dma/dma-axi-dmac.c b/drivers/dma/dma-axi-dmac.c
> index 45c2c8e4bc45..0017f4dc6dcc 100644
> --- a/drivers/dma/dma-axi-dmac.c
> +++ b/drivers/dma/dma-axi-dmac.c
> @@ -193,7 +193,7 @@ static struct axi_dmac_desc *to_axi_dmac_desc(struct virt_dma_desc *vdesc)
>  }
>
>  static void axi_dmac_write(struct axi_dmac *axi_dmac, unsigned int reg,
> -	unsigned int val)
> +			   unsigned int val)
>  {
>  	writel(val, axi_dmac->base + reg);
>  }
> @@ -382,7 +382,7 @@ static void axi_dmac_start_transfer(struct axi_dmac_chan *chan)
>  }
>
>  static inline unsigned int axi_dmac_total_sg_bytes(struct axi_dmac_chan *chan,
> -	struct axi_dmac_sg *sg)
> +						   struct axi_dmac_sg *sg)
>  {
>  	if (chan->hw_2d)
>  		return (sg->hw->x_len + 1) * (sg->hw->y_len + 1);
> @@ -437,7 +437,7 @@ static void axi_dmac_dequeue_partial_xfers(struct axi_dmac_chan *chan)
>  }
>
>  static void axi_dmac_compute_residue(struct axi_dmac_chan *chan,
> -	struct axi_dmac_desc *active)
> +				     struct axi_dmac_desc *active)
>  {
>  	struct dmaengine_result *rslt = &active->vdesc.tx_result;
>  	unsigned int start = active->num_completed - 1;
> @@ -517,7 +517,7 @@ static bool axi_dmac_handle_cyclic_eot(struct axi_dmac_chan *chan,
>  }
>
>  static bool axi_dmac_transfer_done(struct axi_dmac_chan *chan,
> -	unsigned int completed_transfers)
> +				   unsigned int completed_transfers)
>  {
>  	struct axi_dmac_desc *active;
>  	struct axi_dmac_sg *sg;
> @@ -667,7 +667,7 @@ axi_dmac_alloc_desc(struct axi_dmac_chan *chan, unsigned int num_sgs)
>  	desc->chan = chan;
>
>  	hws = dma_alloc_coherent(dev, PAGE_ALIGN(num_sgs * sizeof(*hws)),
> -				&hw_phys, GFP_ATOMIC);
> +				 &hw_phys, GFP_ATOMIC);
>  	if (!hws) {
>  		kfree(desc);
>  		return NULL;
> @@ -703,9 +703,11 @@ static void axi_dmac_free_desc(struct axi_dmac_desc *desc)
>  }
>
>  static struct axi_dmac_sg *axi_dmac_fill_linear_sg(struct axi_dmac_chan *chan,
> -	enum dma_transfer_direction direction, dma_addr_t addr,
> -	unsigned int num_periods, unsigned int period_len,
> -	struct axi_dmac_sg *sg)
> +						   enum dma_transfer_direction direction,
> +						   dma_addr_t addr,
> +						   unsigned int num_periods,
> +						   unsigned int period_len,
> +						   struct axi_dmac_sg *sg)
>  {
>  	unsigned int num_segments, i;
>  	unsigned int segment_size;
> @@ -817,7 +819,7 @@ static struct dma_async_tx_descriptor *axi_dmac_prep_slave_sg(
>  		}
>
>  		dsg = axi_dmac_fill_linear_sg(chan, direction, sg_dma_address(sg), 1,
> -			sg_dma_len(sg), dsg);
> +					      sg_dma_len(sg), dsg);
>  	}
>
>  	desc->cyclic = false;
> @@ -857,7 +859,7 @@ static struct dma_async_tx_descriptor *axi_dmac_prep_dma_cyclic(
>  	desc->sg[num_sgs - 1].hw->flags &= ~AXI_DMAC_HW_FLAG_LAST;
>
>  	axi_dmac_fill_linear_sg(chan, direction, buf_addr, num_periods,
> -		period_len, desc->sg);
> +				period_len, desc->sg);
>
>  	desc->cyclic = true;
>
> @@ -1006,7 +1008,7 @@ static void axi_dmac_adjust_chan_params(struct axi_dmac_chan *chan)
>   * features are implemented and how it should behave.
>   */
>  static int axi_dmac_parse_chan_dt(struct device_node *of_chan,
> -	struct axi_dmac_chan *chan)
> +				  struct axi_dmac_chan *chan)
>  {
>  	u32 val;
>  	int ret;
> @@ -1295,7 +1297,7 @@ static int axi_dmac_probe(struct platform_device *pdev)
>  		return ret;
>
>  	ret = of_dma_controller_register(pdev->dev.of_node,
> -		of_dma_xlate_by_chan_id, dma_dev);
> +					 of_dma_xlate_by_chan_id, dma_dev);
>  	if (ret)
>  		return ret;
>
> @@ -1310,7 +1312,7 @@ static int axi_dmac_probe(struct platform_device *pdev)
>  		return ret;
>
>  	regmap = devm_regmap_init_mmio(&pdev->dev, dmac->base,
> -		 &axi_dmac_regmap_config);
> +				       &axi_dmac_regmap_config);
>
>  	return PTR_ERR_OR_ZERO(regmap);
>  }
> --
> 2.43.0
>

^ permalink raw reply

* [PATCH v5 10/10] arm64: tegra: Enable GPCDMA in Tegra264 and add iommu-map
From: Akhil R @ 2026-03-30 14:44 UTC (permalink / raw)
  To: Vinod Koul, Frank Li, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Thierry Reding, Jonathan Hunter, Laxman Dewangan,
	Philipp Zabel, dmaengine, devicetree, linux-tegra, linux-kernel
  Cc: Akhil R
In-Reply-To: <20260330144456.13551-1-akhilrajeev@nvidia.com>

Enable GPCDMA in Tegra264 and add the iommu-map property so that each
channel uses a separate stream ID and gets its own IOMMU domain for
memory.

Signed-off-by: Akhil R <akhilrajeev@nvidia.com>
---
 arch/arm64/boot/dts/nvidia/tegra264-p3834.dtsi | 4 ++++
 arch/arm64/boot/dts/nvidia/tegra264.dtsi       | 1 +
 2 files changed, 5 insertions(+)

diff --git a/arch/arm64/boot/dts/nvidia/tegra264-p3834.dtsi b/arch/arm64/boot/dts/nvidia/tegra264-p3834.dtsi
index 7e2c3e66c2ab..58cd81bc33d7 100644
--- a/arch/arm64/boot/dts/nvidia/tegra264-p3834.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra264-p3834.dtsi
@@ -9,6 +9,10 @@ aliases {
 	};
 
 	bus@0 {
+		dma-controller@8400000 {
+			status = "okay";
+		};
+
 		serial@c4e0000 {
 			status = "okay";
 		};
diff --git a/arch/arm64/boot/dts/nvidia/tegra264.dtsi b/arch/arm64/boot/dts/nvidia/tegra264.dtsi
index af077420d7d9..b2f20d4b567a 100644
--- a/arch/arm64/boot/dts/nvidia/tegra264.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra264.dtsi
@@ -3244,6 +3244,7 @@ gpcdma: dma-controller@8400000 {
 				     <GIC_SPI 615 IRQ_TYPE_LEVEL_HIGH>;
 			#dma-cells = <1>;
 			iommus = <&smmu1 0x00000800>;
+			iommu-map = <1 &smmu1 0x801 31>;
 			dma-coherent;
 			dma-channel-mask = <0xfffffffe>;
 			status = "disabled";
-- 
2.50.1


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox