static int msm_afe_close(struct snd_pcm_substream *substream) { int rc = 0; struct snd_dma_buffer *dma_buf; struct snd_pcm_runtime *runtime; struct pcm_afe_info *prtd; struct snd_soc_pcm_runtime *rtd = NULL; struct snd_soc_dai *dai = NULL; int dir = IN; int ret = 0; pr_debug("%s\n", __func__); if (substream == NULL) { pr_err("substream is NULL\n"); return -EINVAL; } rtd = substream->private_data; dai = rtd->cpu_dai; runtime = substream->runtime; prtd = runtime->private_data; mutex_lock(&prtd->lock); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { dir = IN; ret = afe_unregister_get_events(dai->id); if (ret < 0) pr_err("AFE unregister for events failed\n"); } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { dir = OUT; ret = afe_unregister_get_events(dai->id); if (ret < 0) pr_err("AFE unregister for events failed\n"); } hrtimer_cancel(&prtd->hrt); rc = afe_cmd_memory_unmap(afe_req_mmap_handle(prtd->audio_client)); if (rc < 0) pr_err("AFE memory unmap failed\n"); pr_debug("release all buffer\n"); dma_buf = &substream->dma_buffer; if (dma_buf == NULL) { pr_debug("dma_buf is NULL\n"); goto done; } if (dma_buf->area) dma_buf->area = NULL; q6afe_audio_client_buf_free_contiguous(dir, prtd->audio_client); done: pr_debug("%s: dai->id =%x\n", __func__, dai->id); q6afe_audio_client_free(prtd->audio_client); mutex_unlock(&prtd->lock); prtd->prepared--; kfree(prtd); runtime->private_data = NULL; return 0; }
static int msm_afe_close(struct snd_pcm_substream *substream) { int rc = 0; struct snd_dma_buffer *dma_buf; struct snd_pcm_runtime *runtime; struct pcm_afe_info *prtd; struct snd_soc_pcm_runtime *rtd = NULL; struct snd_soc_dai *dai = NULL; int ret = 0; pr_debug("%s\n", __func__); if (substream == NULL) { pr_err("substream is NULL\n"); return -EINVAL; } rtd = substream->private_data; dai = rtd->cpu_dai; runtime = substream->runtime; prtd = runtime->private_data; mutex_lock(&prtd->lock); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { ret = afe_unregister_get_events(dai->id); if (ret < 0) pr_err("AFE unregister for events failed\n"); } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { ret = afe_unregister_get_events(dai->id); if (ret < 0) pr_err("AFE unregister for events failed\n"); } hrtimer_cancel(&prtd->hrt); rc = afe_cmd_memory_unmap(runtime->dma_addr); if (rc < 0) pr_err("AFE memory unmap failed\n"); pr_debug("release all buffer\n"); dma_buf = &substream->dma_buffer; if (dma_buf == NULL) { pr_debug("dma_buf is NULL\n"); goto done; } if (dma_buf->area != NULL) { dma_free_coherent(substream->pcm->card->dev, runtime->hw.buffer_bytes_max, dma_buf->area, dma_buf->addr); dma_buf->area = NULL; } done: pr_debug("%s: dai->id =%x\n", __func__, dai->id); mutex_unlock(&prtd->lock); prtd->prepared--; kfree(prtd); return 0; }
static int pcm_in_release(struct inode *inode, struct file *file) { int rc = 0; struct pcm *pcm = file->private_data; pr_info("[AUD][%s:%s] release session id[%d]\n", __MM_FILE__, __func__, pcm->ac->session); mutex_lock(&pcm->lock); /* remove this session from topology list */ auddev_cfg_tx_copp_topology(pcm->ac->session, DEFAULT_COPP_TOPOLOGY); rc = pcm_in_disable(pcm); hrtimer_cancel(&pcm->hrt); rc = afe_cmd_memory_unmap(pcm->dma_addr); if (rc < 0) pr_err("AFE memory unmap failed\n"); rc = afe_unregister_get_events(RT_PROXY_DAI_001_TX); if (rc < 0) pr_err("AFE unregister for events failed\n"); afe_close(RT_PROXY_DAI_001_TX); pr_debug("release all buffer\n"); q6asm_audio_client_buf_free_contiguous(OUT, pcm->ac); msm_clear_session_id(pcm->ac->session); q6asm_audio_client_free(pcm->ac); mutex_unlock(&pcm->lock); mutex_destroy(&pcm->lock); mutex_destroy(&pcm->read_lock); kfree(pcm); return rc; }