blob: 99e23bb67e57ac06ce09059cc34d8a1ca7a8d5dc [file] [log] [blame]
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