DMAEngine: sirf: lock the shared registers access in sirfsoc_dma_terminate_all
authorBarry Song <Baohua.Song@csr.com>
Fri, 14 Dec 2012 11:06:58 +0000 (11:06 +0000)
committerVinod Koul <vinod.koul@intel.com>
Mon, 28 Jan 2013 09:44:46 +0000 (01:44 -0800)
Just like Russell pointed out in "DMAEngine: sirf: add DMA
pause/resume support" at
http://www.spinics.net/lists/arm-kernel/msg212496.html
here I find sirfsoc_dma_terminate_all() has same problem,
so move the locking to the front of registers access.

Signed-off-by: Barry Song <Baohua.Song@csr.com>
Cc: Russell King <linux@arm.linux.org.uk>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
drivers/dma/sirf-dma.c

index 7d78cf7..fb5790d 100644 (file)
@@ -291,6 +291,8 @@ static int sirfsoc_dma_terminate_all(struct sirfsoc_dma_chan *schan)
        int cid = schan->chan.chan_id;
        unsigned long flags;
 
+       spin_lock_irqsave(&schan->lock, flags);
+
        if (!sdma->is_marco) {
                writel_relaxed(readl_relaxed(sdma->base + SIRFSOC_DMA_INT_EN) &
                        ~(1 << cid), sdma->base + SIRFSOC_DMA_INT_EN);
@@ -305,9 +307,9 @@ static int sirfsoc_dma_terminate_all(struct sirfsoc_dma_chan *schan)
 
        writel_relaxed(1 << cid, sdma->base + SIRFSOC_DMA_CH_VALID);
 
-       spin_lock_irqsave(&schan->lock, flags);
        list_splice_tail_init(&schan->active, &schan->free);
        list_splice_tail_init(&schan->queued, &schan->free);
+
        spin_unlock_irqrestore(&schan->lock, flags);
 
        return 0;