* [PATCH] dmaengine: pl330: _stop: clear interrupt status
@ 2019-04-03 11:06 Sugar Zhang
2019-04-26 11:21 ` Vinod Koul
0 siblings, 1 reply; 2+ messages in thread
From: Sugar Zhang @ 2019-04-03 11:06 UTC (permalink / raw)
To: heiko, broonie
Cc: linux-rockchip, Sugar Zhang, Vinod Koul, Dan Williams, dmaengine,
linux-kernel
This patch kill instructs the DMAC to immediately terminate
execution of a thread. and then clear the interrupt status,
at last, stop generating interrupts for DMA_SEV. to guarantee
the next dma start is clean. otherwise, one interrupt maybe leave
to next start and make some mistake.
we can reporduce the problem as follows:
DMASEV: modify the event-interrupt resource, and if the INTEN sets
function as interrupt, the DMAC will set irq<event_num> HIGH to
generate interrupt. write INTCLR to clear interrupt.
DMA EXECUTING INSTRUCTS DMA TERMINATE
| |
| |
... _stop
| |
| spin_lock_irqsave
DMASEV |
| |
| mask INTEN
| |
| DMAKILL
| |
| spin_unlock_irqrestore
in above case, a interrupt was left, and if we unmask INTEN, the DMAC
will set irq<event_num> HIGH to generate interrupt.
to fix this, do as follows:
DMA EXECUTING INSTRUCTS DMA TERMINATE
| |
| |
... _stop
| |
| spin_lock_irqsave
DMASEV |
| |
| DMAKILL
| |
| clear INTCLR
| mask INTEN
| |
| spin_unlock_irqrestore
Signed-off-by: Sugar Zhang <sugar.zhang@rock-chips.com>
---
drivers/dma/pl330.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index eec79fd..56695ff 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -966,6 +966,7 @@ static void _stop(struct pl330_thread *thrd)
{
void __iomem *regs = thrd->dmac->base;
u8 insn[6] = {0, 0, 0, 0, 0, 0};
+ u32 inten = readl(regs + INTEN);
if (_state(thrd) == PL330_STATE_FAULT_COMPLETING)
UNTIL(thrd, PL330_STATE_FAULTING | PL330_STATE_KILLING);
@@ -978,10 +979,13 @@ static void _stop(struct pl330_thread *thrd)
_emit_KILL(0, insn);
- /* Stop generating interrupts for SEV */
- writel(readl(regs + INTEN) & ~(1 << thrd->ev), regs + INTEN);
-
_execute_DBGINSN(thrd, insn, is_manager(thrd));
+
+ /* clear the event */
+ if (inten & (1 << thrd->ev))
+ writel(1 << thrd->ev, regs + INTCLR);
+ /* Stop generating interrupts for SEV */
+ writel(inten & ~(1 << thrd->ev), regs + INTEN);
}
/* Start doing req 'idx' of thread 'thrd' */
--
2.7.4
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH] dmaengine: pl330: _stop: clear interrupt status
2019-04-03 11:06 [PATCH] dmaengine: pl330: _stop: clear interrupt status Sugar Zhang
@ 2019-04-26 11:21 ` Vinod Koul
0 siblings, 0 replies; 2+ messages in thread
From: Vinod Koul @ 2019-04-26 11:21 UTC (permalink / raw)
To: Sugar Zhang
Cc: heiko, broonie, linux-rockchip, Dan Williams, dmaengine, linux-kernel
On 03-04-19, 19:06, Sugar Zhang wrote:
> This patch kill instructs the DMAC to immediately terminate
> execution of a thread. and then clear the interrupt status,
> at last, stop generating interrupts for DMA_SEV. to guarantee
> the next dma start is clean. otherwise, one interrupt maybe leave
> to next start and make some mistake.
Applied, thanks
--
~Vinod
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2019-04-26 11:21 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-04-03 11:06 [PATCH] dmaengine: pl330: _stop: clear interrupt status Sugar Zhang
2019-04-26 11:21 ` Vinod Koul
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).