From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
[ Upstream commit f40ecc2743652c0b0f19935f81baf57c601eb7f0 ]
ASoC has 2 functions to set bias level. (A) snd_soc_dapm_force_bias_level() (B) snd_soc_dapm_set_bias_level()
snd_soc_dapm_force_bias_level() (A) will set dapm->bias_level (a) if successed.
(A) int snd_soc_dapm_force_bias_level(...) { ... if (ret == 0) (a) dapm->bias_level = level; ... }
snd_soc_dapm_set_bias_level() (B) is also a function that sets bias_level. It will call snd_soc_dapm_force_bias_level() (A) inside, but doesn't set dapm->bias_level by itself. One note is that (A) might not be called.
(B) static int snd_soc_dapm_set_bias_level(...) { ... ret = snd_soc_card_set_bias_level(...); ... if (dapm != &card->dapm) (A) ret = snd_soc_dapm_force_bias_level(...); ... ret = snd_soc_card_set_bias_level_post(...); ... }
dapm->bias_level will be set if (A) was called, but might not be set if (B) was called, even though it calles set_bias_level() function.
We should set dapm->bias_level if we calls snd_soc_dapm_set_bias_level() (B), too.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com Link: https://patch.msgid.link/87qzyn4g4h.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
Based on my analysis, here's my assessment:
**Backport Status: YES**
This commit should be backported to stable kernel trees for the following reasons:
1. **Bug Fix**: This is a clear bug fix that addresses an inconsistency in bias level management. The commit message clearly explains that `snd_soc_dapm_set_bias_level()` doesn't always update `dapm->bias_level`, particularly when dealing with card-level DAPM contexts where `snd_soc_dapm_force_bias_level()` is not called.
2. **Small and Contained**: The fix is minimal - it only adds 4 lines of code: ```c /* success */ if (ret == 0) snd_soc_dapm_init_bias_level(dapm, level); ``` This ensures that `dapm->bias_level` is always updated when the bias level change succeeds.
3. **Important Correctness Issue**: The inconsistency could lead to incorrect bias level tracking, which affects power management decisions in the ASoC subsystem. Code that checks `dapm->bias_level` (as shown in lines like `if (dapm->bias_level == SND_SOC_BIAS_ON)`) may make wrong decisions if the bias level isn't properly tracked.
4. **No Architectural Changes**: This is a straightforward fix that doesn't introduce new features or change the architecture. It simply ensures consistent behavior between the two bias level setting functions.
5. **Low Risk**: The change only affects the success path (when `ret == 0`) and uses an existing inline function `snd_soc_dapm_init_bias_level()` that simply sets `dapm->bias_level = level`. This is the same operation that `snd_soc_dapm_force_bias_level()` performs on success.
6. **Affects User-Facing Functionality**: Incorrect bias level tracking can lead to power management issues, potentially causing audio devices to not power up/down correctly, which directly impacts users.
The commit fixes a real bug where the DAPM bias level state could become out of sync with the actual hardware state, particularly for card-level DAPM contexts. This is exactly the type of bug fix that stable kernels should include - it's small, targeted, fixes a real issue, and has minimal risk of introducing regressions.
sound/soc/soc-dapm.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index f26f9e9d7ce7..7d9c9e8839f6 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -739,6 +739,10 @@ static int snd_soc_dapm_set_bias_level(struct snd_soc_dapm_context *dapm, out: trace_snd_soc_bias_level_done(dapm, level);
+ /* success */ + if (ret == 0) + snd_soc_dapm_init_bias_level(dapm, level); + return ret; }