diff options
author | Liam Girdwood <liam.r.girdwood@linux.intel.com> | 2014-05-02 11:56:32 -0400 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2014-05-02 12:53:02 -0400 |
commit | 916152c48848290a8aba5cf4dd16c2a8a888e11c (patch) | |
tree | 7e3f84b0500c5ce4204bf65bfe7d5a8da8517ecb /sound | |
parent | 10df350977b15d44dba0b3b44e3da7989711cb8d (diff) |
ASoC: Intel: Fix allow hw_params to be called more than once.
hw_params() can be called multiple times. Make sure we release the DSP
stream that was allocated on previous hw_params() calls before allocating
a new DSP stream.
Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/intel/sst-haswell-pcm.c | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/sound/soc/intel/sst-haswell-pcm.c b/sound/soc/intel/sst-haswell-pcm.c index ba585a75878d..50fea077898b 100644 --- a/sound/soc/intel/sst-haswell-pcm.c +++ b/sound/soc/intel/sst-haswell-pcm.c | |||
@@ -99,6 +99,7 @@ struct hsw_pcm_data { | |||
99 | struct snd_compr_stream *cstream; | 99 | struct snd_compr_stream *cstream; |
100 | unsigned int wpos; | 100 | unsigned int wpos; |
101 | struct mutex mutex; | 101 | struct mutex mutex; |
102 | bool allocated; | ||
102 | }; | 103 | }; |
103 | 104 | ||
104 | /* private data for the driver */ | 105 | /* private data for the driver */ |
@@ -113,6 +114,8 @@ struct hsw_priv_data { | |||
113 | struct hsw_pcm_data pcm[HSW_PCM_COUNT]; | 114 | struct hsw_pcm_data pcm[HSW_PCM_COUNT]; |
114 | }; | 115 | }; |
115 | 116 | ||
117 | static u32 hsw_notify_pointer(struct sst_hsw_stream *stream, void *data); | ||
118 | |||
116 | static inline u32 hsw_mixer_to_ipc(unsigned int value) | 119 | static inline u32 hsw_mixer_to_ipc(unsigned int value) |
117 | { | 120 | { |
118 | if (value >= ARRAY_SIZE(volume_map)) | 121 | if (value >= ARRAY_SIZE(volume_map)) |
@@ -322,6 +325,29 @@ static int hsw_pcm_hw_params(struct snd_pcm_substream *substream, | |||
322 | u8 channels; | 325 | u8 channels; |
323 | int ret; | 326 | int ret; |
324 | 327 | ||
328 | /* check if we are being called a subsequent time */ | ||
329 | if (pcm_data->allocated) { | ||
330 | ret = sst_hsw_stream_reset(hsw, pcm_data->stream); | ||
331 | if (ret < 0) | ||
332 | dev_dbg(rtd->dev, "error: reset stream failed %d\n", | ||
333 | ret); | ||
334 | |||
335 | ret = sst_hsw_stream_free(hsw, pcm_data->stream); | ||
336 | if (ret < 0) { | ||
337 | dev_dbg(rtd->dev, "error: free stream failed %d\n", | ||
338 | ret); | ||
339 | return ret; | ||
340 | } | ||
341 | pcm_data->allocated = false; | ||
342 | |||
343 | pcm_data->stream = sst_hsw_stream_new(hsw, rtd->cpu_dai->id, | ||
344 | hsw_notify_pointer, pcm_data); | ||
345 | if (pcm_data->stream == NULL) { | ||
346 | dev_err(rtd->dev, "error: failed to create stream\n"); | ||
347 | return -EINVAL; | ||
348 | } | ||
349 | } | ||
350 | |||
325 | /* stream direction */ | 351 | /* stream direction */ |
326 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 352 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
327 | path_id = SST_HSW_STREAM_PATH_SSP0_OUT; | 353 | path_id = SST_HSW_STREAM_PATH_SSP0_OUT; |
@@ -475,6 +501,7 @@ static int hsw_pcm_hw_params(struct snd_pcm_substream *substream, | |||
475 | dev_err(rtd->dev, "error: failed to commit stream %d\n", ret); | 501 | dev_err(rtd->dev, "error: failed to commit stream %d\n", ret); |
476 | return ret; | 502 | return ret; |
477 | } | 503 | } |
504 | pcm_data->allocated = true; | ||
478 | 505 | ||
479 | ret = sst_hsw_stream_pause(hsw, pcm_data->stream, 1); | 506 | ret = sst_hsw_stream_pause(hsw, pcm_data->stream, 1); |
480 | if (ret < 0) | 507 | if (ret < 0) |
@@ -607,6 +634,7 @@ static int hsw_pcm_close(struct snd_pcm_substream *substream) | |||
607 | dev_dbg(rtd->dev, "error: free stream failed %d\n", ret); | 634 | dev_dbg(rtd->dev, "error: free stream failed %d\n", ret); |
608 | goto out; | 635 | goto out; |
609 | } | 636 | } |
637 | pcm_data->allocated = 0; | ||
610 | pcm_data->stream = NULL; | 638 | pcm_data->stream = NULL; |
611 | 639 | ||
612 | out: | 640 | out: |