dmaengine: shdma: fix a race condition in __ld_cleanup()
This patch fixes a race condition about a list of shdma-base driver. If we don't apply this patch, a dma slave driver (especially a usb peripheral driver) may not be able to start the transfer. If a dma slave driver has a callback, __ld_cleanup() will call the callback before this driver removes the list. After the callback, since the return value of __ld_cleanup() is not zero, shdma_chan_ld_cleanup() calls __ld_cleanup() again. And, __ld_clean() will removes the list. At this time, if a dma slave driver calls dmaengine_submit() before this driver removes the list, this driver will set schan->pm_state to SHDMA_PM_PENDING in shdma_tx_submit(). And then, even if a dma slave driver calls dma_async_issue_pending(), this driver don't start the transfer because the schan->pm_state is SHDMA_PM_PENDING in shdma_issue_pending(). So, this patch adds a new condition in __ld_clean() to check if the schan->pm_state is SHDMA_PM_PENDING or not. Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> Signed-off-by: Vinod Koul <vinod.koul@intel.com>
This commit is contained in:
parent
ce9406380d
commit
26fd830a99
@ -391,6 +391,8 @@ static dma_async_tx_callback __ld_cleanup(struct shdma_chan *schan, bool all)
|
||||
dev_dbg(schan->dev, "Bring down channel %d\n", schan->id);
|
||||
pm_runtime_put(schan->dev);
|
||||
schan->pm_state = SHDMA_PM_ESTABLISHED;
|
||||
} else if (schan->pm_state == SHDMA_PM_PENDING) {
|
||||
shdma_chan_xfer_ld_queue(schan);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user