On Fri, Feb 06, 2026 at 12:56:24PM -0500, Frank Li wrote: > On Sat, Feb 07, 2026 at 02:26:40AM +0900, Koichiro Den wrote: > > Endpoint controller drivers may need to expose or consume eDMA-related > > resources (e.g. for remote programming or doorbell/self-tests). For > > that, consumers need a stable way to discover the Linux IRQ used by a > > given eDMA channel/vector and a register offset suitable for interrupt > > emulation. > > > > Record each channel's IRQ-vector index and store the requested Linux IRQ > > number. Add a core callback .ch_info() to provide core-specific metadata > > and implement it for v0. > > > > Export dw_edma_chan_info() so that platform drivers can retrieve: > > - per-channel device name > > - Linux IRQ number for the channel's interrupt vector > > - offset of the register used as an emulated-interrupt doorbell within > > the eDMA register window. > > > > Signed-off-by: Koichiro Den <[email protected]> > > --- > > drivers/dma/dw-edma/dw-edma-core.c | 31 +++++++++++++++++++++++++++ > > drivers/dma/dw-edma/dw-edma-core.h | 14 ++++++++++++ > > drivers/dma/dw-edma/dw-edma-v0-core.c | 7 ++++++ > > include/linux/dma/edma.h | 20 +++++++++++++++++ > > 4 files changed, 72 insertions(+) > > > > diff --git a/drivers/dma/dw-edma/dw-edma-core.c > > b/drivers/dma/dw-edma/dw-edma-core.c > > index dd01a9aa8ad8..147a5466e4e7 100644 > > --- a/drivers/dma/dw-edma/dw-edma-core.c > > +++ b/drivers/dma/dw-edma/dw-edma-core.c > > @@ -842,6 +842,7 @@ static int dw_edma_channel_setup(struct dw_edma *dw, > > u32 wr_alloc, u32 rd_alloc) > > else > > pos = wr_alloc + chan->id % rd_alloc; > > > > + chan->irq_idx = pos; > > irq = &dw->irq[pos]; > > > > if (chan->dir == EDMA_DIR_WRITE) > > @@ -947,6 +948,7 @@ static int dw_edma_irq_request(struct dw_edma *dw, > > if (irq_get_msi_desc(irq)) > > get_cached_msi_msg(irq, &dw->irq[0].msi); > > > > + dw->irq[0].irq = irq; > > dw->nr_irqs = 1; > > } else { > > /* Distribute IRQs equally among all channels */ > > @@ -973,6 +975,7 @@ static int dw_edma_irq_request(struct dw_edma *dw, > > > > if (irq_get_msi_desc(irq)) > > get_cached_msi_msg(irq, &dw->irq[i].msi); > > + dw->irq[i].irq = irq; > > } > > > > dw->nr_irqs = i; > > @@ -1098,6 +1101,34 @@ int dw_edma_remove(struct dw_edma_chip *chip) > > } > > EXPORT_SYMBOL_GPL(dw_edma_remove); > > > > +int dw_edma_chan_info(struct dw_edma_chip *chip, unsigned int ch_idx, > > + struct dw_edma_chan_info *info) > > +{ > > + struct dw_edma *dw = chip->dw; > > + struct dw_edma_chan *chan; > > + struct dma_chan *dchan; > > + u32 ch_cnt; > > + int ret; > > + > > + if (!chip || !info || !dw) > > + return -EINVAL; > > + > > + ch_cnt = dw->wr_ch_cnt + dw->rd_ch_cnt; > > + if (ch_idx >= ch_cnt) > > + return -EINVAL; > > + > > + chan = &dw->chan[ch_idx]; > > + dchan = &chan->vc.chan; > > + > > + ret = dw_edma_core_ch_info(dw, chan, info); > > + if (ret) > > + return ret; > > + > > + info->irq = dw->irq[chan->irq_idx].irq; > > + return 0; > > +} > > +EXPORT_SYMBOL_GPL(dw_edma_chan_info); > > + > > MODULE_LICENSE("GPL v2"); > > MODULE_DESCRIPTION("Synopsys DesignWare eDMA controller core driver"); > > MODULE_AUTHOR("Gustavo Pimentel <[email protected]>"); > > diff --git a/drivers/dma/dw-edma/dw-edma-core.h > > b/drivers/dma/dw-edma/dw-edma-core.h > > index abc97e375484..e92891ed5536 100644 > > --- a/drivers/dma/dw-edma/dw-edma-core.h > > +++ b/drivers/dma/dw-edma/dw-edma-core.h > > @@ -82,6 +82,7 @@ struct dw_edma_chan { > > struct msi_msg msi; > > > > enum dw_edma_ch_irq_mode irq_mode; > > + u32 irq_idx; > > can we directly save irq_number?
Yes, that makes sense. I'll address this in v5 together with the changes based on the discussion here: https://lore.kernel.org/dmaengine/cuihp4wo5bcku75myq7mfbfvyddwptitiyy6pz5ldq2l6robxk@kghlibxpr7wf/ > > > > > enum dw_edma_request request; > > enum dw_edma_status status; > > @@ -95,6 +96,7 @@ struct dw_edma_irq { > > u32 wr_mask; > > u32 rd_mask; > > struct dw_edma *dw; > > + int irq; > > }; > > > > struct dw_edma { > > @@ -129,6 +131,7 @@ struct dw_edma_core_ops { > > void (*ch_config)(struct dw_edma_chan *chan); > > void (*debugfs_on)(struct dw_edma *dw); > > void (*ack_selfirq)(struct dw_edma *dw); > > + void (*ch_info)(struct dw_edma_chan *chan, struct dw_edma_chan_info > > *info); > > }; > > > > struct dw_edma_sg { > > @@ -219,6 +222,17 @@ int dw_edma_core_ack_selfirq(struct dw_edma *dw) > > return 0; > > } > > > > +static inline > > +int dw_edma_core_ch_info(struct dw_edma *dw, struct dw_edma_chan *chan, > > + struct dw_edma_chan_info *info) > > wrap int to previous line, check others. Thanks for pointing that out. I'll update it for the same reasons as discussed here: https://lore.kernel.org/dmaengine/qktad6ggosznbznej7n2luxwkhr34f3egtojzjnkry4v2balbh@sfxxoii5yxoa/ Thanks, Koichiro > > Frank > > +{ > > + if (!dw->core->ch_info) > > + return -EOPNOTSUPP; > > + > > + dw->core->ch_info(chan, info); > > + return 0; > > +} > > + > > static inline > > bool dw_edma_core_ch_ignore_irq(struct dw_edma_chan *chan) > > { > > diff --git a/drivers/dma/dw-edma/dw-edma-v0-core.c > > b/drivers/dma/dw-edma/dw-edma-v0-core.c > > index 68e0d088570d..9c7908a76fff 100644 > > --- a/drivers/dma/dw-edma/dw-edma-v0-core.c > > +++ b/drivers/dma/dw-edma/dw-edma-v0-core.c > > @@ -529,6 +529,12 @@ static void dw_edma_v0_core_ack_selfirq(struct dw_edma > > *dw) > > SET_BOTH_32(dw, int_clear, 0); > > } > > > > +static void dw_edma_v0_core_ch_info(struct dw_edma_chan *chan, > > + struct dw_edma_chan_info *info) > > +{ > > + info->db_offset = offsetof(struct dw_edma_v0_regs, rd_int_status); > > +} > > + > > static const struct dw_edma_core_ops dw_edma_v0_core = { > > .off = dw_edma_v0_core_off, > > .ch_count = dw_edma_v0_core_ch_count, > > @@ -538,6 +544,7 @@ static const struct dw_edma_core_ops dw_edma_v0_core = { > > .ch_config = dw_edma_v0_core_ch_config, > > .debugfs_on = dw_edma_v0_core_debugfs_on, > > .ack_selfirq = dw_edma_v0_core_ack_selfirq, > > + .ch_info = dw_edma_v0_core_ch_info, > > }; > > > > void dw_edma_v0_core_register(struct dw_edma *dw) > > diff --git a/include/linux/dma/edma.h b/include/linux/dma/edma.h > > index 53b31a974331..9fd78dc313e5 100644 > > --- a/include/linux/dma/edma.h > > +++ b/include/linux/dma/edma.h > > @@ -129,10 +129,23 @@ struct dw_edma_chip { > > struct dw_edma *dw; > > }; > > > > +/** > > + * struct dw_edma_chan_info - DW eDMA channel metadata > > + * @irq: Linux IRQ number used by this channel's interrupt vector > > + * @db_offset: offset within the eDMA register window that can be used > > as > > + * an interrupt-emulation doorbell for this channel > > + */ > > +struct dw_edma_chan_info { > > + int irq; > > + resource_size_t db_offset; > > +}; > > + > > /* Export to the platform drivers */ > > #if IS_REACHABLE(CONFIG_DW_EDMA) > > int dw_edma_probe(struct dw_edma_chip *chip); > > int dw_edma_remove(struct dw_edma_chip *chip); > > +int dw_edma_chan_info(struct dw_edma_chip *chip, unsigned int ch_idx, > > + struct dw_edma_chan_info *info); > > #else > > static inline int dw_edma_probe(struct dw_edma_chip *chip) > > { > > @@ -143,6 +156,13 @@ static inline int dw_edma_remove(struct dw_edma_chip > > *chip) > > { > > return 0; > > } > > + > > +static inline int dw_edma_chan_info(struct dw_edma_chip *chip, > > + unsigned int ch_idx, > > + struct dw_edma_chan_info *info) > > +{ > > + return -ENODEV; > > +} > > #endif /* CONFIG_DW_EDMA */ > > > > #endif /* _DW_EDMA_H */ > > -- > > 2.51.0 > >

