From 6e78108bda78adbb2d4ef55ec60a388aba975797 Mon Sep 17 00:00:00 2001
From: Shengjiu Wang <shengjiu.wang@freescale.com>
Date: Fri, 3 Jul 2015 16:30:30 +0800
Subject: ASoC: core: Don't probe the component which is dummy

Dummy dai can be used by multiple sound card. But it only belong to one
card's dapm list. If another card use it, there will be dapm_assert_locked
warning.

[   20.015782] WARNING: CPU: 1 PID: 661 at sound/soc/soc-dapm.c:124 dapm_assert_locked.isra.36+0x4c/0x58()
[   20.025249] Modules linked in:
[   20.028349] CPU: 1 PID: 661 Comm: aplay Not tainted 4.1.0-rc6-next-20150605-00004-gaee05d8-dirty #92
[   20.037528] Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree)
[   20.044110] Backtrace:
[   20.046614] [<80012e00>] (dump_backtrace) from [<80012fa0>] (show_stack+0x18/0x1c)
[   20.054229]  r6:809e8060 r5:00000000 r4:00000000 r3:00000000
[   20.060002] [<80012f88>] (show_stack) from [<807a0f74>] (dump_stack+0x80/0x9c)
[   20.067293] [<807a0ef4>] (dump_stack) from [<8002b144>] (warn_slowpath_common+0x7c/0xb4)
[   20.075427]  r5:0000007c r4:00000000
[   20.079065] [<8002b0c8>] (warn_slowpath_common) from [<8002b1a0>] (warn_slowpath_null+0x24/0x2c)
[   20.087898]  r8:00000001 r7:88007c28 r6:ed94a680 r5:809e83e4 r4:ed83d6c0
[   20.094747] [<8002b17c>] (warn_slowpath_null) from [<8058403c>] (dapm_assert_locked.isra.36+0x4c/0x58)
[   20.104101] [<80583ff0>] (dapm_assert_locked.isra.36) from [<805842ec>] (dapm_mark_dirty+0x64/0xa4)
[   20.113165] [<80584288>] (dapm_mark_dirty) from [<805853a8>] (soc_dapm_dai_stream_event.isra.42+0x30/0xc8)
[   20.122863]  r8:ed9b5dbc r7:00000000 r6:00000001 r5:00000001 r4:ed83d6c0
[   20.129706] [<80585378>] (soc_dapm_dai_stream_event.isra.42) from [<80587e28>] (snd_soc_dapm_stream_event+0x78/0xa0)
[   20.140264]  r5:ee2ee62c r4:00000001
[   20.143918] [<80587db0>] (snd_soc_dapm_stream_event) from [<8058957c>] (soc_pcm_prepare+0x138/0x21c)
[   20.153058]  r8:ed8d9480 r7:00000000 r6:ed9b0e00 r5:00000001 r4:ee2ee62c r3:00000000
...

This patch is to not probe the dummy component in soc_probe_component. Then
there is no widget created for dummy DAI, and also don't need to check the
dummy dai in dapm_connect_dai_link_widgets().

Signed-off-by: Shengjiu Wang <shengjiu.wang@freescale.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 sound/soc/soc-core.c | 2 +-
 sound/soc/soc-dapm.c | 5 -----
 2 files changed, 1 insertion(+), 6 deletions(-)

diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 3a4a5c0e3f97..6ce621749f8d 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -1102,7 +1102,7 @@ static int soc_probe_component(struct snd_soc_card *card,
 	struct snd_soc_dai *dai;
 	int ret;
 
-	if (component->probed)
+	if (!strcmp(component->name, "snd-soc-dummy") || component->probed)
 		return 0;
 
 	component->card = card;
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index aa327c92480c..37ab6b9b6902 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -3820,11 +3820,6 @@ static void dapm_connect_dai_link_widgets(struct snd_soc_card *card,
 	for (i = 0; i < rtd->num_codecs; i++) {
 		struct snd_soc_dai *codec_dai = rtd->codec_dais[i];
 
-		/* there is no point in connecting BE DAI links with dummies */
-		if (snd_soc_dai_is_dummy(codec_dai) ||
-			snd_soc_dai_is_dummy(cpu_dai))
-			continue;
-
 		/* connect BE DAI playback if widgets are valid */
 		if (codec_dai->playback_widget && cpu_dai->playback_widget) {
 			source = cpu_dai->playback_widget;
-- 
cgit v1.2.3-58-ga151


From 1b7c12316982f74a5b8e7704c24cf5524d0723a3 Mon Sep 17 00:00:00 2001
From: Lars-Peter Clausen <lars@metafoo.de>
Date: Wed, 8 Jul 2015 20:47:43 +0200
Subject: ASoC: Prevent components from being bound to multiple cards

A component can only be bound to a single card at a time. Binding it to
card while it is already bound to another will result in undefined
behavior.

As the undefined behavior might only manifest itself later on it is not
necessarily always straight forward to find the cause. To prevent this add
a check that refuses to bind a component to multiple cards as well as
prints a error describing the problem.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 sound/soc/soc-core.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 6ce621749f8d..96bb71aea529 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -1102,9 +1102,19 @@ static int soc_probe_component(struct snd_soc_card *card,
 	struct snd_soc_dai *dai;
 	int ret;
 
-	if (!strcmp(component->name, "snd-soc-dummy") || component->probed)
+	if (!strcmp(component->name, "snd-soc-dummy"))
 		return 0;
 
+	if (component->probed) {
+		if (component->card != card) {
+			dev_err(component->dev,
+				"Trying to bind component to card \"%s\" but is already bound to card \"%s\"\n",
+				card->name, component->card->name);
+			return -ENODEV;
+		}
+		return 0;
+	}
+
 	component->card = card;
 	dapm->card = card;
 	soc_set_name_prefix(card, component);
-- 
cgit v1.2.3-58-ga151


From abd31b32dde4683df6fd0439caa314aafd751698 Mon Sep 17 00:00:00 2001
From: Lars-Peter Clausen <lars@metafoo.de>
Date: Wed, 8 Jul 2015 20:47:44 +0200
Subject: ASoC: Use card field to indicate whether a component is bound

Use the card field of a component to indicate whether it is bound or not.
This makes a certain sense given that the field contains the card the
component is bound to and a component can only be bound to one card at a
time. And it also requires to unset the card field when the component is
unbound from the card.

This makes the probded flag redundant and it can be removed.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 include/sound/soc.h  |  1 -
 sound/soc/soc-core.c | 16 ++++++++--------
 2 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/include/sound/soc.h b/include/sound/soc.h
index 93df8bf9d54a..59635a12c3be 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -758,7 +758,6 @@ struct snd_soc_component {
 
 	unsigned int ignore_pmdown_time:1; /* pmdown_time is ignored at stop */
 	unsigned int registered_as_component:1;
-	unsigned int probed:1;
 
 	struct list_head list;
 
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 96bb71aea529..42575b03411e 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -978,7 +978,7 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num)
 
 static void soc_remove_component(struct snd_soc_component *component)
 {
-	if (!component->probed)
+	if (!component->card)
 		return;
 
 	/* This is a HACK and will be removed soon */
@@ -991,7 +991,7 @@ static void soc_remove_component(struct snd_soc_component *component)
 	snd_soc_dapm_free(snd_soc_component_get_dapm(component));
 
 	soc_cleanup_component_debugfs(component);
-	component->probed = 0;
+	component->card = NULL;
 	module_put(component->dev->driver->owner);
 }
 
@@ -1105,7 +1105,7 @@ static int soc_probe_component(struct snd_soc_card *card,
 	if (!strcmp(component->name, "snd-soc-dummy"))
 		return 0;
 
-	if (component->probed) {
+	if (component->card) {
 		if (component->card != card) {
 			dev_err(component->dev,
 				"Trying to bind component to card \"%s\" but is already bound to card \"%s\"\n",
@@ -1115,13 +1115,13 @@ static int soc_probe_component(struct snd_soc_card *card,
 		return 0;
 	}
 
+	if (!try_module_get(component->dev->driver->owner))
+		return -ENODEV;
+
 	component->card = card;
 	dapm->card = card;
 	soc_set_name_prefix(card, component);
 
-	if (!try_module_get(component->dev->driver->owner))
-		return -ENODEV;
-
 	soc_init_component_debugfs(component);
 
 	if (component->dapm_widgets) {
@@ -1165,7 +1165,6 @@ static int soc_probe_component(struct snd_soc_card *card,
 		snd_soc_dapm_add_routes(dapm, component->dapm_routes,
 					component->num_dapm_routes);
 
-	component->probed = 1;
 	list_add(&dapm->list, &card->dapm_list);
 
 	/* This is a HACK and will be removed soon */
@@ -1176,6 +1175,7 @@ static int soc_probe_component(struct snd_soc_card *card,
 
 err_probe:
 	soc_cleanup_component_debugfs(component);
+	component->card = NULL;
 	module_put(component->dev->driver->owner);
 
 	return ret;
@@ -1459,7 +1459,7 @@ static void soc_remove_aux_dev(struct snd_soc_card *card, int num)
 		rtd->dev_registered = 0;
 	}
 
-	if (component && component->probed)
+	if (component)
 		soc_remove_component(component);
 }
 
-- 
cgit v1.2.3-58-ga151