static int mxs_pcm_close(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; struct mxs_runtime_data *prtd = runtime->private_data; int desc_num = mxs_pcm_hardware.periods_max; int desc; int timeo = 20; static LIST_HEAD(list); mxs_dma_disable(prtd->dma_ch); /* Wait until the DMA chain is finished. */ while (mxs_dma_read_semaphore(prtd->dma_ch)) { if (!timeo--) break; pr_debug("The sema is not zero now\n"); msleep(10); } if (timeo <= 0) pr_warn("Is the DMA channel dead?\n"); /* Free DMA irq */ free_irq(prtd->params->irq, substream); mxs_dma_get_cooked(prtd->dma_ch, &list); /* Free DMA channel*/ for (desc = 0; desc < desc_num; desc++) mxs_dma_free_desc(prtd->dma_desc_array[desc]); mxs_dma_release(prtd->dma_ch, mxs_pcm_dev); /* Free private runtime data */ kfree(prtd); return 0; }
static int mxs_pcm_close(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; struct mxs_runtime_data *prtd = runtime->private_data; int desc_num = mxs_pcm_hardware.periods_max; int desc; static LIST_HEAD(list); mxs_dma_disable(prtd->dma_ch); /* Free DMA irq */ free_irq(prtd->params->irq, substream); mxs_dma_get_cooked(prtd->dma_ch, &list); /* Free DMA channel*/ for (desc = 0; desc < desc_num; desc++) mxs_dma_free_desc(prtd->dma_desc_array[desc]); mxs_dma_release(prtd->dma_ch, mxs_pcm_dev); /* Free private runtime data */ kfree(prtd); return 0; }