| From ecce180cbbb27b5f7f1bdec2c1a7f8d282b7f9b7 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Wed, 4 Jun 2025 02:06:48 +0000 |
| Subject: ASoC: qcom: use drvdata instead of component to keep id |
| |
| From: Srinivas Kandagatla <srini@kernel.org> |
| |
| [ Upstream commit 8167f4f42572818fa8153be2b03e4c2120846603 ] |
| |
| Qcom lpass is using component->id to keep DAI ID (A). |
| |
| (S) static int lpass_platform_pcmops_open( |
| sruct snd_soc_component *component, |
| struct snd_pcm_substream *substream) |
| { ^^^^^^^^^(B0) |
| ... |
| (B1) struct snd_soc_pcm_runtime *soc_runtime = snd_soc_substream_to_rtd(substream); |
| (B2) struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(soc_runtime, 0); |
| ... |
| (B3) unsigned int dai_id = cpu_dai->driver->id; |
| |
| (A) component->id = dai_id; |
| ... |
| } |
| |
| This driver can get dai_id from substream (B0 - B3). |
| In this driver, below functions get dai_id from component->id (A). |
| |
| (X) lpass_platform_pcmops_suspend() |
| (Y) lpass_platform_pcmops_resume() |
| (Z) lpass_platform_copy() |
| |
| Here, (Z) can get it from substream (B0 - B3), don't need to use |
| component->id (A). On suspend/resume (X)(Y), dai_id can only be obtained |
| from component->id (A), because there is no substream (B0) in function |
| parameter. |
| |
| But, component->id (A) itself should not be used for such purpose. |
| It is intilialized at snd_soc_component_initialize(), and parsed its ID |
| (= component->id) from device name (a). |
| |
| int snd_soc_component_initialize(...) |
| { |
| ... |
| if (!component->name) { |
| (a) component->name = fmt_single_name(dev, &component->id); |
| ... ^^^^^^^^^^^^^ |
| } |
| ... |
| } |
| |
| Unfortunately, current code is broken to start with. |
| |
| There are many regmaps that the driver cares about, however its only |
| managing one (either dp or i2s) in component suspend/resume path. |
| |
| I2S regmap is mandatory however other regmaps are setup based on flags |
| like "hdmi_port_enable" and "codec_dma_enable". |
| |
| Correct thing for suspend/resume path to handle is by checking these |
| flags, instead of using component->id. |
| |
| Signed-off-by: Srinivas Kandagatla <srini@kernel.org> |
| Suggested-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> |
| Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> |
| Link: https://patch.msgid.link/87a56ouuob.wl-kuninori.morimoto.gx@renesas.com |
| Signed-off-by: Mark Brown <broonie@kernel.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| sound/soc/qcom/lpass-platform.c | 27 +++++++++++++++++---------- |
| 1 file changed, 17 insertions(+), 10 deletions(-) |
| |
| diff --git a/sound/soc/qcom/lpass-platform.c b/sound/soc/qcom/lpass-platform.c |
| index f918d9e16dc0..f342bc4b3a14 100644 |
| --- a/sound/soc/qcom/lpass-platform.c |
| +++ b/sound/soc/qcom/lpass-platform.c |
| @@ -201,7 +201,6 @@ static int lpass_platform_pcmops_open(struct snd_soc_component *component, |
| struct regmap *map; |
| unsigned int dai_id = cpu_dai->driver->id; |
| |
| - component->id = dai_id; |
| data = kzalloc(sizeof(*data), GFP_KERNEL); |
| if (!data) |
| return -ENOMEM; |
| @@ -1189,13 +1188,14 @@ static int lpass_platform_pcmops_suspend(struct snd_soc_component *component) |
| { |
| struct lpass_data *drvdata = snd_soc_component_get_drvdata(component); |
| struct regmap *map; |
| - unsigned int dai_id = component->id; |
| |
| - if (dai_id == LPASS_DP_RX) |
| + if (drvdata->hdmi_port_enable) { |
| map = drvdata->hdmiif_map; |
| - else |
| - map = drvdata->lpaif_map; |
| + regcache_cache_only(map, true); |
| + regcache_mark_dirty(map); |
| + } |
| |
| + map = drvdata->lpaif_map; |
| regcache_cache_only(map, true); |
| regcache_mark_dirty(map); |
| |
| @@ -1206,14 +1206,19 @@ static int lpass_platform_pcmops_resume(struct snd_soc_component *component) |
| { |
| struct lpass_data *drvdata = snd_soc_component_get_drvdata(component); |
| struct regmap *map; |
| - unsigned int dai_id = component->id; |
| + int ret; |
| |
| - if (dai_id == LPASS_DP_RX) |
| + if (drvdata->hdmi_port_enable) { |
| map = drvdata->hdmiif_map; |
| - else |
| - map = drvdata->lpaif_map; |
| + regcache_cache_only(map, false); |
| + ret = regcache_sync(map); |
| + if (ret) |
| + return ret; |
| + } |
| |
| + map = drvdata->lpaif_map; |
| regcache_cache_only(map, false); |
| + |
| return regcache_sync(map); |
| } |
| |
| @@ -1223,7 +1228,9 @@ static int lpass_platform_copy(struct snd_soc_component *component, |
| unsigned long bytes) |
| { |
| struct snd_pcm_runtime *rt = substream->runtime; |
| - unsigned int dai_id = component->id; |
| + struct snd_soc_pcm_runtime *soc_runtime = snd_soc_substream_to_rtd(substream); |
| + struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(soc_runtime, 0); |
| + unsigned int dai_id = cpu_dai->driver->id; |
| int ret = 0; |
| |
| void __iomem *dma_buf = (void __iomem *) (rt->dma_area + pos + |
| -- |
| 2.39.5 |
| |