From 4eb691cb07be68eceefe7bb728f7a9b851bb5846 Mon Sep 17 00:00:00 2001 From: Simon Xue Date: Thu, 17 Dec 2020 11:15:48 +0800 Subject: [PATCH] PCI: rockchip: dw: fix UDMA logic Clear UDMA interrupt first before starting a new transfer. Otherwise, the new interrupt corresponding to new transfer may be cleared when clear the last interrupt which finally cause transfer timeout. Change-Id: I4d232e41cdfaa68178cdd99942aefa717032c1b9 Signed-off-by: Simon Xue --- drivers/pci/controller/dwc/pcie-dw-rockchip.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/pci/controller/dwc/pcie-dw-rockchip.c b/drivers/pci/controller/dwc/pcie-dw-rockchip.c index 92e5788ca568..e908a156134c 100644 --- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c +++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c @@ -984,18 +984,21 @@ rk_pcie_handle_dma_interrupt(struct rk_pcie *rk_pcie) static irqreturn_t rk_pcie_sys_irq_handler(int irq, void *arg) { struct rk_pcie *rk_pcie = arg; - u32 chn = rk_pcie->dma_obj->cur->chn; + u32 chn = 0; union int_status status; union int_clear clears; status.asdword = dw_pcie_readl_dbi(rk_pcie->pci, PCIE_DMA_OFFSET + PCIE_DMA_WR_INT_STATUS); + if (rk_pcie->dma_obj && rk_pcie->dma_obj->cur) + chn = rk_pcie->dma_obj->cur->chn; + if (status.donesta & BIT(0)) { - rk_pcie_handle_dma_interrupt(rk_pcie); clears.doneclr = 0x1 << chn; dw_pcie_writel_dbi(rk_pcie->pci, PCIE_DMA_OFFSET + PCIE_DMA_WR_INT_CLEAR, clears.asdword); + rk_pcie_handle_dma_interrupt(rk_pcie); } if (status.abortsta & BIT(0)) {