All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3 v2][resend] ASoC: Component level pcm_new/pcm_free v2
@ 2017-08-08  6:17 Kuninori Morimoto
  2017-08-08  6:17 ` [PATCH 1/3 v2][resend] ASoC: soc-core: add snd_soc_rtdcom_xxx() Kuninori Morimoto
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Kuninori Morimoto @ 2017-08-08  6:17 UTC (permalink / raw)
  To: Mark Brown; +Cc: Linux-ALSA, Simon


Hi Mark

I posted this patch-set 2weeks ago, and no response, no objection from community.
Thus, I re-post these again.

These are Component level pcm_new/free v2.
v1 pcm_new/free had breaked some platform, because it
called "card" connected component callback.
It should call "rtd" connected one's.

Special thanks to Arnaud who tested this v2 patch on his
environment.

These patch-set adds rtd connected component list (= rtdcom)
and replace current platform level pcm_new/free into component level
pcm_new/free
I don't know this naming (= rtdcom) sense is nice or not ;P
I can replace it to more nicer naming if someone have nice sense.

Kuninori Morimoto (3):
  ASoC: soc-core: add snd_soc_rtdcom_xxx()
  ASoC: use snd_soc_rtdcom_add() and convert to consistent operation
  ASoC: add Component level pcm_new/pcm_free v2

 include/sound/soc.h  |  21 ++++++-
 sound/soc/soc-core.c | 153 +++++++++++++++++++++++++++++++++++++++------------
 sound/soc/soc-pcm.c  |  68 +++++++++++++++--------
 3 files changed, 183 insertions(+), 59 deletions(-)

-- 
1.9.1

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 1/3 v2][resend] ASoC: soc-core: add snd_soc_rtdcom_xxx()
  2017-08-08  6:17 [PATCH 0/3 v2][resend] ASoC: Component level pcm_new/pcm_free v2 Kuninori Morimoto
@ 2017-08-08  6:17 ` Kuninori Morimoto
  2017-08-10 15:41   ` Applied "ASoC: soc-core: add snd_soc_rtdcom_xxx()" to the asoc tree Mark Brown
  2017-08-08  6:18 ` [PATCH 2/3 v2][resend] ASoC: use snd_soc_rtdcom_add() and convert to consistent operation Kuninori Morimoto
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 7+ messages in thread
From: Kuninori Morimoto @ 2017-08-08  6:17 UTC (permalink / raw)
  To: Mark Brown; +Cc: Linux-ALSA, Simon


From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>

Current snd_soc_pcm_runtime has platform / codec pointers, and we could
use these specific pointer. But these will be replaced to more generic
"component" soon, and will need more generic method to get each
connected component pointer from rtd.

This patch adds new snd_soc_rtdcom_xxx() to connect/disconnect
component to rtd. It means same as previous "platform" / "codec"
pointer style, but more generic.
We can find necessary component pointer from rtd by using component
driver name on snd_soc_rtdcom_lookup().

Here, the reason why it uses "driver name" is that "component name"
was created by fmt_single_name() and difficult to use it from driver.
Driver of course knows its "driver name", thus, using it is more easy.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Tested-by: Arnaud Pouliquen <arnaud.pouliquen@st.com>
---
 include/sound/soc.h  | 13 +++++++++++++
 sound/soc/soc-core.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 63 insertions(+)

diff --git a/include/sound/soc.h b/include/sound/soc.h
index 62bc0c7..b53b45d 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -880,6 +880,18 @@ struct snd_soc_component {
 #endif
 };
 
+struct snd_soc_rtdcom_list {
+	struct snd_soc_component *component;
+	struct list_head list; /* rtd::component_list */
+};
+struct snd_soc_component*
+snd_soc_rtdcom_lookup(struct snd_soc_pcm_runtime *rtd,
+		       const char *driver_name);
+#define for_each_rtdcom(rtd, rtdcom) \
+	list_for_each_entry(rtdcom, &(rtd)->component_list, list)
+#define for_each_rtdcom_safe(rtd, rtdcom1, rtdcom2) \
+	list_for_each_entry_safe(rtdcom1, rtdcom2, &(rtd)->component_list, list)
+
 /* SoC Audio Codec device */
 struct snd_soc_codec {
 	struct device *dev;
@@ -1238,6 +1250,7 @@ struct snd_soc_pcm_runtime {
 
 	unsigned int num; /* 0-based and monotonic increasing */
 	struct list_head list; /* rtd list of the soc card */
+	struct list_head component_list; /* list of connected components */
 
 	/* bit field */
 	unsigned int dev_registered:1;
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index a407a9a..5d8847f 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -550,6 +550,54 @@ static inline void snd_soc_debugfs_exit(void)
 
 #endif
 
+static int snd_soc_rtdcom_add(struct snd_soc_pcm_runtime *rtd,
+			      struct snd_soc_component *component)
+{
+	struct snd_soc_rtdcom_list *rtdcom;
+	struct snd_soc_rtdcom_list *new_rtdcom;
+
+	for_each_rtdcom(rtd, rtdcom) {
+		/* already connected */
+		if (rtdcom->component == component)
+			return 0;
+	}
+
+	new_rtdcom = kmalloc(sizeof(*new_rtdcom), GFP_KERNEL);
+	if (!new_rtdcom)
+		return -ENOMEM;
+
+	new_rtdcom->component = component;
+	INIT_LIST_HEAD(&new_rtdcom->list);
+
+	list_add_tail(&new_rtdcom->list, &rtd->component_list);
+
+	return 0;
+}
+
+static void snd_soc_rtdcom_del_all(struct snd_soc_pcm_runtime *rtd)
+{
+	struct snd_soc_rtdcom_list *rtdcom1, *rtdcom2;
+
+	for_each_rtdcom_safe(rtd, rtdcom1, rtdcom2)
+		kfree(rtdcom1);
+
+	INIT_LIST_HEAD(&rtd->component_list);
+}
+
+struct snd_soc_component *snd_soc_rtdcom_lookup(struct snd_soc_pcm_runtime *rtd,
+						const char *driver_name)
+{
+	struct snd_soc_rtdcom_list *rtdcom;
+
+	for_each_rtdcom(rtd, rtdcom) {
+		if ((rtdcom->component->driver->name == driver_name) ||
+		    strcmp(rtdcom->component->driver->name, driver_name) == 0)
+			return rtdcom->component;
+	}
+
+	return NULL;
+}
+
 struct snd_pcm_substream *snd_soc_get_dai_substream(struct snd_soc_card *card,
 		const char *dai_link, int stream)
 {
@@ -574,6 +622,7 @@ static struct snd_soc_pcm_runtime *soc_new_pcm_runtime(
 	if (!rtd)
 		return NULL;
 
+	INIT_LIST_HEAD(&rtd->component_list);
 	rtd->card = card;
 	rtd->dai_link = dai_link;
 	rtd->codec_dais = kzalloc(sizeof(struct snd_soc_dai *) *
@@ -591,6 +640,7 @@ static void soc_free_pcm_runtime(struct snd_soc_pcm_runtime *rtd)
 {
 	if (rtd && rtd->codec_dais)
 		kfree(rtd->codec_dais);
+	snd_soc_rtdcom_del_all(rtd);
 	kfree(rtd);
 }
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 2/3 v2][resend] ASoC: use snd_soc_rtdcom_add() and convert to consistent operation
  2017-08-08  6:17 [PATCH 0/3 v2][resend] ASoC: Component level pcm_new/pcm_free v2 Kuninori Morimoto
  2017-08-08  6:17 ` [PATCH 1/3 v2][resend] ASoC: soc-core: add snd_soc_rtdcom_xxx() Kuninori Morimoto
@ 2017-08-08  6:18 ` Kuninori Morimoto
  2017-08-08  6:18 ` [PATCH 3/3 v2][resend] ASoC: add Component level pcm_new/pcm_free v2 Kuninori Morimoto
  2017-08-08 10:48 ` [PATCH 0/3 v2][resend] ASoC: " Mark Brown
  3 siblings, 0 replies; 7+ messages in thread
From: Kuninori Morimoto @ 2017-08-08  6:18 UTC (permalink / raw)
  To: Mark Brown; +Cc: Linux-ALSA, Simon

From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>

Basically, current ALSA SoC framework is based on CPU/Codec/Platform,
but its operation doesn't have consistent.
Thus, source code was unreadable, and difficult to understand.
This patch connects each component (= CPU/Codec/Platform) to rtd by
using snd_soc_rtdcom_add(), and convert uneven operations to consistent
operation.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Tested-by: Arnaud Pouliquen <arnaud.pouliquen@st.com>
---
 include/sound/soc.h  |  2 +-
 sound/soc/soc-core.c | 61 +++++++++++++++++++++++-----------------------------
 sound/soc/soc-pcm.c  | 38 ++++++++++++++++----------------
 3 files changed, 47 insertions(+), 54 deletions(-)

diff --git a/include/sound/soc.h b/include/sound/soc.h
index b53b45d..82e29e4 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -1235,7 +1235,7 @@ struct snd_soc_pcm_runtime {
 	struct snd_pcm *pcm;
 	struct snd_compr *compr;
 	struct snd_soc_codec *codec;
-	struct snd_soc_platform *platform;
+	struct snd_soc_platform *platform; /* will be removed */
 	struct snd_soc_dai *codec_dai;
 	struct snd_soc_dai *cpu_dai;
 
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 5d8847f..e0f5d89 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -1099,6 +1099,7 @@ static int soc_bind_dai_link(struct snd_soc_card *card,
 	struct snd_soc_pcm_runtime *rtd;
 	struct snd_soc_dai_link_component *codecs = dai_link->codecs;
 	struct snd_soc_dai_link_component cpu_dai_component;
+	struct snd_soc_component *component;
 	struct snd_soc_dai **codec_dais;
 	struct snd_soc_platform *platform;
 	struct device_node *platform_of_node;
@@ -1126,6 +1127,7 @@ static int soc_bind_dai_link(struct snd_soc_card *card,
 			dai_link->cpu_dai_name);
 		goto _err_defer;
 	}
+	snd_soc_rtdcom_add(rtd, rtd->cpu_dai->component);
 
 	rtd->num_codecs = dai_link->num_codecs;
 
@@ -1138,6 +1140,7 @@ static int soc_bind_dai_link(struct snd_soc_card *card,
 				codecs[i].dai_name);
 			goto _err_defer;
 		}
+		snd_soc_rtdcom_add(rtd, codec_dais[i]->component);
 	}
 
 	/* Single codec links expect codec and codec_dai in runtime data */
@@ -1150,6 +1153,23 @@ static int soc_bind_dai_link(struct snd_soc_card *card,
 		platform_name = "snd-soc-dummy";
 
 	/* find one from the set of registered platforms */
+	list_for_each_entry(component, &component_list, list) {
+		platform_of_node = component->dev->of_node;
+		if (!platform_of_node && component->dev->parent->of_node)
+			platform_of_node = component->dev->parent->of_node;
+
+		if (dai_link->platform_of_node) {
+			if (platform_of_node != dai_link->platform_of_node)
+				continue;
+		} else {
+			if (strcmp(component->name, platform_name))
+				continue;
+		}
+
+		snd_soc_rtdcom_add(rtd, component);
+	}
+
+	/* find one from the set of registered platforms */
 	list_for_each_entry(platform, &platform_list, list) {
 		platform_of_node = platform->dev->of_node;
 		if (!platform_of_node && platform->dev->parent->of_node)
@@ -1234,27 +1254,15 @@ static void soc_remove_link_dais(struct snd_soc_card *card,
 static void soc_remove_link_components(struct snd_soc_card *card,
 	struct snd_soc_pcm_runtime *rtd, int order)
 {
-	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
-	struct snd_soc_platform *platform = rtd->platform;
 	struct snd_soc_component *component;
-	int i;
+	struct snd_soc_rtdcom_list *rtdcom;
 
-	/* remove the platform */
-	if (platform && platform->component.driver->remove_order == order)
-		soc_remove_component(&platform->component);
+	for_each_rtdcom(rtd, rtdcom) {
+		component = rtdcom->component;
 
-	/* remove the CODEC-side CODEC */
-	for (i = 0; i < rtd->num_codecs; i++) {
-		component = rtd->codec_dais[i]->component;
 		if (component->driver->remove_order == order)
 			soc_remove_component(component);
 	}
-
-	/* remove any CPU-side CODEC */
-	if (cpu_dai) {
-		if (cpu_dai->component->driver->remove_order == order)
-			soc_remove_component(cpu_dai->component);
-	}
 }
 
 static void soc_remove_dai_links(struct snd_soc_card *card)
@@ -1606,21 +1614,13 @@ static int soc_probe_link_components(struct snd_soc_card *card,
 			struct snd_soc_pcm_runtime *rtd,
 				     int order)
 {
-	struct snd_soc_platform *platform = rtd->platform;
 	struct snd_soc_component *component;
-	int i, ret;
+	struct snd_soc_rtdcom_list *rtdcom;
+	int ret;
 
-	/* probe the CPU-side component, if it is a CODEC */
-	component = rtd->cpu_dai->component;
-	if (component->driver->probe_order == order) {
-		ret = soc_probe_component(card, component);
-		if (ret < 0)
-			return ret;
-	}
+	for_each_rtdcom(rtd, rtdcom) {
+		component = rtdcom->component;
 
-	/* probe the CODEC-side components */
-	for (i = 0; i < rtd->num_codecs; i++) {
-		component = rtd->codec_dais[i]->component;
 		if (component->driver->probe_order == order) {
 			ret = soc_probe_component(card, component);
 			if (ret < 0)
@@ -1628,13 +1628,6 @@ static int soc_probe_link_components(struct snd_soc_card *card,
 		}
 	}
 
-	/* probe the platform */
-	if (platform->component.driver->probe_order == order) {
-		ret = soc_probe_component(card, &platform->component);
-		if (ret < 0)
-			return ret;
-	}
-
 	return 0;
 }
 
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index 7d3859e..df1587c 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -454,6 +454,8 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct snd_soc_platform *platform = rtd->platform;
+	struct snd_soc_component *component;
+	struct snd_soc_rtdcom_list *rtdcom;
 	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
 	struct snd_soc_dai *codec_dai;
 	const char *codec_dai_name = "multicodec";
@@ -462,10 +464,12 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
 	pinctrl_pm_select_default_state(cpu_dai->dev);
 	for (i = 0; i < rtd->num_codecs; i++)
 		pinctrl_pm_select_default_state(rtd->codec_dais[i]->dev);
-	pm_runtime_get_sync(cpu_dai->dev);
-	for (i = 0; i < rtd->num_codecs; i++)
-		pm_runtime_get_sync(rtd->codec_dais[i]->dev);
-	pm_runtime_get_sync(platform->dev);
+
+	for_each_rtdcom(rtd, rtdcom) {
+		component = rtdcom->component;
+
+		pm_runtime_get_sync(component->dev);
+	}
 
 	mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
 
@@ -603,15 +607,13 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
 out:
 	mutex_unlock(&rtd->pcm_mutex);
 
-	pm_runtime_mark_last_busy(platform->dev);
-	pm_runtime_put_autosuspend(platform->dev);
-	for (i = 0; i < rtd->num_codecs; i++) {
-		pm_runtime_mark_last_busy(rtd->codec_dais[i]->dev);
-		pm_runtime_put_autosuspend(rtd->codec_dais[i]->dev);
+	for_each_rtdcom(rtd, rtdcom) {
+		component = rtdcom->component;
+
+		pm_runtime_mark_last_busy(component->dev);
+		pm_runtime_put_autosuspend(component->dev);
 	}
 
-	pm_runtime_mark_last_busy(cpu_dai->dev);
-	pm_runtime_put_autosuspend(cpu_dai->dev);
 	for (i = 0; i < rtd->num_codecs; i++) {
 		if (!rtd->codec_dais[i]->active)
 			pinctrl_pm_select_sleep_state(rtd->codec_dais[i]->dev);
@@ -659,6 +661,8 @@ static int soc_pcm_close(struct snd_pcm_substream *substream)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct snd_soc_platform *platform = rtd->platform;
+	struct snd_soc_component *component;
+	struct snd_soc_rtdcom_list *rtdcom;
 	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
 	struct snd_soc_dai *codec_dai;
 	int i;
@@ -715,17 +719,13 @@ static int soc_pcm_close(struct snd_pcm_substream *substream)
 
 	mutex_unlock(&rtd->pcm_mutex);
 
-	pm_runtime_mark_last_busy(platform->dev);
-	pm_runtime_put_autosuspend(platform->dev);
+	for_each_rtdcom(rtd, rtdcom) {
+		component = rtdcom->component;
 
-	for (i = 0; i < rtd->num_codecs; i++) {
-		pm_runtime_mark_last_busy(rtd->codec_dais[i]->dev);
-		pm_runtime_put_autosuspend(rtd->codec_dais[i]->dev);
+		pm_runtime_mark_last_busy(component->dev);
+		pm_runtime_put_autosuspend(component->dev);
 	}
 
-	pm_runtime_mark_last_busy(cpu_dai->dev);
-	pm_runtime_put_autosuspend(cpu_dai->dev);
-
 	for (i = 0; i < rtd->num_codecs; i++) {
 		if (!rtd->codec_dais[i]->active)
 			pinctrl_pm_select_sleep_state(rtd->codec_dais[i]->dev);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 3/3 v2][resend] ASoC: add Component level pcm_new/pcm_free v2
  2017-08-08  6:17 [PATCH 0/3 v2][resend] ASoC: Component level pcm_new/pcm_free v2 Kuninori Morimoto
  2017-08-08  6:17 ` [PATCH 1/3 v2][resend] ASoC: soc-core: add snd_soc_rtdcom_xxx() Kuninori Morimoto
  2017-08-08  6:18 ` [PATCH 2/3 v2][resend] ASoC: use snd_soc_rtdcom_add() and convert to consistent operation Kuninori Morimoto
@ 2017-08-08  6:18 ` Kuninori Morimoto
  2017-08-08 10:48 ` [PATCH 0/3 v2][resend] ASoC: " Mark Brown
  3 siblings, 0 replies; 7+ messages in thread
From: Kuninori Morimoto @ 2017-08-08  6:18 UTC (permalink / raw)
  To: Mark Brown; +Cc: Linux-ALSA, Simon


From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>

In current ALSA SoC, Platform only has pcm_new/pcm_free feature,
but it should be supported on Component level. This patch adds it.

The v1 was added commit 99b04f4c4051f7 ("ASoC: add Component level
pcm_new/pcm_free") but it called all "card" connected component's
pcm_new/free, it was wrong.
This patch calls "rtd" connected component.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Tested-by: Arnaud Pouliquen <arnaud.pouliquen@st.com>
---
 include/sound/soc.h  |  6 ++++++
 sound/soc/soc-core.c | 42 ++++++++++++++++++++++++++++++++++++++++++
 sound/soc/soc-pcm.c  | 30 +++++++++++++++++++++++++-----
 3 files changed, 73 insertions(+), 5 deletions(-)

diff --git a/include/sound/soc.h b/include/sound/soc.h
index 82e29e4..689d06a 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -795,6 +795,10 @@ struct snd_soc_component_driver {
 	int (*suspend)(struct snd_soc_component *);
 	int (*resume)(struct snd_soc_component *);
 
+	/* pcm creation and destruction */
+	int (*pcm_new)(struct snd_soc_pcm_runtime *);
+	void (*pcm_free)(struct snd_pcm *);
+
 	/* DT */
 	int (*of_xlate_dai_name)(struct snd_soc_component *component,
 				 struct of_phandle_args *args,
@@ -870,6 +874,8 @@ struct snd_soc_component {
 	void (*remove)(struct snd_soc_component *);
 	int (*suspend)(struct snd_soc_component *);
 	int (*resume)(struct snd_soc_component *);
+	int (*pcm_new)(struct snd_soc_component *, struct snd_soc_pcm_runtime *);
+	void (*pcm_free)(struct snd_soc_component *, struct snd_pcm *);
 
 	/* machine specific init */
 	int (*init)(struct snd_soc_component *component);
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index e0f5d89..57cf4f5 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -3197,6 +3197,22 @@ static int snd_soc_component_stream_event(struct snd_soc_dapm_context *dapm,
 	return component->driver->stream_event(component, event);
 }
 
+static int snd_soc_component_drv_pcm_new(struct snd_soc_component *component,
+					struct snd_soc_pcm_runtime *rtd)
+{
+	if (component->driver->pcm_new)
+		return component->driver->pcm_new(rtd);
+
+	return 0;
+}
+
+static void snd_soc_component_drv_pcm_free(struct snd_soc_component *component,
+					  struct snd_pcm *pcm)
+{
+	if (component->driver->pcm_free)
+		component->driver->pcm_free(pcm);
+}
+
 static int snd_soc_component_initialize(struct snd_soc_component *component,
 	const struct snd_soc_component_driver *driver, struct device *dev)
 {
@@ -3214,6 +3230,8 @@ static int snd_soc_component_initialize(struct snd_soc_component *component,
 	component->remove = component->driver->remove;
 	component->suspend = component->driver->suspend;
 	component->resume = component->driver->resume;
+	component->pcm_new = snd_soc_component_drv_pcm_new;
+	component->pcm_free = snd_soc_component_drv_pcm_free;
 
 	dapm = &component->dapm;
 	dapm->dev = dev;
@@ -3413,6 +3431,26 @@ static void snd_soc_platform_drv_remove(struct snd_soc_component *component)
 	platform->driver->remove(platform);
 }
 
+static int snd_soc_platform_drv_pcm_new(struct snd_soc_component *component,
+					struct snd_soc_pcm_runtime *rtd)
+{
+	struct snd_soc_platform *platform = snd_soc_component_to_platform(component);
+
+	if (platform->driver->pcm_new)
+		return platform->driver->pcm_new(rtd);
+
+	return 0;
+}
+
+static void snd_soc_platform_drv_pcm_free(struct snd_soc_component *component,
+					  struct snd_pcm *pcm)
+{
+	struct snd_soc_platform *platform = snd_soc_component_to_platform(component);
+
+	if (platform->driver->pcm_free)
+		platform->driver->pcm_free(pcm);
+}
+
 /**
  * snd_soc_add_platform - Add a platform to the ASoC core
  * @dev: The parent device for the platform
@@ -3436,6 +3474,10 @@ int snd_soc_add_platform(struct device *dev, struct snd_soc_platform *platform,
 		platform->component.probe = snd_soc_platform_drv_probe;
 	if (platform_drv->remove)
 		platform->component.remove = snd_soc_platform_drv_remove;
+	if (platform_drv->pcm_new)
+		platform->component.pcm_new = snd_soc_platform_drv_pcm_new;
+	if (platform_drv->pcm_free)
+		platform->component.pcm_free = snd_soc_platform_drv_pcm_free;
 
 #ifdef CONFIG_DEBUG_FS
 	platform->component.debugfs_prefix = "platform";
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index df1587c..844bbd5 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -2632,12 +2632,28 @@ static int dpcm_fe_dai_close(struct snd_pcm_substream *fe_substream)
 	return ret;
 }
 
+static void soc_pcm_free(struct snd_pcm *pcm)
+{
+	struct snd_soc_pcm_runtime *rtd = pcm->private_data;
+	struct snd_soc_rtdcom_list *rtdcom;
+	struct snd_soc_component *component;
+
+	for_each_rtdcom(rtd, rtdcom) {
+		component = rtdcom->component;
+
+		if (component->pcm_free)
+			component->pcm_free(component, pcm);
+	}
+}
+
 /* create a new pcm */
 int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
 {
 	struct snd_soc_platform *platform = rtd->platform;
 	struct snd_soc_dai *codec_dai;
 	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+	struct snd_soc_component *component;
+	struct snd_soc_rtdcom_list *rtdcom;
 	struct snd_pcm *pcm;
 	char new_name[64];
 	int ret = 0, playback = 0, capture = 0;
@@ -2747,17 +2763,21 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
 	if (capture)
 		snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &rtd->ops);
 
-	if (platform->driver->pcm_new) {
-		ret = platform->driver->pcm_new(rtd);
+	for_each_rtdcom(rtd, rtdcom) {
+		component = rtdcom->component;
+
+		if (!component->pcm_new)
+			continue;
+
+		ret = component->pcm_new(component, rtd);
 		if (ret < 0) {
-			dev_err(platform->dev,
+			dev_err(component->dev,
 				"ASoC: pcm constructor failed: %d\n",
 				ret);
 			return ret;
 		}
 	}
-
-	pcm->private_free = platform->driver->pcm_free;
+	pcm->private_free = soc_pcm_free;
 out:
 	dev_info(rtd->card->dev, "%s <-> %s mapping ok\n",
 		 (rtd->num_codecs > 1) ? "multicodec" : rtd->codec_dai->name,
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH 0/3 v2][resend] ASoC: Component level pcm_new/pcm_free v2
  2017-08-08  6:17 [PATCH 0/3 v2][resend] ASoC: Component level pcm_new/pcm_free v2 Kuninori Morimoto
                   ` (2 preceding siblings ...)
  2017-08-08  6:18 ` [PATCH 3/3 v2][resend] ASoC: add Component level pcm_new/pcm_free v2 Kuninori Morimoto
@ 2017-08-08 10:48 ` Mark Brown
  2017-08-09  0:24   ` Kuninori Morimoto
  3 siblings, 1 reply; 7+ messages in thread
From: Mark Brown @ 2017-08-08 10:48 UTC (permalink / raw)
  To: Kuninori Morimoto; +Cc: Linux-ALSA, Simon


[-- Attachment #1.1: Type: text/plain, Size: 353 bytes --]

On Tue, Aug 08, 2017 at 06:17:07AM +0000, Kuninori Morimoto wrote:

> I posted this patch-set 2weeks ago, and no response, no objection from community.
> Thus, I re-post these again.

You posted three patch serieses threaded together with each other which
made it look like it was intended to make the organization of a single
big patch series clearer.

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 0/3 v2][resend] ASoC: Component level pcm_new/pcm_free v2
  2017-08-08 10:48 ` [PATCH 0/3 v2][resend] ASoC: " Mark Brown
@ 2017-08-09  0:24   ` Kuninori Morimoto
  0 siblings, 0 replies; 7+ messages in thread
From: Kuninori Morimoto @ 2017-08-09  0:24 UTC (permalink / raw)
  To: Mark Brown; +Cc: Linux-ALSA, Simon


Hi Mark

> > I posted this patch-set 2weeks ago, and no response, no objection from community.
> > Thus, I re-post these again.
> 
> You posted three patch serieses threaded together with each other which
> made it look like it was intended to make the organization of a single
> big patch series clearer.

Yes. I'm sorry, it was not clear.
>From big picture (= replace platform to component) point of view,
3 step are needed, IMO.
 - 1) component tidyup/cleanup
 - 2) rtd component list
 - 3) replace platform to component

I posted these 3 patch-set in previous time.
Because it can indicate 3 steps, and I wanted to know 2) and 3)
opinion/review.

Now, 1) part is almost applied in your tree. It is independent from 2) and 3).
This patch-set is 2) position.
If 2) are accepted, I will post 3) patch-set.

Best regards
---
Kuninori Morimoto

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Applied "ASoC: soc-core: add snd_soc_rtdcom_xxx()" to the asoc tree
  2017-08-08  6:17 ` [PATCH 1/3 v2][resend] ASoC: soc-core: add snd_soc_rtdcom_xxx() Kuninori Morimoto
@ 2017-08-10 15:41   ` Mark Brown
  0 siblings, 0 replies; 7+ messages in thread
From: Mark Brown @ 2017-08-10 15:41 UTC (permalink / raw)
  To: Kuninori Morimoto; +Cc: alsa-devel, Mark Brown, Arnaud Pouliquen, Simon

The patch

   ASoC: soc-core: add snd_soc_rtdcom_xxx()

has been applied to the asoc tree at

   git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From a0ac441152238c9b474bafa46940511d9b2e9c7e Mon Sep 17 00:00:00 2001
From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date: Tue, 8 Aug 2017 06:17:47 +0000
Subject: [PATCH] ASoC: soc-core: add snd_soc_rtdcom_xxx()

Current snd_soc_pcm_runtime has platform / codec pointers, and we could
use these specific pointer. But these will be replaced to more generic
"component" soon, and will need more generic method to get each
connected component pointer from rtd.

This patch adds new snd_soc_rtdcom_xxx() to connect/disconnect
component to rtd. It means same as previous "platform" / "codec"
pointer style, but more generic.
We can find necessary component pointer from rtd by using component
driver name on snd_soc_rtdcom_lookup().

Here, the reason why it uses "driver name" is that "component name"
was created by fmt_single_name() and difficult to use it from driver.
Driver of course knows its "driver name", thus, using it is more easy.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Tested-by: Arnaud Pouliquen <arnaud.pouliquen@st.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 include/sound/soc.h  | 13 +++++++++++++
 sound/soc/soc-core.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 63 insertions(+)

diff --git a/include/sound/soc.h b/include/sound/soc.h
index aad3f14966f1..87dbe39797ca 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -886,6 +886,18 @@ struct snd_soc_component {
 #endif
 };
 
+struct snd_soc_rtdcom_list {
+	struct snd_soc_component *component;
+	struct list_head list; /* rtd::component_list */
+};
+struct snd_soc_component*
+snd_soc_rtdcom_lookup(struct snd_soc_pcm_runtime *rtd,
+		       const char *driver_name);
+#define for_each_rtdcom(rtd, rtdcom) \
+	list_for_each_entry(rtdcom, &(rtd)->component_list, list)
+#define for_each_rtdcom_safe(rtd, rtdcom1, rtdcom2) \
+	list_for_each_entry_safe(rtdcom1, rtdcom2, &(rtd)->component_list, list)
+
 /* SoC Audio Codec device */
 struct snd_soc_codec {
 	struct device *dev;
@@ -1240,6 +1252,7 @@ struct snd_soc_pcm_runtime {
 
 	unsigned int num; /* 0-based and monotonic increasing */
 	struct list_head list; /* rtd list of the soc card */
+	struct list_head component_list; /* list of connected components */
 
 	/* bit field */
 	unsigned int dev_registered:1;
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 07d708498500..c2462e0f0f0d 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -551,6 +551,54 @@ static inline void snd_soc_debugfs_exit(void)
 
 #endif
 
+static int snd_soc_rtdcom_add(struct snd_soc_pcm_runtime *rtd,
+			      struct snd_soc_component *component)
+{
+	struct snd_soc_rtdcom_list *rtdcom;
+	struct snd_soc_rtdcom_list *new_rtdcom;
+
+	for_each_rtdcom(rtd, rtdcom) {
+		/* already connected */
+		if (rtdcom->component == component)
+			return 0;
+	}
+
+	new_rtdcom = kmalloc(sizeof(*new_rtdcom), GFP_KERNEL);
+	if (!new_rtdcom)
+		return -ENOMEM;
+
+	new_rtdcom->component = component;
+	INIT_LIST_HEAD(&new_rtdcom->list);
+
+	list_add_tail(&new_rtdcom->list, &rtd->component_list);
+
+	return 0;
+}
+
+static void snd_soc_rtdcom_del_all(struct snd_soc_pcm_runtime *rtd)
+{
+	struct snd_soc_rtdcom_list *rtdcom1, *rtdcom2;
+
+	for_each_rtdcom_safe(rtd, rtdcom1, rtdcom2)
+		kfree(rtdcom1);
+
+	INIT_LIST_HEAD(&rtd->component_list);
+}
+
+struct snd_soc_component *snd_soc_rtdcom_lookup(struct snd_soc_pcm_runtime *rtd,
+						const char *driver_name)
+{
+	struct snd_soc_rtdcom_list *rtdcom;
+
+	for_each_rtdcom(rtd, rtdcom) {
+		if ((rtdcom->component->driver->name == driver_name) ||
+		    strcmp(rtdcom->component->driver->name, driver_name) == 0)
+			return rtdcom->component;
+	}
+
+	return NULL;
+}
+
 struct snd_pcm_substream *snd_soc_get_dai_substream(struct snd_soc_card *card,
 		const char *dai_link, int stream)
 {
@@ -575,6 +623,7 @@ static struct snd_soc_pcm_runtime *soc_new_pcm_runtime(
 	if (!rtd)
 		return NULL;
 
+	INIT_LIST_HEAD(&rtd->component_list);
 	rtd->card = card;
 	rtd->dai_link = dai_link;
 	rtd->codec_dais = kzalloc(sizeof(struct snd_soc_dai *) *
@@ -592,6 +641,7 @@ static void soc_free_pcm_runtime(struct snd_soc_pcm_runtime *rtd)
 {
 	if (rtd && rtd->codec_dais)
 		kfree(rtd->codec_dais);
+	snd_soc_rtdcom_del_all(rtd);
 	kfree(rtd);
 }
 
-- 
2.13.2

^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2017-08-10 15:42 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-08-08  6:17 [PATCH 0/3 v2][resend] ASoC: Component level pcm_new/pcm_free v2 Kuninori Morimoto
2017-08-08  6:17 ` [PATCH 1/3 v2][resend] ASoC: soc-core: add snd_soc_rtdcom_xxx() Kuninori Morimoto
2017-08-10 15:41   ` Applied "ASoC: soc-core: add snd_soc_rtdcom_xxx()" to the asoc tree Mark Brown
2017-08-08  6:18 ` [PATCH 2/3 v2][resend] ASoC: use snd_soc_rtdcom_add() and convert to consistent operation Kuninori Morimoto
2017-08-08  6:18 ` [PATCH 3/3 v2][resend] ASoC: add Component level pcm_new/pcm_free v2 Kuninori Morimoto
2017-08-08 10:48 ` [PATCH 0/3 v2][resend] ASoC: " Mark Brown
2017-08-09  0:24   ` Kuninori Morimoto

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.