From 742c2a8041e8c23ec4ac6688284ac12c623df1cc Mon Sep 17 00:00:00 2001 From: Koichiro Den Date: Sun, 13 Sep 2026 02:40:23 +0900 Subject: [PATCH] dmaengine: dw-edma: Account for the MSI vector offset 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 Signed-off-by: Koichiro Den Link: https://patch.msgid.link/20260912174023.1227397-4-den@valinux.co.jp Signed-off-by: Vinod Koul --- 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 da14b6b9cbc6..b08bb31657c9 100644 --- a/drivers/dma/dw-edma/dw-edma-core.c +++ b/drivers/dma/dw-edma/dw-edma-core.c @@ -7,6 +7,7 @@ */ #include +#include #include #include #include @@ -1237,12 +1238,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; @@ -1267,8 +1279,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 { @@ -1291,12 +1302,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;