Re: [PATCH] dmaengine: pl08x: mark slave channels as DMA_PRIVATE

From: Andreas Gabriel-Platschek

Date: Tue Oct 27 2026 - 14:32:15 EST



On 10/27/26 3:39 PM, Frank Li wrote:
On Tue, Oct 27, 2026 at 08:00:37AM +0100, Andreas Gabriel-Platschek wrote:
[You don't often get email from andi.platschek@xxxxxxxxx. Learn why this is important at https://aka.ms/LearnAboutSenderIdentification ]

The pl08x slave engine channels are only ever handed out through
explicit requests: DT clients go via pl08x_of_xlate() and the
platform-data path uses dma_request_channel() with a filter, both of
which end up in dma_get_slave_channel(). They are not meant to be
published in the general-purpose channel table.

Mark the slave device with DMA_PRIVATE at probe time so the dmaengine
core treats it as always-private. Without this, if a dmaengine client
is already active when the device is registered,
dma_async_device_register() takes a reference on every channel,
Code change is okay. Are you sure the above description correct? where
code set it active when dma_async_device_register().

Frank

I do think so, because

async_damengine_get() -> dmaengine_get() is called from crypto/async_tx/async_tx.c and increments the dmaengine_ref_count.
This way the dmaengine_ref_count is already >=1 before the pl08x dmaengine probes.

dma_async_device_register() (in dmaengine.c) iterates over the channels inside of the following conditional:

 if (dmaengine_ref_count && !dma_has_cap(DMA_PRIVATE, device->cap_mask))

and in there a dma_chan_get() is called for each channel and increments the client_count. With a client_count  >=1 we fail once pl08x_of_xlate()->dma_get_slave_channel() is called.

setting DMA_PRIVATE prevents the client_count from being incremented by the core, keeping the client_count at 0 until a real client requests one

hope that makes sense?
best!
Andi

and
the subsequent dma_get_slave_channel() from pl08x_of_xlate() fails
because the channel is no longer free (client_count != 0), leaving DT
slave clients unable to acquire channels.

The memcpy engine stays public as it is intended to be shared through
the per-CPU channel table.

Signed-off-by: Andreas Gabriel-Platschek <andi.platschek@xxxxxxxxx>
---
drivers/dma/amba-pl08x.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index 543c2eb8cfa8..06881d3f29a9 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -2775,6 +2775,7 @@ static int pl08x_probe(struct amba_device *adev, const struct amba_id *id)
pl08x->has_slave = true;
dma_cap_set(DMA_SLAVE, pl08x->slave.cap_mask);
dma_cap_set(DMA_CYCLIC, pl08x->slave.cap_mask);
+ dma_cap_set(DMA_PRIVATE, pl08x->slave.cap_mask);
pl08x->slave.dev = &adev->dev;
pl08x->slave.device_free_chan_resources =
pl08x_free_chan_resources;
--
2.47.3