diff --git a/sound/soc/tegra-alt/tegra210_adsp_alt.c b/sound/soc/tegra-alt/tegra210_adsp_alt.c index b8995e53..923aae67 100644 --- a/sound/soc/tegra-alt/tegra210_adsp_alt.c +++ b/sound/soc/tegra-alt/tegra210_adsp_alt.c @@ -1821,6 +1821,8 @@ static int tegra210_adsp_pcm_close(struct snd_pcm_substream *substream) prtd->fe_apm->msg_handler = tegra210_adsp_app_default_msg_handler; + prtd->fe_apm->private_data = NULL; + spin_unlock_irqrestore(&prtd->fe_apm->lock, flags); prtd->fe_apm->fe = 1; @@ -2689,10 +2691,10 @@ static int tegra210_adsp_fe_widget_event(struct snd_soc_dapm_widget *w, } } else if (event == SND_SOC_DAPM_POST_PMD) { + unsigned long flags; + dev_info(adsp->dev, "disconnect event on APM %d, ADSP-FE %d\n", (i + 1) - APM_IN_START, w->reg); - prtd = apm->private_data; - runtime = prtd->substream->runtime; ret = tegra210_adsp_send_state_msg(apm, nvfx_state_inactive, TEGRA210_ADSP_MSG_FLAG_SEND | TEGRA210_ADSP_MSG_FLAG_NEED_ACK); @@ -2701,6 +2703,16 @@ static int tegra210_adsp_fe_widget_event(struct snd_soc_dapm_widget *w, goto err_put; } + spin_lock_irqsave(&apm->lock, flags); + prtd = apm->private_data; + + if (!prtd) { + dev_dbg(adsp->dev, "PCM close caused this widget event\n"); + spin_unlock_irqrestore(&apm->lock, flags); + goto err_put; + } + + runtime = prtd->substream->runtime; runtime->status->state = SNDRV_PCM_STATE_DISCONNECTED; if (!(prtd->substream->f_flags & O_NONBLOCK)) { if (IS_MMAP_ACCESS(runtime->access)) @@ -2708,6 +2720,9 @@ static int tegra210_adsp_fe_widget_event(struct snd_soc_dapm_widget *w, else wake_up(&runtime->tsleep); } + + spin_unlock_irqrestore(&apm->lock, flags); + } else { pr_err("%s: error. unknown event: %d\n", __func__, event); ret = -1;