Merge "ALSA: pcm: use lock to protect substream runtime resource"
diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index b6fdf29..348d958 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -466,6 +466,7 @@
 	const struct snd_pcm_ops *ops;
 	/* -- runtime information -- */
 	struct snd_pcm_runtime *runtime;
+	spinlock_t runtime_lock;
         /* -- timer section -- */
 	struct snd_timer *timer;		/* timer */
 	unsigned timer_running: 1;	/* time is running */
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index a2c2f06..4fc68b1 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -742,6 +742,7 @@
 		}
 		substream->group = &substream->self_group;
 		spin_lock_init(&substream->self_group.lock);
+		spin_lock_init(&substream->runtime_lock);
 		mutex_init(&substream->self_group.mutex);
 		INIT_LIST_HEAD(&substream->self_group.substreams);
 		list_add_tail(&substream->link_list, &substream->self_group.substreams);
@@ -1020,9 +1021,11 @@
 void snd_pcm_detach_substream(struct snd_pcm_substream *substream)
 {
 	struct snd_pcm_runtime *runtime;
+	unsigned long flags = 0;
 
 	if (PCM_RUNTIME_CHECK(substream))
 		return;
+	spin_lock_irqsave(&substream->runtime_lock, flags);
 	runtime = substream->runtime;
 	if (runtime->private_free != NULL)
 		runtime->private_free(runtime);
@@ -1036,6 +1039,7 @@
 	put_pid(substream->pid);
 	substream->pid = NULL;
 	substream->pstr->substream_opened--;
+	spin_unlock_irqrestore(&substream->runtime_lock, flags);
 }
 
 static ssize_t show_pcm_class(struct device *dev,
diff --git a/sound/core/pcm_timer.c b/sound/core/pcm_timer.c
index 20ecd8f..5258ecc 100644
--- a/sound/core/pcm_timer.c
+++ b/sound/core/pcm_timer.c
@@ -65,9 +65,16 @@
 static unsigned long snd_pcm_timer_resolution(struct snd_timer * timer)
 {
 	struct snd_pcm_substream *substream;
+	unsigned long ret = 0, flags = 0;
 	
 	substream = timer->private_data;
-	return substream->runtime ? substream->runtime->timer_resolution : 0;
+	spin_lock_irqsave(&substream->runtime_lock, flags);
+	if (substream->runtime)
+		ret = substream->runtime->timer_resolution;
+	else
+		ret = 0;
+	spin_unlock_irqrestore(&substream->runtime_lock, flags);
+	return ret;
 }
 
 static int snd_pcm_timer_start(struct snd_timer * timer)