mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 20:54:03 +02:00
dmaengine: dw-edma: Move control field update of DMA link to the last step
The control field in a DMA link list entry must be updated as the final step because it includes the CB bit, which indicates whether the entry is ready. Add dma_wmb() to ensure the correct memory write ordering. Currently the driver does not update DMA link entries while the DMA is running, so no visible failure occurs. However, fixing the ordering now prepares the driver for supporting link entry updates during DMA operation. Tested-by: Koichiro Den <den@valinux.co.jp> Tested-By: Devendra Verma <devendra.verma@amd.com> Signed-off-by: Frank Li <Frank.Li@nxp.com> Link: https://patch.msgid.link/20260713-edma_ll-v7-1-6fb7498c901e@nxp.com Signed-off-by: Vinod Koul <vkoul@kernel.org>
This commit is contained in:
parent
bf1af4dfdc
commit
99c46385ed
|
|
@ -284,17 +284,18 @@ static void dw_edma_v0_write_ll_data(struct dw_edma_chunk *chunk, int i,
|
|||
if (chunk->chan->dw->chip->flags & DW_EDMA_CHIP_LOCAL) {
|
||||
struct dw_edma_v0_lli *lli = chunk->ll_region.vaddr.mem + ofs;
|
||||
|
||||
lli->control = control;
|
||||
lli->transfer_size = size;
|
||||
lli->sar.reg = sar;
|
||||
lli->dar.reg = dar;
|
||||
dma_wmb();
|
||||
lli->control = control;
|
||||
} else {
|
||||
struct dw_edma_v0_lli __iomem *lli = chunk->ll_region.vaddr.io + ofs;
|
||||
|
||||
writel(control, &lli->control);
|
||||
writel(size, &lli->transfer_size);
|
||||
writeq(sar, &lli->sar.reg);
|
||||
writeq(dar, &lli->dar.reg);
|
||||
writel(control, &lli->control);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -306,13 +307,14 @@ static void dw_edma_v0_write_ll_link(struct dw_edma_chunk *chunk,
|
|||
if (chunk->chan->dw->chip->flags & DW_EDMA_CHIP_LOCAL) {
|
||||
struct dw_edma_v0_llp *llp = chunk->ll_region.vaddr.mem + ofs;
|
||||
|
||||
llp->control = control;
|
||||
llp->llp.reg = pointer;
|
||||
dma_wmb();
|
||||
llp->control = control;
|
||||
} else {
|
||||
struct dw_edma_v0_llp __iomem *llp = chunk->ll_region.vaddr.io + ofs;
|
||||
|
||||
writel(control, &llp->control);
|
||||
writeq(pointer, &llp->llp.reg);
|
||||
writel(control, &llp->control);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -160,17 +160,18 @@ static void dw_hdma_v0_write_ll_data(struct dw_edma_chunk *chunk, int i,
|
|||
if (chunk->chan->dw->chip->flags & DW_EDMA_CHIP_LOCAL) {
|
||||
struct dw_hdma_v0_lli *lli = chunk->ll_region.vaddr.mem + ofs;
|
||||
|
||||
lli->control = control;
|
||||
lli->transfer_size = size;
|
||||
lli->sar.reg = sar;
|
||||
lli->dar.reg = dar;
|
||||
dma_wmb();
|
||||
lli->control = control;
|
||||
} else {
|
||||
struct dw_hdma_v0_lli __iomem *lli = chunk->ll_region.vaddr.io + ofs;
|
||||
|
||||
writel(control, &lli->control);
|
||||
writel(size, &lli->transfer_size);
|
||||
writeq(sar, &lli->sar.reg);
|
||||
writeq(dar, &lli->dar.reg);
|
||||
writel(control, &lli->control);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -182,13 +183,14 @@ static void dw_hdma_v0_write_ll_link(struct dw_edma_chunk *chunk,
|
|||
if (chunk->chan->dw->chip->flags & DW_EDMA_CHIP_LOCAL) {
|
||||
struct dw_hdma_v0_llp *llp = chunk->ll_region.vaddr.mem + ofs;
|
||||
|
||||
llp->control = control;
|
||||
llp->llp.reg = pointer;
|
||||
dma_wmb();
|
||||
llp->control = control;
|
||||
} else {
|
||||
struct dw_hdma_v0_llp __iomem *llp = chunk->ll_region.vaddr.io + ofs;
|
||||
|
||||
writel(control, &llp->control);
|
||||
writeq(pointer, &llp->llp.reg);
|
||||
writel(control, &llp->control);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user