[PATCH 01/15] dmaengine: dw-edma: Cache DMA channel IDs in dw_edma_chip

Koichiro Den posted 15 patches 3 weeks, 4 days ago
[PATCH 01/15] dmaengine: dw-edma: Cache DMA channel IDs in dw_edma_chip
Posted by Koichiro Den 3 weeks, 4 days ago
The exported-DMA path needs to describe each exposed descriptor window
with the DMAEngine channel ID that owns it. Those IDs are only assigned
once the channels have been registered.

Cache the dma_chan IDs in dw_edma_chip after registration so controller
frontends can later publish them as auxiliary-resource metadata without
reaching back into the live channel objects.

Signed-off-by: Koichiro Den <den@valinux.co.jp>
---
 drivers/dma/dw-edma/dw-edma-core.c | 18 +++++++++++++++++-
 include/linux/dma/edma.h           |  4 ++++
 2 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/drivers/dma/dw-edma/dw-edma-core.c b/drivers/dma/dw-edma/dw-edma-core.c
index cd34a3ea602d..a13beacce2e7 100644
--- a/drivers/dma/dw-edma/dw-edma-core.c
+++ b/drivers/dma/dw-edma/dw-edma-core.c
@@ -837,6 +837,7 @@ static int dw_edma_channel_setup(struct dw_edma *dw, u32 wr_alloc, u32 rd_alloc)
 	struct dma_device *dma;
 	u32 i, ch_cnt;
 	u32 pos;
+	int ret;
 
 	ch_cnt = dw->wr_ch_cnt + dw->rd_ch_cnt;
 	dma = &dw->dma;
@@ -932,7 +933,22 @@ static int dw_edma_channel_setup(struct dw_edma *dw, u32 wr_alloc, u32 rd_alloc)
 	dma_set_max_seg_size(dma->dev, U32_MAX);
 
 	/* Register DMA device */
-	return dma_async_device_register(dma);
+	ret = dma_async_device_register(dma);
+	if (ret)
+		return ret;
+
+	/* Cache dma_chan.id in dw_edma_chip */
+	for (i = 0; i < ch_cnt; i++) {
+		chan = &dw->chan[i];
+
+		if (i < dw->wr_ch_cnt)
+			chip->chan_ids_wr[i] = chan->vc.chan.chan_id;
+		else
+			chip->chan_ids_rd[i - dw->wr_ch_cnt] =
+						chan->vc.chan.chan_id;
+	}
+
+	return 0;
 }
 
 static inline void dw_edma_dec_irq_alloc(int *nr_irqs, u32 *alloc, u16 cnt)
diff --git a/include/linux/dma/edma.h b/include/linux/dma/edma.h
index 9da53c75e49b..0b861e8d305e 100644
--- a/include/linux/dma/edma.h
+++ b/include/linux/dma/edma.h
@@ -100,6 +100,10 @@ struct dw_edma_chip {
 	int			db_irq;
 	resource_size_t		db_offset;
 
+	/* dma_chan ids */
+	int			chan_ids_wr[EDMA_MAX_WR_CH];
+	int			chan_ids_rd[EDMA_MAX_RD_CH];
+
 	enum dw_edma_map_format	mf;
 
 	struct dw_edma		*dw;
-- 
2.51.0
Re: [PATCH 01/15] dmaengine: dw-edma: Cache DMA channel IDs in dw_edma_chip
Posted by Frank Li 3 weeks, 4 days ago
On Fri, Mar 13, 2026 at 01:49:51AM +0900, Koichiro Den wrote:
> The exported-DMA path needs to describe each exposed descriptor window
> with the DMAEngine channel ID that owns it. Those IDs are only assigned
> once the channels have been registered.
>
> Cache the dma_chan IDs in dw_edma_chip after registration so controller
> frontends can later publish them as auxiliary-resource metadata without
> reaching back into the live channel objects.
>
> Signed-off-by: Koichiro Den <den@valinux.co.jp>
> ---
>  drivers/dma/dw-edma/dw-edma-core.c | 18 +++++++++++++++++-
>  include/linux/dma/edma.h           |  4 ++++
>  2 files changed, 21 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/dma/dw-edma/dw-edma-core.c b/drivers/dma/dw-edma/dw-edma-core.c
> index cd34a3ea602d..a13beacce2e7 100644
> --- a/drivers/dma/dw-edma/dw-edma-core.c
> +++ b/drivers/dma/dw-edma/dw-edma-core.c
> @@ -837,6 +837,7 @@ static int dw_edma_channel_setup(struct dw_edma *dw, u32 wr_alloc, u32 rd_alloc)
>  	struct dma_device *dma;
>  	u32 i, ch_cnt;
>  	u32 pos;
> +	int ret;
>
>  	ch_cnt = dw->wr_ch_cnt + dw->rd_ch_cnt;
>  	dma = &dw->dma;
> @@ -932,7 +933,22 @@ static int dw_edma_channel_setup(struct dw_edma *dw, u32 wr_alloc, u32 rd_alloc)
>  	dma_set_max_seg_size(dma->dev, U32_MAX);
>
>  	/* Register DMA device */
> -	return dma_async_device_register(dma);
> +	ret = dma_async_device_register(dma);
> +	if (ret)
> +		return ret;
> +
> +	/* Cache dma_chan.id in dw_edma_chip */
> +	for (i = 0; i < ch_cnt; i++) {
> +		chan = &dw->chan[i];
> +
> +		if (i < dw->wr_ch_cnt)
> +			chip->chan_ids_wr[i] = chan->vc.chan.chan_id;
> +		else
> +			chip->chan_ids_rd[i - dw->wr_ch_cnt] =
> +						chan->vc.chan.chan_id;
> +	}

why need cache in dw_edma_chip? you's cache into chan.

Frank
> +
> +	return 0;
>  }
>
>  static inline void dw_edma_dec_irq_alloc(int *nr_irqs, u32 *alloc, u16 cnt)
> diff --git a/include/linux/dma/edma.h b/include/linux/dma/edma.h
> index 9da53c75e49b..0b861e8d305e 100644
> --- a/include/linux/dma/edma.h
> +++ b/include/linux/dma/edma.h
> @@ -100,6 +100,10 @@ struct dw_edma_chip {
>  	int			db_irq;
>  	resource_size_t		db_offset;
>
> +	/* dma_chan ids */
> +	int			chan_ids_wr[EDMA_MAX_WR_CH];
> +	int			chan_ids_rd[EDMA_MAX_RD_CH];
> +
>  	enum dw_edma_map_format	mf;
>
>  	struct dw_edma		*dw;
> --
> 2.51.0
>
Re: [PATCH 01/15] dmaengine: dw-edma: Cache DMA channel IDs in dw_edma_chip
Posted by Koichiro Den 3 weeks, 4 days ago
On Thu, Mar 12, 2026 at 04:05:21PM -0400, Frank Li wrote:
> On Fri, Mar 13, 2026 at 01:49:51AM +0900, Koichiro Den wrote:
> > The exported-DMA path needs to describe each exposed descriptor window
> > with the DMAEngine channel ID that owns it. Those IDs are only assigned
> > once the channels have been registered.
> >
> > Cache the dma_chan IDs in dw_edma_chip after registration so controller
> > frontends can later publish them as auxiliary-resource metadata without
> > reaching back into the live channel objects.
> >
> > Signed-off-by: Koichiro Den <den@valinux.co.jp>
> > ---
> >  drivers/dma/dw-edma/dw-edma-core.c | 18 +++++++++++++++++-
> >  include/linux/dma/edma.h           |  4 ++++
> >  2 files changed, 21 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/dma/dw-edma/dw-edma-core.c b/drivers/dma/dw-edma/dw-edma-core.c
> > index cd34a3ea602d..a13beacce2e7 100644
> > --- a/drivers/dma/dw-edma/dw-edma-core.c
> > +++ b/drivers/dma/dw-edma/dw-edma-core.c
> > @@ -837,6 +837,7 @@ static int dw_edma_channel_setup(struct dw_edma *dw, u32 wr_alloc, u32 rd_alloc)
> >  	struct dma_device *dma;
> >  	u32 i, ch_cnt;
> >  	u32 pos;
> > +	int ret;
> >
> >  	ch_cnt = dw->wr_ch_cnt + dw->rd_ch_cnt;
> >  	dma = &dw->dma;
> > @@ -932,7 +933,22 @@ static int dw_edma_channel_setup(struct dw_edma *dw, u32 wr_alloc, u32 rd_alloc)
> >  	dma_set_max_seg_size(dma->dev, U32_MAX);
> >
> >  	/* Register DMA device */
> > -	return dma_async_device_register(dma);
> > +	ret = dma_async_device_register(dma);
> > +	if (ret)
> > +		return ret;
> > +
> > +	/* Cache dma_chan.id in dw_edma_chip */
> > +	for (i = 0; i < ch_cnt; i++) {
> > +		chan = &dw->chan[i];
> > +
> > +		if (i < dw->wr_ch_cnt)
> > +			chip->chan_ids_wr[i] = chan->vc.chan.chan_id;
> > +		else
> > +			chip->chan_ids_rd[i - dw->wr_ch_cnt] =
> > +						chan->vc.chan.chan_id;
> > +	}
> 
> why need cache in dw_edma_chip? you's cache into chan.

The reason I cached dma_chan::chan_id in dw_edma_chip is that
dw_pcie_ep_get_aux_resources() later needs to populate
PCI_EPC_AUX_DMA_CHAN_DESC with a key that can be matched against the struct
dma_chan instances returned by repeated dma_request_channel().

The delegated set returned by repeated dma_request_channel() is not
guaranteed to correspond to the first N READ channels, since some READ
channels may already be in use by another local consumer. So I do need some
explicit matching key.

If you have a cleaner way to correlate a delegated struct dma_chan with the
corresponding pci_epc_aux_resource, I would be happy to rework it.

(More fundamentally, for sparse channels export I think we will eventually
need to carry the hardware channel number separately as well.)

Thanks,
Koichiro

> 
> Frank
> > +
> > +	return 0;
> >  }
> >
> >  static inline void dw_edma_dec_irq_alloc(int *nr_irqs, u32 *alloc, u16 cnt)
> > diff --git a/include/linux/dma/edma.h b/include/linux/dma/edma.h
> > index 9da53c75e49b..0b861e8d305e 100644
> > --- a/include/linux/dma/edma.h
> > +++ b/include/linux/dma/edma.h
> > @@ -100,6 +100,10 @@ struct dw_edma_chip {
> >  	int			db_irq;
> >  	resource_size_t		db_offset;
> >
> > +	/* dma_chan ids */
> > +	int			chan_ids_wr[EDMA_MAX_WR_CH];
> > +	int			chan_ids_rd[EDMA_MAX_RD_CH];
> > +
> >  	enum dw_edma_map_format	mf;
> >
> >  	struct dw_edma		*dw;
> > --
> > 2.51.0
> >