aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin Strasser <kevin.strasser@intel.com>2014-05-19 04:14:23 -0400
committerMark Brown <broonie@linaro.org>2014-05-19 12:30:56 -0400
commit2fa190ce33bdf2f58bb0a65d94e08980d92c76ed (patch)
treeb7abe5d7bf55f22b0cc1f6226c2c21c0e8dcf04e
parentd7b54c3083b2e04243697c5e450a446d501107bc (diff)
ASoC: Intel: Fix pcm stream context restore crash
In some cases the pcm stream is closed while context has been scheduled to be restored, causing a null pointer deref panic. Cancel work to ensure stream does not get freed while work is still active/pending. Also, restoring the pcm context can be safely skipped after the stream has been stopped. Check if pcm stream is still running before restoring stream context to help pending work finish more quickly in stream close path. Signed-off-by: Kevin Strasser <kevin.strasser@intel.com> Signed-off-by: Jarkko Nikula <jarkko.nikula@linux.intel.com> Signed-off-by: Mark Brown <broonie@linaro.org>
-rw-r--r--sound/soc/intel/sst-baytrail-pcm.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/sound/soc/intel/sst-baytrail-pcm.c b/sound/soc/intel/sst-baytrail-pcm.c
index 6242ccce2bb7..3af38576e91e 100644
--- a/sound/soc/intel/sst-baytrail-pcm.c
+++ b/sound/soc/intel/sst-baytrail-pcm.c
@@ -164,7 +164,8 @@ static void sst_byt_pcm_work(struct work_struct *work)
164 struct sst_byt_pcm_data *pcm_data = 164 struct sst_byt_pcm_data *pcm_data =
165 container_of(work, struct sst_byt_pcm_data, work); 165 container_of(work, struct sst_byt_pcm_data, work);
166 166
167 sst_byt_pcm_restore_stream_context(pcm_data->substream); 167 if (snd_pcm_running(pcm_data->substream))
168 sst_byt_pcm_restore_stream_context(pcm_data->substream);
168} 169}
169 170
170static int sst_byt_pcm_trigger(struct snd_pcm_substream *substream, int cmd) 171static int sst_byt_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
@@ -277,6 +278,7 @@ static int sst_byt_pcm_close(struct snd_pcm_substream *substream)
277 278
278 dev_dbg(rtd->dev, "PCM: close\n"); 279 dev_dbg(rtd->dev, "PCM: close\n");
279 280
281 cancel_work_sync(&pcm_data->work);
280 mutex_lock(&pcm_data->mutex); 282 mutex_lock(&pcm_data->mutex);
281 ret = sst_byt_stream_free(byt, pcm_data->stream); 283 ret = sst_byt_stream_free(byt, pcm_data->stream);
282 if (ret < 0) { 284 if (ret < 0) {