Peter Ujfalusi wrote:
On 01/08/11 07:36, ext Stephen Warren wrote:
diff --git a/sound/soc/tegra/tegra_pcm.c b/sound/soc/tegra/tegra_pcm.c
...
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
...
case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
spin_lock_irqsave(&prtd->lock, flags);
prtd->running = 1;
spin_unlock_irqrestore(&prtd->lock, flags);
tegra_pcm_queue_dma(prtd);
tegra_pcm_queue_dma(prtd);
break;
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
spin_lock_irqsave(&prtd->lock, flags);
prtd->running = 0;
spin_unlock_irqrestore(&prtd->lock, flags);
tegra_dma_dequeue_req(prtd->dma_chan, &prtd->dma_req[0]);
tegra_dma_dequeue_req(prtd->dma_chan, &prtd->dma_req[1]);
Does tegra_dma_dequeue_req stops the ongoing DMA transaction as well? If I read the code right, you have two DMA requests placed at every given time (one is currently running, the other is waiting). What happens if the dma_req[0] was running, and you dequeue it? Will the DMA engine moves to process the dma_req[1], which will be stopped a moment later?
Yes, that's my understanding.
The DMA driver internally implements tegra_dma_cancel(), which may be a better thing to use in the long run (simply disables the DMA engine, and drops everything from the queue without running any completion callbacks). However, that's not publicly exposed in the header right now; I was going to investigate why first before trying to use it.