mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
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 <Frank.Li@nxp.com> Signed-off-by: Koichiro Den <den@valinux.co.jp> Link: https://patch.msgid.link/20260912174023.1227397-4-den@valinux.co.jp Signed-off-by: Vinod Koul <vkoul@kernel.org>
This commit is contained in:
parent
9d31ad3b33
commit
742c2a8041
|
|
@ -7,6 +7,7 @@
|
|||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/kernel.h>
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user