ASoC: pcm: Protect FE dai list during dai open/close

When dai open/close, the FE dai list must be protected.
If this list is accessed at the same time, list can
be broken. Then the kernel panic may be generated.
So, the mutex lock is changed to the dai open/close funtions.

Change-Id: Ic75a8d5b9d13eaa38d9edca46b0154cecad29a8e
Signed-off-by: sangwoo <sangwoo2.park@lge.com>
Signed-off-by: Devin Kim <dojip.kim@lge.com>
Signed-off-by: Krishnankutty Kolathappilly <kkolat@codeaurora.org>
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index 294e31e..7c6f0ea 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -1249,7 +1249,6 @@
 	struct snd_pcm_runtime *runtime = fe_substream->runtime;
 	int stream = fe_substream->stream, ret = 0;
 
-	mutex_lock(&fe->card->dpcm_mutex);
 	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
 
 	ret = dpcm_be_dai_startup(fe, fe_substream->stream);
@@ -1273,14 +1272,12 @@
 	snd_pcm_limit_hw_rates(runtime);
 
 	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
-	mutex_unlock(&fe->card->dpcm_mutex);
 	return 0;
 
 unwind:
 	soc_dpcm_be_dai_startup_unwind(fe, fe_substream->stream);
 be_err:
 	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
-	mutex_unlock(&fe->card->dpcm_mutex);
 	return ret;
 }
 
@@ -1328,7 +1325,6 @@
 	struct snd_soc_pcm_runtime *fe = substream->private_data;
 	int stream = substream->stream;
 
-	mutex_lock(&fe->card->dpcm_mutex);
 	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
 	
 	dev_dbg(fe->dev, "dpcm: close FE %s\n", fe->dai_link->name);
@@ -1351,7 +1347,6 @@
 	fe->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE;
 	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
 
-	mutex_unlock(&fe->card->dpcm_mutex);
 	return 0;
 }
 
@@ -2435,12 +2430,14 @@
 	int ret;
 	int stream = fe_substream->stream;
 
+	mutex_lock(&fe->card->dpcm_mutex);
 	fe->dpcm[stream].runtime = fe_substream->runtime;
 
 	if (dpcm_path_get(fe, stream, &list) <= 0) {
 		dev_warn(fe->dev, "asoc: %s no valid %s route from source to sink\n",
 			fe->dai_link->name, stream ? "capture" : "playback");
-			return -EINVAL;
+		mutex_unlock(&fe->card->dpcm_mutex);
+		return -EINVAL;
 	}
 
 	/* calculate valid and active FE <-> BE dpcm_paramss */
@@ -2458,6 +2455,7 @@
 
 	dpcm_clear_pending_state(fe, stream);
 	dpcm_path_put(&list);
+	mutex_unlock(&fe->card->dpcm_mutex);
 	return ret;
 }
 
@@ -2468,6 +2466,7 @@
 	struct snd_soc_dpcm_params *dpcm_params;
 	int stream = fe_substream->stream, ret;
 
+	mutex_lock(&fe->card->dpcm_mutex);
 	ret = soc_dpcm_fe_dai_shutdown(fe_substream);
 
 	/* mark FE's links ready to prune */
@@ -2477,7 +2476,7 @@
 	dpcm_be_disconnect(fe, stream);
 
 	fe->dpcm[stream].runtime = NULL;
-
+	mutex_unlock(&fe->card->dpcm_mutex);
 	return ret;
 }