diff options
author | Fancy Fang <chen.fang@freescale.com> | 2015-06-04 16:19:06 +0800 |
---|---|---|
committer | Nitin Garg <nitin.garg@freescale.com> | 2015-09-17 09:23:32 -0500 |
commit | 7778f11634fdb149cbc4e5c6f55215044ba2b93e (patch) | |
tree | 4773ecca985a9fbd9b56137d6a67946cc7af3836 /drivers/dma | |
parent | a1b2f9936808ccc32127f6e195ab365609c08396 (diff) |
MLK-10607 dma: pxp-v3: fix race condition issue in pxp irq handler
Add pxp_chan spin lock calling in the pxp irq handler to
avoid the simultaneous accesses of the pxp_chan lists data.
Signed-off-by: Fancy Fang <chen.fang@freescale.com>
Diffstat (limited to 'drivers/dma')
-rw-r--r-- | drivers/dma/pxp/pxp_dma_v3.c | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/drivers/dma/pxp/pxp_dma_v3.c b/drivers/dma/pxp/pxp_dma_v3.c index 975258ecfcbd..68dc9f07f275 100644 --- a/drivers/dma/pxp/pxp_dma_v3.c +++ b/drivers/dma/pxp/pxp_dma_v3.c @@ -1594,7 +1594,7 @@ static irqreturn_t pxp_irq(int irq, void *dev_id) struct pxp_tx_desc *desc; dma_async_tx_callback callback; void *callback_param; - unsigned long flags; + unsigned long flags, flags0; u32 hist_status; int pxp_irq_status = 0; @@ -1657,12 +1657,14 @@ static irqreturn_t pxp_irq(int irq, void *dev_id) } pxp_chan = list_entry(head.next, struct pxp_channel, list); + spin_lock_irqsave(&pxp_chan->lock, flags0); list_del_init(&pxp_chan->list); if (list_empty(&pxp_chan->active_list)) { pr_debug("PXP_IRQ pxp_chan->active_list empty. chan_id %d\n", pxp_chan->dma_chan.chan_id); pxp->pxp_ongoing = 0; + spin_unlock_irqrestore(&pxp_chan->lock, flags0); spin_unlock_irqrestore(&pxp->lock, flags); return IRQ_NONE; } @@ -1685,6 +1687,7 @@ static irqreturn_t pxp_irq(int irq, void *dev_id) list_splice_init(&desc->tx_list, &pxp_chan->free_list); list_move(&desc->list, &pxp_chan->free_list); + spin_unlock_irqrestore(&pxp_chan->lock, flags0); mutex_unlock(&hard_lock); pxp->pxp_ongoing = 0; |