summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJie Hai <haijie1@huawei.com>2022-08-30 09:22:46 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2022-10-26 14:25:33 +0300
commitd3fd838536dff43adb4dda34fd15ea3a574125f9 (patch)
tree27bb8a02463c0702a8eb2760813663e4f23d677b
parentd5065ca461a4a0abd8682b6934cbe228a7f2d8c1 (diff)
downloadlinux-d3fd838536dff43adb4dda34fd15ea3a574125f9.tar.xz
dmaengine: hisilicon: Fix CQ head update
[ Upstream commit 94477a79cf80e8ab55b68f14bc579a12ddea1e0b ] After completion of data transfer of one or multiple descriptors, the completion status and the current head pointer to submission queue are written into the CQ and interrupt can be generated to inform the software. In interrupt process CQ is read and cq_head is updated. hisi_dma_irq updates cq_head only when the completion status is success. When an abnormal interrupt reports, cq_head will not update which will cause subsequent interrupt processes read the error CQ and never report the correct status. This patch updates cq_head whenever CQ is accessed. Fixes: e9f08b65250d ("dmaengine: hisilicon: Add Kunpeng DMA engine support") Signed-off-by: Jie Hai <haijie1@huawei.com> Acked-by: Zhou Wang <wangzhou1@hisilicon.com> Link: https://lore.kernel.org/r/20220830062251.52993-3-haijie1@huawei.com Signed-off-by: Vinod Koul <vkoul@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
-rw-r--r--drivers/dma/hisi_dma.c8
1 files changed, 3 insertions, 5 deletions
diff --git a/drivers/dma/hisi_dma.c b/drivers/dma/hisi_dma.c
index 7cedf91e86a9..08ec90dd4c46 100644
--- a/drivers/dma/hisi_dma.c
+++ b/drivers/dma/hisi_dma.c
@@ -442,12 +442,10 @@ static irqreturn_t hisi_dma_irq(int irq, void *data)
desc = chan->desc;
cqe = chan->cq + chan->cq_head;
if (desc) {
+ chan->cq_head = (chan->cq_head + 1) % hdma_dev->chan_depth;
+ hisi_dma_chan_write(hdma_dev->base, HISI_DMA_CQ_HEAD_PTR,
+ chan->qp_num, chan->cq_head);
if (FIELD_GET(STATUS_MASK, cqe->w0) == STATUS_SUCC) {
- chan->cq_head = (chan->cq_head + 1) %
- hdma_dev->chan_depth;
- hisi_dma_chan_write(hdma_dev->base,
- HISI_DMA_CQ_HEAD_PTR, chan->qp_num,
- chan->cq_head);
vchan_cookie_complete(&desc->vd);
} else {
dev_err(&hdma_dev->pdev->dev, "task error!\n");