[PATCH v4 3/3] dmaengine: dw-edma: Account for the MSI vector offset
From: Koichiro Den <hidden>
Date: 2026-09-12 17:40:35
Also in:
lkml
Subsystem:
designware edma core ip driver, dma generic offload engine subsystem, the rest · Maintainers:
Manivannan Sadhasivam, Vinod Koul, Linus Torvalds
get_cached_msi_msg() returns the base message shared by a multi-MSI descriptor. dw-edma currently derives per-channel data from its local IRQ index and does not adjust a common IRQ at all. Both assume eDMA starts at the descriptor's first vector. That is not true when eDMA receives a tail subset. Compose each message from the IRQ offset relative to the descriptor base in both paths. While at it, avoid reading PCI MSI attributes from descriptors owned by non-PCI devices. Reviewed-by: Frank Li <Frank.Li@nxp.com> Signed-off-by: Koichiro Den <redacted> --- Changes in v4: - No changes. drivers/dma/dw-edma/dw-edma-core.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-)
diff --git a/drivers/dma/dw-edma/dw-edma-core.c b/drivers/dma/dw-edma/dw-edma-core.c
index c978da30bac5..1e6fbe0922a9 100644
--- a/drivers/dma/dw-edma/dw-edma-core.c
+++ b/drivers/dma/dw-edma/dw-edma-core.c@@ -7,6 +7,7 @@ */ #include <linux/module.h> +#include <linux/pci.h> #include <linux/delay.h> #include <linux/device.h> #include <linux/kernel.h>
@@ -1106,12 +1107,23 @@ static inline void dw_edma_dec_irq_alloc(int *nr_irqs, u32 *alloc, u16 cnt) } } +static void dw_edma_compose_msi(int irq, struct msi_msg *msi) +{ + struct msi_desc *desc = irq_get_msi_desc(irq); + + if (!desc) + return; + + get_cached_msi_msg(irq, msi); + if (dev_is_pci(desc->dev) && !desc->pci.msi_attrib.is_msix) + msi->data += irq - desc->irq; +} + static int dw_edma_irq_request(struct dw_edma *dw, u32 *wr_alloc, u32 *rd_alloc) { struct dw_edma_chip *chip = dw->chip; struct device *dev = dw->chip->dev; - struct msi_desc *msi_desc; int i, err = 0; u32 ch_cnt; int irq;
@@ -1136,8 +1148,7 @@ static int dw_edma_irq_request(struct dw_edma *dw, return err; } - if (irq_get_msi_desc(irq)) - get_cached_msi_msg(irq, &dw->irq[0].msi); + dw_edma_compose_msi(irq, &dw->irq[0].msi); dw->nr_irqs = 1; } else {
@@ -1160,12 +1171,7 @@ static int dw_edma_irq_request(struct dw_edma *dw, &dw->irq[i]); if (err) goto err_irq_free; - msi_desc = irq_get_msi_desc(irq); - if (msi_desc) { - get_cached_msi_msg(irq, &dw->irq[i].msi); - if (!msi_desc->pci.msi_attrib.is_msix) - dw->irq[i].msi.data = dw->irq[0].msi.data + i; - } + dw_edma_compose_msi(irq, &dw->irq[i].msi); } dw->nr_irqs = i;
--
2.51.0