@@ -19,7 +19,8 @@ void snd_soc_link_shutdown(struct snd_pcm_substream *substream,
int snd_soc_link_prepare(struct snd_pcm_substream *substream);
int snd_soc_link_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params);
-void snd_soc_link_hw_free(struct snd_pcm_substream *substream);
+void snd_soc_link_hw_free(struct snd_pcm_substream *substream,
+ int rollback);
int snd_soc_link_trigger(struct snd_pcm_substream *substream, int cmd);
int snd_soc_link_compr_startup(struct snd_compr_stream *cstream);
@@ -1161,6 +1161,7 @@ struct snd_soc_pcm_runtime {
/* function mark */
struct snd_pcm_substream *mark_startup;
+ struct snd_pcm_substream *mark_hw_params;
/* bit field */
unsigned int pop_wait:1;
@@ -119,16 +119,26 @@ int snd_soc_link_hw_params(struct snd_pcm_substream *substream,
rtd->dai_link->ops->hw_params)
ret = rtd->dai_link->ops->hw_params(substream, params);
+ /* mark substream if succeeded */
+ if (ret == 0)
+ soc_link_mark_push(rtd, substream, hw_params);
+
return soc_link_ret(rtd, ret);
}
-void snd_soc_link_hw_free(struct snd_pcm_substream *substream)
+void snd_soc_link_hw_free(struct snd_pcm_substream *substream, int rollback)
{
struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ if (rollback && !soc_link_mark_match(rtd, substream, hw_params))
+ return;
+
if (rtd->dai_link->ops &&
rtd->dai_link->ops->hw_free)
rtd->dai_link->ops->hw_free(substream);
+
+ /* remove marked substream */
+ soc_link_mark_pop(rtd, substream, hw_params);
}
int snd_soc_link_trigger(struct snd_pcm_substream *substream, int cmd)
@@ -885,7 +885,7 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
}
/* free any machine hw params */
- snd_soc_link_hw_free(substream);
+ snd_soc_link_hw_free(substream, 0);
/* free any component resources */
snd_soc_pcm_component_hw_free(substream, NULL);
@@ -1027,7 +1027,7 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
codec_dai->rate = 0;
}
- snd_soc_link_hw_free(substream);
+ snd_soc_link_hw_free(substream, 1);
mutex_unlock(&rtd->card->pcm_mutex);
return ret;