DMA Engine development
 help / color / mirror / Atom feed
* [PATCHv2 0/4] dma: fsl_raid: fix sparse warnings and simplify probing
@ 2026-07-16 20:29 Rosen Penev
  2026-07-16 20:29 ` [PATCHv2 1/4] dma: fsl_raid: convert descriptor stores to big-endian Rosen Penev
                   ` (3 more replies)
  0 siblings, 4 replies; 11+ messages in thread
From: Rosen Penev @ 2026-07-16 20:29 UTC (permalink / raw)
  To: dmaengine; +Cc: Vinod Koul, Frank Li, open list

This series cleans up the fsl_raid driver to address issues reported by
sparse and to simplify its MMIO handling.

Patch 1 fixes the endianness of in-memory descriptor stores. The
descriptor structs are handed to the device as big-endian, but the driver
stored CPU-endian values directly, which is both incorrect and flagged by
sparse as a base-type mismatch. The stores are wrapped in cpu_to_be32()
and the final-frame bit is now passed as an argument rather than
read-modify-written.

Patch 2 keeps the MMIO bases (re_regs and jrregs) as void __iomem *
instead of typed register struct pointers, eliminating "different address
spaces" sparse warnings on every register access. Each accessor derives a
local __iomem-qualified typed pointer.

Patch 3 replaces the open-coded platform_get_resource() +
devm_ioremap() sequence with devm_platform_ioremap_resource().

v2: split up first patch and simplify __iomem patch.

Rosen Penev (4):
  dma: fsl_raid: convert descriptor stores to big-endian
  dma: fsl_raid: set final bit via fill_cfd_frame() argument
  dma: fsl_raid: keep MMIO bases as void __iomem and cast at access
  dma: fsl_raid: use devm_platform_ioremap_resource

 drivers/dma/fsl_raid.c | 58 ++++++++++++++++++++----------------------
 drivers/dma/fsl_raid.h |  4 +--
 2 files changed, 30 insertions(+), 32 deletions(-)

-- 
2.55.0


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCHv2 1/4] dma: fsl_raid: convert descriptor stores to big-endian
  2026-07-16 20:29 [PATCHv2 0/4] dma: fsl_raid: fix sparse warnings and simplify probing Rosen Penev
@ 2026-07-16 20:29 ` Rosen Penev
  2026-07-16 20:44   ` sashiko-bot
  2026-07-16 20:49   ` Frank Li
  2026-07-16 20:29 ` [PATCHv2 2/4] dma: fsl_raid: set final bit via fill_cfd_frame() argument Rosen Penev
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 11+ messages in thread
From: Rosen Penev @ 2026-07-16 20:29 UTC (permalink / raw)
  To: dmaengine; +Cc: Vinod Koul, Frank Li, open list

The descriptor structs (fsl_re_cmpnd_frame / fsl_re_hw_desc) are
in-memory but their fields are __be32, because the structures are handed
to the device as big-endian. The driver stored CPU-endian u32 values
into them directly, which is both wrong (the engine would see
byte-swapped lengths/addresses) and flagged by sparse as a base-type
mismatch.

Wrap those stores in cpu_to_be32() so the values are little->big
converted.

Reported-by: kernel test robot <lkp@intel.com>
Fixes: https://lore.kernel.org/oe-kbuild-all/202008111749.yy85rFMD%25lkp@intel.com/
Assisted-by: opencode:hy3-free
Signed-off-by: Rosen Penev <rosenp@gmail.com>
---
 drivers/dma/fsl_raid.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/dma/fsl_raid.c b/drivers/dma/fsl_raid.c
index 99945845d8b5..2778d07a05e8 100644
--- a/drivers/dma/fsl_raid.c
+++ b/drivers/dma/fsl_raid.c
@@ -242,9 +242,9 @@ static void fill_cfd_frame(struct fsl_re_cmpnd_frame *cf, u8 index,
 	u32 efrl = length & FSL_RE_CF_LENGTH_MASK;
 
 	efrl |= final << FSL_RE_CF_FINAL_SHIFT;
-	cf[index].efrl32 = efrl;
-	cf[index].addr_high = upper_32_bits(addr);
-	cf[index].addr_low = lower_32_bits(addr);
+	cf[index].efrl32 = cpu_to_be32(efrl);
+	cf[index].addr_high = cpu_to_be32(upper_32_bits(addr));
+	cf[index].addr_low = cpu_to_be32(lower_32_bits(addr));
 }
 
 static struct fsl_re_desc *fsl_re_init_desc(struct fsl_re_chan *re_chan,
@@ -256,9 +256,10 @@ static struct fsl_re_desc *fsl_re_init_desc(struct fsl_re_chan *re_chan,
 	dma_async_tx_descriptor_init(&desc->async_tx, &re_chan->chan);
 	INIT_LIST_HEAD(&desc->node);
 
-	desc->hwdesc.fmt32 = FSL_RE_FRAME_FORMAT << FSL_RE_HWDESC_FMT_SHIFT;
-	desc->hwdesc.lbea32 = upper_32_bits(paddr);
-	desc->hwdesc.addr_low = lower_32_bits(paddr);
+	desc->hwdesc.fmt32 = cpu_to_be32(FSL_RE_FRAME_FORMAT <<
+					  FSL_RE_HWDESC_FMT_SHIFT);
+	desc->hwdesc.lbea32 = cpu_to_be32(upper_32_bits(paddr));
+	desc->hwdesc.addr_low = cpu_to_be32(lower_32_bits(paddr));
 	desc->cf_addr = cf;
 	desc->cf_paddr = paddr;
 
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCHv2 2/4] dma: fsl_raid: set final bit via fill_cfd_frame() argument
  2026-07-16 20:29 [PATCHv2 0/4] dma: fsl_raid: fix sparse warnings and simplify probing Rosen Penev
  2026-07-16 20:29 ` [PATCHv2 1/4] dma: fsl_raid: convert descriptor stores to big-endian Rosen Penev
@ 2026-07-16 20:29 ` Rosen Penev
  2026-07-16 20:47   ` sashiko-bot
  2026-07-16 20:57   ` Frank Li
  2026-07-16 20:29 ` [PATCHv2 3/4] dma: fsl_raid: keep MMIO bases as void __iomem and cast at access Rosen Penev
  2026-07-16 20:29 ` [PATCHv2 4/4] dma: fsl_raid: use devm_platform_ioremap_resource Rosen Penev
  3 siblings, 2 replies; 11+ messages in thread
From: Rosen Penev @ 2026-07-16 20:29 UTC (permalink / raw)
  To: dmaengine; +Cc: Vinod Koul, Frank Li, open list

The final-frame bit is now passed as the "final" argument of
fill_cfd_frame() (as fsl_re_prep_dma_memcpy already did) and set in CPU
order before the single cpu_to_be32() store, replacing the previous
read-modify-write of the __be32 efrl32 field.

Assisted-by: opencode:hy3-free
Signed-off-by: Rosen Penev <rosenp@gmail.com>
---
 drivers/dma/fsl_raid.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/dma/fsl_raid.c b/drivers/dma/fsl_raid.c
index 2778d07a05e8..888f55b672a5 100644
--- a/drivers/dma/fsl_raid.c
+++ b/drivers/dma/fsl_raid.c
@@ -375,11 +375,11 @@ static struct dma_async_tx_descriptor *fsl_re_prep_dma_genq(
 	for (i = 2, j = 0; j < save_src_cnt; i++, j++)
 		fill_cfd_frame(cf, i, len, src[j], 0);
 
+	/* Fill the last frame and mark it final */
 	if (cont_q)
-		fill_cfd_frame(cf, i++, len, dest, 0);
-
-	/* Setting the final bit in the last source buffer frame in CFD */
-	cf[i - 1].efrl32 |= 1 << FSL_RE_CF_FINAL_SHIFT;
+		fill_cfd_frame(cf, i, len, dest, 1);
+	else
+		fill_cfd_frame(cf, i - 1, len, src[j - 1], 1);
 
 	return &desc->async_tx;
 }
@@ -505,16 +505,16 @@ static struct dma_async_tx_descriptor *fsl_re_prep_dma_pq(
 			p[save_src_cnt + 2] = 1;
 			fill_cfd_frame(cf, i++, len, dest[0], 0);
 			fill_cfd_frame(cf, i++, len, dest[1], 0);
-			fill_cfd_frame(cf, i++, len, dest[1], 0);
+			fill_cfd_frame(cf, i++, len, dest[1], 1);
 		} else {
 			dev_err(re_chan->dev, "PQ tx continuation error!\n");
 			return NULL;
 		}
+	} else {
+		/* Mark the last source buffer frame final */
+		fill_cfd_frame(cf, i - 1, len, src[j - 1], 1);
 	}
 
-	/* Setting the final bit in the last source buffer frame in CFD */
-	cf[i - 1].efrl32 |= 1 << FSL_RE_CF_FINAL_SHIFT;
-
 	return &desc->async_tx;
 }
 
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCHv2 3/4] dma: fsl_raid: keep MMIO bases as void __iomem and cast at access
  2026-07-16 20:29 [PATCHv2 0/4] dma: fsl_raid: fix sparse warnings and simplify probing Rosen Penev
  2026-07-16 20:29 ` [PATCHv2 1/4] dma: fsl_raid: convert descriptor stores to big-endian Rosen Penev
  2026-07-16 20:29 ` [PATCHv2 2/4] dma: fsl_raid: set final bit via fill_cfd_frame() argument Rosen Penev
@ 2026-07-16 20:29 ` Rosen Penev
  2026-07-16 20:44   ` sashiko-bot
  2026-07-16 21:02   ` Frank Li
  2026-07-16 20:29 ` [PATCHv2 4/4] dma: fsl_raid: use devm_platform_ioremap_resource Rosen Penev
  3 siblings, 2 replies; 11+ messages in thread
From: Rosen Penev @ 2026-07-16 20:29 UTC (permalink / raw)
  To: dmaengine; +Cc: Vinod Koul, Frank Li, open list

The fsl_re_ctrl and fsl_re_chan_cfg structures describe memory-mapped
RAID Engine registers accessed only via ioread32be()/iowrite32be(), yet
the pointers to them (re_regs in struct fsl_re_drv_private, and jrregs
in struct fsl_re_chan) were not __iomem-qualified, so sparse emitted
"different address spaces" warnings for every register access.

Store both MMIO bases as a plain void __iomem * and derive jrregs with
void __iomem * arithmetic from re_regs, rather than carrying typed
register struct pointers through the driver. Each function that touches
the registers introduces a local typed pointer (struct fsl_re_ctrl
__iomem *ctrl) and uses ->field, which is the idiomatic kernel pattern
 and keeps the registers' __iomem qualification intact.

Reported-by: kernel test robot <lkp@intel.com>
Fixes: https://lore.kernel.org/oe-kbuild-all/202008111749.yy85rFMD%25lkp@intel.com/
Assisted-by: opencode:hy3-free
Signed-off-by: Rosen Penev <rosenp@gmail.com>
---
 drivers/dma/fsl_raid.c | 19 ++++++++++---------
 drivers/dma/fsl_raid.h |  4 ++--
 2 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/drivers/dma/fsl_raid.c b/drivers/dma/fsl_raid.c
index 888f55b672a5..524f83faf3da 100644
--- a/drivers/dma/fsl_raid.c
+++ b/drivers/dma/fsl_raid.c
@@ -657,8 +657,7 @@ static int fsl_re_chan_probe(struct platform_device *ofdev,
 		goto err_free;
 	}
 
-	chan->jrregs = (struct fsl_re_chan_cfg *)((u8 *)re_priv->re_regs +
-			off + ptr);
+	chan->jrregs = re_priv->base + off + ptr;
 
 	/* read irq property from dts */
 	chan->irq = irq_of_parse_and_map(np, 0);
@@ -746,6 +745,7 @@ static int fsl_re_chan_probe(struct platform_device *ofdev,
 /* Probe function for RAID Engine */
 static int fsl_re_probe(struct platform_device *ofdev)
 {
+	struct fsl_re_ctrl __iomem *re_regs;
 	struct fsl_re_drv_private *re_priv;
 	struct device_node *child;
 	u32 off;
@@ -764,20 +764,21 @@ static int fsl_re_probe(struct platform_device *ofdev)
 		return -ENODEV;
 
 	/* IOMAP the entire RAID Engine region */
-	re_priv->re_regs = devm_ioremap(dev, res->start, resource_size(res));
-	if (!re_priv->re_regs)
+	re_regs = devm_ioremap(dev, res->start, resource_size(res));
+	if (!re_regs)
 		return -EBUSY;
+	re_priv->base = re_regs;
 
 	/* Program the RE mode */
-	out_be32(&re_priv->re_regs->global_config, FSL_RE_NON_DPAA_MODE);
+	out_be32(&re_regs->global_config, FSL_RE_NON_DPAA_MODE);
 
 	/* Program Galois Field polynomial */
-	out_be32(&re_priv->re_regs->galois_field_config, FSL_RE_GFM_POLY);
+	out_be32(&re_regs->galois_field_config, FSL_RE_GFM_POLY);
 
 	dev_info(dev, "version %x, mode %x, gfp %x\n",
-		 in_be32(&re_priv->re_regs->re_version_id),
-		 in_be32(&re_priv->re_regs->global_config),
-		 in_be32(&re_priv->re_regs->galois_field_config));
+		 in_be32(&re_regs->re_version_id),
+		 in_be32(&re_regs->global_config),
+		 in_be32(&re_regs->galois_field_config));
 
 	dma_dev = &re_priv->dma_dev;
 	dma_dev->dev = dev;
diff --git a/drivers/dma/fsl_raid.h b/drivers/dma/fsl_raid.h
index 69d743c04973..adbfede330a7 100644
--- a/drivers/dma/fsl_raid.h
+++ b/drivers/dma/fsl_raid.h
@@ -256,7 +256,7 @@ struct fsl_re_hw_desc {
 struct fsl_re_drv_private {
 	u8 total_chans;
 	struct dma_device dma_dev;
-	struct fsl_re_ctrl *re_regs;
+	void __iomem *base;
 	struct fsl_re_chan *re_jrs[FSL_RE_MAX_CHANS];
 	struct dma_pool *cf_desc_pool;
 	struct dma_pool *hw_desc_pool;
@@ -273,7 +273,7 @@ struct fsl_re_chan {
 	struct device *dev;
 	struct fsl_re_drv_private *re_dev;
 	struct dma_chan chan;
-	struct fsl_re_chan_cfg *jrregs;
+	struct fsl_re_chan_cfg __iomem *jrregs;
 	int irq;
 	struct tasklet_struct irqtask;
 	u32 alloc_count;
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCHv2 4/4] dma: fsl_raid: use devm_platform_ioremap_resource
  2026-07-16 20:29 [PATCHv2 0/4] dma: fsl_raid: fix sparse warnings and simplify probing Rosen Penev
                   ` (2 preceding siblings ...)
  2026-07-16 20:29 ` [PATCHv2 3/4] dma: fsl_raid: keep MMIO bases as void __iomem and cast at access Rosen Penev
@ 2026-07-16 20:29 ` Rosen Penev
  3 siblings, 0 replies; 11+ messages in thread
From: Rosen Penev @ 2026-07-16 20:29 UTC (permalink / raw)
  To: dmaengine; +Cc: Vinod Koul, Frank Li, open list

Replace the open-coded platform_get_resource() plus devm_ioremap()
sequence with devm_platform_ioremap_resource(), which fetches the
resource, requests the region and maps it in one call. Switch the error
check to IS_ERR()/PTR_ERR() and drop the now-unused struct resource
pointer.

The raideng node has a single reg region (0x320000, 0x10000); the
job-queue/ring children are separate OF devices probed independently, so
the region reservation added by devm_ioremap_resource() is exclusive and
does not introduce overlap failures.

Assisted-by: opencode:hy3-free
Signed-off-by: Rosen Penev <rosenp@gmail.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
---
 drivers/dma/fsl_raid.c | 14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/drivers/dma/fsl_raid.c b/drivers/dma/fsl_raid.c
index 524f83faf3da..2d86f61105e5 100644
--- a/drivers/dma/fsl_raid.c
+++ b/drivers/dma/fsl_raid.c
@@ -751,22 +751,18 @@ static int fsl_re_probe(struct platform_device *ofdev)
 	u32 off;
 	u8 ridx = 0;
 	struct dma_device *dma_dev;
-	struct resource *res;
 	int rc;
 	struct device *dev = &ofdev->dev;
 
+	/* IOMAP the entire RAID Engine region */
+	re_regs = devm_platform_ioremap_resource(ofdev, 0);
+	if (IS_ERR(re_regs))
+		return PTR_ERR(re_regs);
+
 	re_priv = devm_kzalloc(dev, sizeof(*re_priv), GFP_KERNEL);
 	if (!re_priv)
 		return -ENOMEM;
 
-	res = platform_get_resource(ofdev, IORESOURCE_MEM, 0);
-	if (!res)
-		return -ENODEV;
-
-	/* IOMAP the entire RAID Engine region */
-	re_regs = devm_ioremap(dev, res->start, resource_size(res));
-	if (!re_regs)
-		return -EBUSY;
 	re_priv->base = re_regs;
 
 	/* Program the RE mode */
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCHv2 3/4] dma: fsl_raid: keep MMIO bases as void __iomem and cast at access
  2026-07-16 20:29 ` [PATCHv2 3/4] dma: fsl_raid: keep MMIO bases as void __iomem and cast at access Rosen Penev
@ 2026-07-16 20:44   ` sashiko-bot
  2026-07-16 21:02   ` Frank Li
  1 sibling, 0 replies; 11+ messages in thread
From: sashiko-bot @ 2026-07-16 20:44 UTC (permalink / raw)
  To: Rosen Penev; +Cc: Frank.Li, dmaengine, vkoul

Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider:

Pre-existing issues:
- [High] Missing bounds check when parsing device tree Job Ring nodes.
- [High] `fsl_re_probe()` ignores the return value of `fsl_re_chan_probe()` and unconditionally increments `total_chans`, leading to a NULL pointer dereference.
- [High] DMA channels are never registered with the parent DMA device framework.
- [High] Missing cleanup for channel IRQs and platform devices in both error paths and driver removal, plus incorrect teardown order.
- [High] Potential NULL pointer dereference in `fsl_re_isr` due to premature IRQ registration.
--

--- Patch [1]: [PATCHv2 3/4] dma: fsl_raid: keep MMIO bases as void __iomem and cast at access ---
commit d9bcf292f2ff70b568c4dd2362d8ec21ba56f6cd
Author: Rosen Penev <rosenp@gmail.com>

dma: fsl_raid: keep MMIO bases as void __iomem and cast at access

The commit modifies the fsl_re_drv_private and fsl_re_chan structures to
store MMIO bases as void __iomem * instead of typed struct pointers. This
resolves sparse warnings about mismatched address spaces by ensuring typed
pointers are only introduced locally in functions that touch the registers.

Fixes: https://lore.kernel.org/oe-kbuild-all/202008111749.yy85rFMD%25lkp@intel.com/

> diff --git a/drivers/dma/fsl_raid.c b/drivers/dma/fsl_raid.c
> index 99945845d8b5e..5bc5bd499ba27 100644
> --- a/drivers/dma/fsl_raid.c
> +++ b/drivers/dma/fsl_raid.c
> @@ -656,8 +656,7 @@ static int fsl_re_chan_probe(struct platform_device *ofdev,
>  		goto err_free;
>  	}
>  
> -	chan->jrregs = (struct fsl_re_chan_cfg *)((u8 *)re_priv->re_regs +
> -			off + ptr);
> +	chan->jrregs = re_priv->base + off + ptr;
>  
>  	/* read irq property from dts */
>  	chan->irq = irq_of_parse_and_map(np, 0);

[Severity: High]
This isn't a bug introduced by this patch, but the driver context seems to
be attached to the device too late.

In fsl_re_chan_probe(), request_irq() is called before dev_set_drvdata()
populates the driver data:

    ret = request_irq(chan->irq, fsl_re_isr, 0, chan->name, chandev);
    ...
    dev_set_drvdata(chandev, chan);

If an interrupt triggers immediately, fsl_re_isr() retrieves a NULL pointer
and dereferences it:

    re_chan = dev_get_drvdata((struct device *)data);
    irqstate = in_be32(&re_chan->jrregs->jr_interrupt_status);

Is there a vulnerable window here where an incoming interrupt could lead to
a NULL pointer dereference?

[Severity: High]
This is a pre-existing issue, but it appears the DMA channels are never
registered with the parent DMA device framework.

In fsl_re_chan_probe(), the channels are initialized, but the required list
addition to attach them to dma_dev->channels is omitted:

    re_priv->re_jrs[q] = chan;
    chan->chan.device = dma_dev;
    ...

Without adding the channel to dma_dev->channels, will
dma_async_device_register() end up registering 0 channels and leave the
driver functionally dead?

[Severity: High]
This isn't a bug introduced by this patch, but I noticed potential resource
leaks and incorrect teardown ordering.

On error paths inside fsl_re_chan_probe(), resources like requested IRQs
and platform devices are not freed:

    err_free:
        return ret;

Additionally, in fsl_re_remove_chan(), free_irq() or
of_platform_device_destroy() are not called.

This leaves an active unmanaged IRQ pointing to freed driver memory.

Also, in fsl_re_remove(), the driver frees ring buffers before unregistering
the async DMA device:

    for (i = 0; i < re_priv->total_chans; i++)
        fsl_re_remove_chan(re_priv->re_jrs[i]);

    /* Unregister the driver */
    dma_async_device_unregister(&re_priv->dma_dev);

Could this cause a use-after-free if the IRQ fires, and does the teardown
order violate teardown safety expectations?

[ ... ]

> @@ -763,20 +763,21 @@ static int fsl_re_probe(struct platform_device *ofdev)
>  		return -ENODEV;
>  
>  	/* IOMAP the entire RAID Engine region */
> -	re_priv->re_regs = devm_ioremap(dev, res->start, resource_size(res));
> -	if (!re_priv->re_regs)
> +	re_regs = devm_ioremap(dev, res->start, resource_size(res));
> +	if (!re_regs)
>  		return -EBUSY;
> +	re_priv->base = re_regs;
>  
>  	/* Program the RE mode */
> -	out_be32(&re_priv->re_regs->global_config, FSL_RE_NON_DPAA_MODE);
> +	out_be32(&re_regs->global_config, FSL_RE_NON_DPAA_MODE);

[ ... ]

[Severity: High]
This is a pre-existing issue, but there seems to be a missing bounds check
when parsing device tree Job Ring nodes.

In fsl_re_probe(), the ridx counter is incremented indefinitely and passed
directly to fsl_re_chan_probe() without being bounded against
FSL_RE_MAX_CHANS (4):

    fsl_re_chan_probe(ofdev, child, ridx++, off);
    re_priv->total_chans++;

Then in fsl_re_chan_probe(), the unbounded index q is directly used to write
into the statically sized array:

    re_priv->re_jrs[q] = chan;

If a malformed device tree contains more than 4 job ring child nodes,
would this cause an out-of-bounds write and memory corruption?

[Severity: High]
This isn't a bug introduced by this patch, but fsl_re_probe() appears to
ignore the return value of fsl_re_chan_probe() and unconditionally
increments total_chans.

    fsl_re_chan_probe(ofdev, child, ridx++, off);
    re_priv->total_chans++;

If fsl_re_chan_probe() fails and returns an error, fsl_re_probe() ignores
the error but still increments re_priv->total_chans.

Subsequent calls to fsl_re_remove_chan() on driver remove or error rollback
will then dereference a NULL pointer:

    static void fsl_re_remove_chan(struct fsl_re_chan *chan)
    {
        tasklet_kill(&chan->irqtask);
        ...

Might this result in a kernel panic from a NULL pointer dereference during
teardown?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260716202949.677290-4-rosenp@gmail.com?part=1

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCHv2 1/4] dma: fsl_raid: convert descriptor stores to big-endian
  2026-07-16 20:29 ` [PATCHv2 1/4] dma: fsl_raid: convert descriptor stores to big-endian Rosen Penev
@ 2026-07-16 20:44   ` sashiko-bot
  2026-07-16 20:49   ` Frank Li
  1 sibling, 0 replies; 11+ messages in thread
From: sashiko-bot @ 2026-07-16 20:44 UTC (permalink / raw)
  To: Rosen Penev; +Cc: dmaengine, vkoul, Frank.Li

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:

New issues:
- [High] Bitwise OR operation on a __be32 field using a host-endian constant introduces data corruption.

Pre-existing issues:
- [High] Incomplete endianness conversion for command descriptor blocks leaves the driver broken on little-endian platforms.
--

--- Patch [1]: [PATCHv2 1/4] dma: fsl_raid: convert descriptor stores to big-endian ---
commit 4b4dfb0a314d465959f6268650dc8a30d7c69bd2
Author: Rosen Penev <rosenp@gmail.com>

dma: fsl_raid: convert descriptor stores to big-endian

The descriptor structs (fsl_re_cmpnd_frame / fsl_re_hw_desc) are
in-memory but their fields are __be32, because the structures are handed
to the device as big-endian. The driver stored CPU-endian u32 values
into them directly, which is both wrong (the engine would see
byte-swapped lengths/addresses) and flagged by sparse as a base-type
mismatch. Wrap those stores in cpu_to_be32().

Fixes: https://lore.kernel.org/oe-kbuild-all/202008111749.yy85rFMD%25lkp@intel.com/

> diff --git a/drivers/dma/fsl_raid.c b/drivers/dma/fsl_raid.c
> index 99945845d8b5e..2778d07a05e86 100644
> --- a/drivers/dma/fsl_raid.c
> +++ b/drivers/dma/fsl_raid.c
> @@ -242,9 +242,9 @@ static void fill_cfd_frame(struct fsl_re_cmpnd_frame *cf, u8 index,
>  	u32 efrl = length & FSL_RE_CF_LENGTH_MASK;
>  
>  	efrl |= final << FSL_RE_CF_FINAL_SHIFT;
> -	cf[index].efrl32 = efrl;
> -	cf[index].addr_high = upper_32_bits(addr);
> -	cf[index].addr_low = lower_32_bits(addr);
> +	cf[index].efrl32 = cpu_to_be32(efrl);

[Severity: High]
Since this function now writes a big-endian value to efrl32, doesn't this
cause a regression later when a host-endian bitwise OR is applied?

In fsl_re_prep_dma_genq():

	/* Setting the final bit in the last source buffer frame in CFD */
	cf[i - 1].efrl32 |= 1 << FSL_RE_CF_FINAL_SHIFT;

Since efrl32 now contains a byte-swapped value on little-endian architectures,
won't this host-endian bitwise OR place the final flag in the wrong byte and
corrupt the lower bits of the length field? 

The same pattern also occurs in fsl_re_prep_dma_pq().

[Severity: High]
This is a pre-existing issue, but while you are fixing endianness, should the
cdb32 field in the command descriptor blocks also be converted?

For example, in fsl_re_prep_dma_genq():

	xor = desc->cdb_addr;
	xor->cdb32 = cdb;

And similarly in fsl_re_prep_dma_pq() and fsl_re_prep_dma_memcpy(), a
host-endian u32 is assigned directly to the __be32 cdb32 field. Doesn't this
leave the driver broken on little-endian platforms?

> +	cf[index].addr_high = cpu_to_be32(upper_32_bits(addr));
> +	cf[index].addr_low = cpu_to_be32(lower_32_bits(addr));
>  }

[ ... ]

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260716202949.677290-2-rosenp@gmail.com?part=1

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCHv2 2/4] dma: fsl_raid: set final bit via fill_cfd_frame() argument
  2026-07-16 20:29 ` [PATCHv2 2/4] dma: fsl_raid: set final bit via fill_cfd_frame() argument Rosen Penev
@ 2026-07-16 20:47   ` sashiko-bot
  2026-07-16 20:57   ` Frank Li
  1 sibling, 0 replies; 11+ messages in thread
From: sashiko-bot @ 2026-07-16 20:47 UTC (permalink / raw)
  To: Rosen Penev; +Cc: vkoul, Frank.Li, dmaengine

Thank you for your contribution! Sashiko AI review found 9 potential issue(s) to consider:

New issues:
- [High] Integer underflow leading to wild pointer dereference when src_cnt == 0.
- [Medium] The commit message claims to fix an endianness issue by setting a bit before a 'single cpu_to_be32() store', but this byte-swap is completely missing from the modified code.

Pre-existing issues:
- [High] Multiple severe out-of-bounds writes in `fsl_re_prep_dma_pq()` corrupt the Command Descriptor Block (CDB) when `DMA_PREP_CONTINUE` is set.
- [High] Missing IRQ cleanup leaves the interrupt handler active after module unload.
- [High] Incorrect teardown sequence frees DMA channel resources before unregistering the DMA device.
- [High] Ignored probe failures lead to uninitialized or partially initialized channels being torn down, causing NULL pointer dereferences or double frees.
- [High] Recursive locking deadlock when invoking DMA client callback.
- [High] Race condition due to prematurely enabling interrupts before initialization is complete.
- [High] DMA transfers of exactly 1MB will be silently truncated to 0 bytes due to `FSL_RE_CF_LENGTH_MASK` mismatch.
--

--- Patch [1]: [PATCHv2 2/4] dma: fsl_raid: set final bit via fill_cfd_frame() argument ---
commit 62a6bad1aef1e87fcc87f1d390c2ed3be7152732
Author: Rosen Penev <rosenp@gmail.com>

dma: fsl_raid: set final bit via fill_cfd_frame() argument

The final-frame bit is now passed as the "final" argument of
fill_cfd_frame() (as fsl_re_prep_dma_memcpy already did) and set in CPU
order before the single cpu_to_be32() store, replacing the previous
read-modify-write of the __be32 efrl32 field.

[Severity: Medium]
The commit message claims to fix an endianness issue by setting a bit before
a single cpu_to_be32() store, but this byte-swap appears to be missing from
the modified code.  Looking at fill_cfd_frame() in drivers/dma/fsl_raid.c,
the native integer is assigned directly to the __be32 field:

    cf[index].efrl32 = efrl;

Could this leave the type mismatch unresolved and the endianness bug in
place on little-endian hardware?

> ---
>  drivers/dma/fsl_raid.c | 16 ++++++++--------
>  1 file changed, 8 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/dma/fsl_raid.c b/drivers/dma/fsl_raid.c
> index 99945845d8b5e..a4feaa9a1c628 100644
> --- a/drivers/dma/fsl_raid.c
> +++ b/drivers/dma/fsl_raid.c
> @@ -374,11 +374,11 @@ static struct dma_async_tx_descriptor *fsl_re_prep_dma_genq(
>  	for (i = 2, j = 0; j < save_src_cnt; i++, j++)
>  		fill_cfd_frame(cf, i, len, src[j], 0);
>  
> +	/* Fill the last frame and mark it final */
>  	if (cont_q)
> -		fill_cfd_frame(cf, i++, len, dest, 0);
> -
> -	/* Setting the final bit in the last source buffer frame in CFD */
> -	cf[i - 1].efrl32 |= 1 << FSL_RE_CF_FINAL_SHIFT;
> +		fill_cfd_frame(cf, i, len, dest, 1);
> +	else
> +		fill_cfd_frame(cf, i - 1, len, src[j - 1], 1);

[Severity: High]
Does this code cause an integer underflow when fsl_re_prep_dma_genq() is
called with src_cnt == 0?

If the loop initializing cf frames is completely skipped, j remains 0
(unsigned), causing j - 1 to underflow to UINT_MAX.  This could lead to a
wild pointer dereference when accessing src[j - 1].

>  	return &desc->async_tx;
>  }

[ ... ]

> @@ -504,16 +504,16 @@ static struct dma_async_tx_descriptor *fsl_re_prep_dma_pq(
>  			p[save_src_cnt + 2] = 1;
>  			fill_cfd_frame(cf, i++, len, dest[0], 0);
>  			fill_cfd_frame(cf, i++, len, dest[1], 0);
> -			fill_cfd_frame(cf, i++, len, dest[1], 0);
> +			fill_cfd_frame(cf, i++, len, dest[1], 1);

[Severity: High]
This is a pre-existing issue, but does this continuation path write out of
bounds?

When dmaengine_prep_dma_pq is called with DMA_PREP_CONTINUE and a
src_cnt of 14 to 16, the driver artificially increments src_cnt by 3 (up to
19).  This causes the loop initializing gfm_q1 (and subsequently scf copying)
to overflow the fixed-size 16-byte arrays.

Additionally, the continuation frames are written to cf[19], cf[20], and
cf[21], which overflows the 20-frame limit and can corrupt the adjacent
hardware Command Descriptor Block (CDB) structure.

>  		} else {
>  			dev_err(re_chan->dev, "PQ tx continuation error!\n");
>  			return NULL;
>  		}
> +	} else {
> +		/* Mark the last source buffer frame final */
> +		fill_cfd_frame(cf, i - 1, len, src[j - 1], 1);

[Severity: High]
Similar to the issue in fsl_re_prep_dma_genq(), does this access cause an
integer underflow if fsl_re_prep_dma_pq() is called with src_cnt == 0?

>  	}
>  
> -	/* Setting the final bit in the last source buffer frame in CFD */
> -	cf[i - 1].efrl32 |= 1 << FSL_RE_CF_FINAL_SHIFT;
> -
>  	return &desc->async_tx;
>  }

[ ... ]

[Severity: High]
This is a pre-existing issue, but does fsl_re_remove_chan() leak the
interrupt handler after module unload?

The function kills the tasklet and frees memory, but fails to call
free_irq(chan->irq, chan->dev).  This could leave the ISR active after the
driver is unloaded, potentially causing a use-after-free on the next
hardware interrupt:

drivers/dma/fsl_raid.c:fsl_re_remove_chan() {
    ...
	tasklet_kill(&chan->irqtask);
    ...
}

[Severity: High]
This is a pre-existing issue, but does fsl_re_remove() free DMA channel
resources before unregistering the DMA device?

The teardown sequence iterates over channels to destroy their rings before
notifying the DMA core.  This creates a race condition where a concurrent
client might submit a new DMA request into already freed memory:

drivers/dma/fsl_raid.c:fsl_re_remove() {
    ...
	/* Cleanup chan related memory areas */
	for (i = 0; i < re_priv->total_chans; i++)
		fsl_re_remove_chan(re_priv->re_jrs[i]);
	
	/* Unregister the driver */
	dma_async_device_unregister(&re_priv->dma_dev);
    ...
}

[Severity: High]
This is a pre-existing issue, but does fsl_re_probe() ignore probe failures
and blindly increment the active channel count?

drivers/dma/fsl_raid.c:fsl_re_probe() {
    ...
		if (rc) {
			fsl_re_chan_probe(ofdev, child, ridx++, off);
			re_priv->total_chans++;
		}
    ...
}

If fsl_re_chan_probe() fails, re_jrs[i] remains NULL.  During unload, the
teardown loop unconditionally dereferences it:

drivers/dma/fsl_raid.c:fsl_re_remove() {
    ...
	for (i = 0; i < re_priv->total_chans; i++)
		fsl_re_remove_chan(re_priv->re_jrs[i]);
    ...
}

Could this lead to a NULL pointer dereference in tasklet_kill() if a channel
failed to probe?

[Severity: High]
This is a pre-existing issue, but can fsl_re_dequeue() cause a recursive
locking deadlock if the client submits a new transaction from the callback?

fsl_re_dequeue() acquires desc_lock and holds it while executing the client
callback:

drivers/dma/fsl_raid.c:fsl_re_dequeue() {
    ...
	spin_lock_irqsave(&re_chan->desc_lock, flags);
	...
		fsl_re_desc_done(desc);
    ...
}

If the callback implements request chaining, fsl_re_tx_submit() will attempt
to synchronously re-acquire the exact same desc_lock:

drivers/dma/fsl_raid.c:fsl_re_tx_submit() {
    ...
	spin_lock_irqsave(&re_chan->desc_lock, flags);
    ...
}

[Severity: High]
This is a pre-existing issue, but does fsl_re_chan_probe() enable interrupts
before initialization is complete?

The IRQ is requested before drvdata is persistently linked to the device:

drivers/dma/fsl_raid.c:fsl_re_chan_probe() {
    ...
	ret = request_irq(chan->irq, fsl_re_isr, 0, chan->name, chandev);
	...
	dev_set_drvdata(chandev, chan);
    ...
}

If a pending or spurious interrupt fires immediately, fsl_re_isr() will call
dev_get_drvdata(), which returns NULL, and then dereference it:

drivers/dma/fsl_raid.c:fsl_re_isr() {
    ...
	re_chan = dev_get_drvdata((struct device *)data);

	irqstate = in_be32(&re_chan->jrregs->jr_interrupt_status);
    ...
}

[Severity: High]
This is a pre-existing issue, but does fill_cfd_frame() silently truncate
1MB transfers to 0 bytes?

drivers/dma/fsl_raid.c:fill_cfd_frame() {
    ...
	u32 efrl = length & FSL_RE_CF_LENGTH_MASK;
    ...
}

FSL_RE_MAX_DATA_LEN is defined as 1024*1024 (0x100000), allowing exactly 1MB.
However, if FSL_RE_CF_LENGTH_MASK is 0x000FFFFF (20 bits), the bitwise-AND
operation will silently truncate a 1MB transfer to 0.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260716202949.677290-3-rosenp@gmail.com?part=1

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCHv2 1/4] dma: fsl_raid: convert descriptor stores to big-endian
  2026-07-16 20:29 ` [PATCHv2 1/4] dma: fsl_raid: convert descriptor stores to big-endian Rosen Penev
  2026-07-16 20:44   ` sashiko-bot
@ 2026-07-16 20:49   ` Frank Li
  1 sibling, 0 replies; 11+ messages in thread
From: Frank Li @ 2026-07-16 20:49 UTC (permalink / raw)
  To: Rosen Penev; +Cc: dmaengine, Vinod Koul, Frank Li, open list

On Thu, Jul 16, 2026 at 01:29:46PM -0700, Rosen Penev wrote:
> The descriptor structs (fsl_re_cmpnd_frame / fsl_re_hw_desc) are
> in-memory but their fields are __be32, because the structures are handed
> to the device as big-endian. The driver stored CPU-endian u32 values
> into them directly, which is both wrong (the engine would see
> byte-swapped lengths/addresses) and flagged by sparse as a base-type
> mismatch.
>
> Wrap those stores in cpu_to_be32() so the values are little->big
> converted.
>
> Reported-by: kernel test robot <lkp@intel.com>
> Fixes: https://lore.kernel.org/oe-kbuild-all/202008111749.yy85rFMD%25lkp@intel.com/
> Assisted-by: opencode:hy3-free
> Signed-off-by: Rosen Penev <rosenp@gmail.com>
> ---

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

>  drivers/dma/fsl_raid.c | 13 +++++++------
>  1 file changed, 7 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/dma/fsl_raid.c b/drivers/dma/fsl_raid.c
> index 99945845d8b5..2778d07a05e8 100644
> --- a/drivers/dma/fsl_raid.c
> +++ b/drivers/dma/fsl_raid.c
> @@ -242,9 +242,9 @@ static void fill_cfd_frame(struct fsl_re_cmpnd_frame *cf, u8 index,
>  	u32 efrl = length & FSL_RE_CF_LENGTH_MASK;
>
>  	efrl |= final << FSL_RE_CF_FINAL_SHIFT;
> -	cf[index].efrl32 = efrl;
> -	cf[index].addr_high = upper_32_bits(addr);
> -	cf[index].addr_low = lower_32_bits(addr);
> +	cf[index].efrl32 = cpu_to_be32(efrl);
> +	cf[index].addr_high = cpu_to_be32(upper_32_bits(addr));
> +	cf[index].addr_low = cpu_to_be32(lower_32_bits(addr));
>  }
>
>  static struct fsl_re_desc *fsl_re_init_desc(struct fsl_re_chan *re_chan,
> @@ -256,9 +256,10 @@ static struct fsl_re_desc *fsl_re_init_desc(struct fsl_re_chan *re_chan,
>  	dma_async_tx_descriptor_init(&desc->async_tx, &re_chan->chan);
>  	INIT_LIST_HEAD(&desc->node);
>
> -	desc->hwdesc.fmt32 = FSL_RE_FRAME_FORMAT << FSL_RE_HWDESC_FMT_SHIFT;
> -	desc->hwdesc.lbea32 = upper_32_bits(paddr);
> -	desc->hwdesc.addr_low = lower_32_bits(paddr);
> +	desc->hwdesc.fmt32 = cpu_to_be32(FSL_RE_FRAME_FORMAT <<
> +					  FSL_RE_HWDESC_FMT_SHIFT);
> +	desc->hwdesc.lbea32 = cpu_to_be32(upper_32_bits(paddr));
> +	desc->hwdesc.addr_low = cpu_to_be32(lower_32_bits(paddr));
>  	desc->cf_addr = cf;
>  	desc->cf_paddr = paddr;
>
> --
> 2.55.0
>

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCHv2 2/4] dma: fsl_raid: set final bit via fill_cfd_frame() argument
  2026-07-16 20:29 ` [PATCHv2 2/4] dma: fsl_raid: set final bit via fill_cfd_frame() argument Rosen Penev
  2026-07-16 20:47   ` sashiko-bot
@ 2026-07-16 20:57   ` Frank Li
  1 sibling, 0 replies; 11+ messages in thread
From: Frank Li @ 2026-07-16 20:57 UTC (permalink / raw)
  To: Rosen Penev; +Cc: dmaengine, Vinod Koul, Frank Li, open list

On Thu, Jul 16, 2026 at 01:29:47PM -0700, Rosen Penev wrote:
> The final-frame bit is now passed as the "final" argument of
> fill_cfd_frame() (as fsl_re_prep_dma_memcpy already did) and set in CPU
> order before the single cpu_to_be32() store, replacing the previous
> read-modify-write of the __be32 efrl32 field.
>
> Assisted-by: opencode:hy3-free
> Signed-off-by: Rosen Penev <rosenp@gmail.com>
> ---

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

>  drivers/dma/fsl_raid.c | 16 ++++++++--------
>  1 file changed, 8 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/dma/fsl_raid.c b/drivers/dma/fsl_raid.c
> index 2778d07a05e8..888f55b672a5 100644
> --- a/drivers/dma/fsl_raid.c
> +++ b/drivers/dma/fsl_raid.c
> @@ -375,11 +375,11 @@ static struct dma_async_tx_descriptor *fsl_re_prep_dma_genq(
>  	for (i = 2, j = 0; j < save_src_cnt; i++, j++)
>  		fill_cfd_frame(cf, i, len, src[j], 0);
>
> +	/* Fill the last frame and mark it final */
>  	if (cont_q)
> -		fill_cfd_frame(cf, i++, len, dest, 0);
> -
> -	/* Setting the final bit in the last source buffer frame in CFD */
> -	cf[i - 1].efrl32 |= 1 << FSL_RE_CF_FINAL_SHIFT;
> +		fill_cfd_frame(cf, i, len, dest, 1);
> +	else
> +		fill_cfd_frame(cf, i - 1, len, src[j - 1], 1);
>
>  	return &desc->async_tx;
>  }
> @@ -505,16 +505,16 @@ static struct dma_async_tx_descriptor *fsl_re_prep_dma_pq(
>  			p[save_src_cnt + 2] = 1;
>  			fill_cfd_frame(cf, i++, len, dest[0], 0);
>  			fill_cfd_frame(cf, i++, len, dest[1], 0);
> -			fill_cfd_frame(cf, i++, len, dest[1], 0);
> +			fill_cfd_frame(cf, i++, len, dest[1], 1);
>  		} else {
>  			dev_err(re_chan->dev, "PQ tx continuation error!\n");
>  			return NULL;
>  		}
> +	} else {
> +		/* Mark the last source buffer frame final */
> +		fill_cfd_frame(cf, i - 1, len, src[j - 1], 1);
>  	}
>
> -	/* Setting the final bit in the last source buffer frame in CFD */
> -	cf[i - 1].efrl32 |= 1 << FSL_RE_CF_FINAL_SHIFT;
> -
>  	return &desc->async_tx;
>  }
>
> --
> 2.55.0
>

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCHv2 3/4] dma: fsl_raid: keep MMIO bases as void __iomem and cast at access
  2026-07-16 20:29 ` [PATCHv2 3/4] dma: fsl_raid: keep MMIO bases as void __iomem and cast at access Rosen Penev
  2026-07-16 20:44   ` sashiko-bot
@ 2026-07-16 21:02   ` Frank Li
  1 sibling, 0 replies; 11+ messages in thread
From: Frank Li @ 2026-07-16 21:02 UTC (permalink / raw)
  To: Rosen Penev; +Cc: dmaengine, Vinod Koul, Frank Li, open list

On Thu, Jul 16, 2026 at 01:29:48PM -0700, Rosen Penev wrote:
> The fsl_re_ctrl and fsl_re_chan_cfg structures describe memory-mapped
> RAID Engine registers accessed only via ioread32be()/iowrite32be(), yet
> the pointers to them (re_regs in struct fsl_re_drv_private, and jrregs
> in struct fsl_re_chan) were not __iomem-qualified, so sparse emitted
> "different address spaces" warnings for every register access.
>
> Store both MMIO bases as a plain void __iomem * and derive jrregs with
> void __iomem * arithmetic from re_regs, rather than carrying typed
                                 ^ base

> register struct pointers through the driver. Each function that touches
> the registers introduces a local typed pointer (struct fsl_re_ctrl
> __iomem *ctrl) and uses ->field, which is the idiomatic kernel pattern
>  and keeps the registers' __iomem qualification intact.
>
> Reported-by: kernel test robot <lkp@intel.com>
> Fixes: https://lore.kernel.org/oe-kbuild-all/202008111749.yy85rFMD%25lkp@intel.com/
> Assisted-by: opencode:hy3-free
> Signed-off-by: Rosen Penev <rosenp@gmail.com>
> ---

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

>  drivers/dma/fsl_raid.c | 19 ++++++++++---------
>  drivers/dma/fsl_raid.h |  4 ++--
>  2 files changed, 12 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/dma/fsl_raid.c b/drivers/dma/fsl_raid.c
> index 888f55b672a5..524f83faf3da 100644
> --- a/drivers/dma/fsl_raid.c
> +++ b/drivers/dma/fsl_raid.c
> @@ -657,8 +657,7 @@ static int fsl_re_chan_probe(struct platform_device *ofdev,
>  		goto err_free;
>  	}
>
> -	chan->jrregs = (struct fsl_re_chan_cfg *)((u8 *)re_priv->re_regs +
> -			off + ptr);
> +	chan->jrregs = re_priv->base + off + ptr;
>
>  	/* read irq property from dts */
>  	chan->irq = irq_of_parse_and_map(np, 0);
> @@ -746,6 +745,7 @@ static int fsl_re_chan_probe(struct platform_device *ofdev,
>  /* Probe function for RAID Engine */
>  static int fsl_re_probe(struct platform_device *ofdev)
>  {
> +	struct fsl_re_ctrl __iomem *re_regs;
>  	struct fsl_re_drv_private *re_priv;
>  	struct device_node *child;
>  	u32 off;
> @@ -764,20 +764,21 @@ static int fsl_re_probe(struct platform_device *ofdev)
>  		return -ENODEV;
>
>  	/* IOMAP the entire RAID Engine region */
> -	re_priv->re_regs = devm_ioremap(dev, res->start, resource_size(res));
> -	if (!re_priv->re_regs)
> +	re_regs = devm_ioremap(dev, res->start, resource_size(res));
> +	if (!re_regs)
>  		return -EBUSY;
> +	re_priv->base = re_regs;
>
>  	/* Program the RE mode */
> -	out_be32(&re_priv->re_regs->global_config, FSL_RE_NON_DPAA_MODE);
> +	out_be32(&re_regs->global_config, FSL_RE_NON_DPAA_MODE);
>
>  	/* Program Galois Field polynomial */
> -	out_be32(&re_priv->re_regs->galois_field_config, FSL_RE_GFM_POLY);
> +	out_be32(&re_regs->galois_field_config, FSL_RE_GFM_POLY);
>
>  	dev_info(dev, "version %x, mode %x, gfp %x\n",
> -		 in_be32(&re_priv->re_regs->re_version_id),
> -		 in_be32(&re_priv->re_regs->global_config),
> -		 in_be32(&re_priv->re_regs->galois_field_config));
> +		 in_be32(&re_regs->re_version_id),
> +		 in_be32(&re_regs->global_config),
> +		 in_be32(&re_regs->galois_field_config));
>
>  	dma_dev = &re_priv->dma_dev;
>  	dma_dev->dev = dev;
> diff --git a/drivers/dma/fsl_raid.h b/drivers/dma/fsl_raid.h
> index 69d743c04973..adbfede330a7 100644
> --- a/drivers/dma/fsl_raid.h
> +++ b/drivers/dma/fsl_raid.h
> @@ -256,7 +256,7 @@ struct fsl_re_hw_desc {
>  struct fsl_re_drv_private {
>  	u8 total_chans;
>  	struct dma_device dma_dev;
> -	struct fsl_re_ctrl *re_regs;
> +	void __iomem *base;
>  	struct fsl_re_chan *re_jrs[FSL_RE_MAX_CHANS];
>  	struct dma_pool *cf_desc_pool;
>  	struct dma_pool *hw_desc_pool;
> @@ -273,7 +273,7 @@ struct fsl_re_chan {
>  	struct device *dev;
>  	struct fsl_re_drv_private *re_dev;
>  	struct dma_chan chan;
> -	struct fsl_re_chan_cfg *jrregs;
> +	struct fsl_re_chan_cfg __iomem *jrregs;
>  	int irq;
>  	struct tasklet_struct irqtask;
>  	u32 alloc_count;
> --
> 2.55.0
>

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2026-07-16 21:03 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-16 20:29 [PATCHv2 0/4] dma: fsl_raid: fix sparse warnings and simplify probing Rosen Penev
2026-07-16 20:29 ` [PATCHv2 1/4] dma: fsl_raid: convert descriptor stores to big-endian Rosen Penev
2026-07-16 20:44   ` sashiko-bot
2026-07-16 20:49   ` Frank Li
2026-07-16 20:29 ` [PATCHv2 2/4] dma: fsl_raid: set final bit via fill_cfd_frame() argument Rosen Penev
2026-07-16 20:47   ` sashiko-bot
2026-07-16 20:57   ` Frank Li
2026-07-16 20:29 ` [PATCHv2 3/4] dma: fsl_raid: keep MMIO bases as void __iomem and cast at access Rosen Penev
2026-07-16 20:44   ` sashiko-bot
2026-07-16 21:02   ` Frank Li
2026-07-16 20:29 ` [PATCHv2 4/4] dma: fsl_raid: use devm_platform_ioremap_resource Rosen Penev

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