summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorAdam Brickman <Adam.Brickman@cirrus.com>2020-10-01 18:24:25 +0300
committerMark Brown <broonie@kernel.org>2020-10-01 20:26:19 +0300
commit20441614d89867142060d3bcd79cc111d8ba7a8e (patch)
treec5652d0882b51aa65bae76aaa5d03801854dba0a /sound
parent6bf28e8a05fda0547658fd51d0acc83dcac6c703 (diff)
downloadlinux-20441614d89867142060d3bcd79cc111d8ba7a8e.tar.xz
ASoC: wm_adsp: Pass full name to snd_ctl_notify
A call to wm_adsp_write_ctl() could cause a kernel crash if it does not retrieve a valid kcontrol from snd_soc_card_get_kcontrol(). This can happen due to a missing control name prefix. Then, snd_ctl_notify() crashes when it tries to use the id field. Modified wm_adsp_write_ctl() to incorporate the name_prefix (if applicable) such that it is able to retrieve a valid id field from the kcontrol once the platform has booted. Fixes: eb65ccdb0836 ("ASoC: wm_adsp: Expose mixer control API") Signed-off-by: Adam Brickman <Adam.Brickman@cirrus.com> Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com> Link: https://lore.kernel.org/r/20201001152425.8590-1-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/codecs/wm_adsp.c20
1 files changed, 19 insertions, 1 deletions
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index 410cca57da52..344bd2c33bea 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -2049,6 +2049,7 @@ int wm_adsp_write_ctl(struct wm_adsp *dsp, const char *name, int type,
{
struct wm_coeff_ctl *ctl;
struct snd_kcontrol *kcontrol;
+ char ctl_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
int ret;
ctl = wm_adsp_get_ctl(dsp, name, type, alg);
@@ -2059,8 +2060,25 @@ int wm_adsp_write_ctl(struct wm_adsp *dsp, const char *name, int type,
return -EINVAL;
ret = wm_coeff_write_ctrl(ctl, buf, len);
+ if (ret)
+ return ret;
+
+ if (ctl->flags & WMFW_CTL_FLAG_SYS)
+ return 0;
+
+ if (dsp->component->name_prefix)
+ snprintf(ctl_name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, "%s %s",
+ dsp->component->name_prefix, ctl->name);
+ else
+ snprintf(ctl_name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, "%s",
+ ctl->name);
+
+ kcontrol = snd_soc_card_get_kcontrol(dsp->component->card, ctl_name);
+ if (!kcontrol) {
+ adsp_err(dsp, "Can't find kcontrol %s\n", ctl_name);
+ return -EINVAL;
+ }
- kcontrol = snd_soc_card_get_kcontrol(dsp->component->card, ctl->name);
snd_ctl_notify(dsp->component->card->snd_card,
SNDRV_CTL_EVENT_MASK_VALUE, &kcontrol->id);