This is a note to let you know that I've just added the patch titled ALSA: hda/tas2781: add locks to kcontrols to the 6.6-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: alsa-hda-tas2781-add-locks-to-kcontrols.patch and it can be found in the queue-6.6 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. >From 15bc3066d2378eef1b45254be9df23b0dd7f1667 Mon Sep 17 00:00:00 2001 From: Gergo Koteles <soyer@xxxxxx> Date: Tue, 26 Mar 2024 17:18:46 +0100 Subject: ALSA: hda/tas2781: add locks to kcontrols From: Gergo Koteles <soyer@xxxxxx> commit 15bc3066d2378eef1b45254be9df23b0dd7f1667 upstream. The rcabin.profile_cfg_id, cur_prog, cur_conf, force_fwload_status variables are acccessible from multiple threads and therefore require locking. Fixes: 5be27f1e3ec9 ("ALSA: hda/tas2781: Add tas2781 HDA driver") CC: stable@xxxxxxxxxxxxxxx Signed-off-by: Gergo Koteles <soyer@xxxxxx> Message-ID: <e35b867f6fe5fa1f869dd658a0a1f2118b737f57.1711469583.git.soyer@xxxxxx> Signed-off-by: Takashi Iwai <tiwai@xxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- sound/pci/hda/tas2781_hda_i2c.c | 50 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-) --- a/sound/pci/hda/tas2781_hda_i2c.c +++ b/sound/pci/hda/tas2781_hda_i2c.c @@ -179,8 +179,12 @@ static int tasdevice_get_profile_id(stru { struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol); + mutex_lock(&tas_priv->codec_lock); + ucontrol->value.integer.value[0] = tas_priv->rcabin.profile_cfg_id; + mutex_unlock(&tas_priv->codec_lock); + return 0; } @@ -194,11 +198,15 @@ static int tasdevice_set_profile_id(stru val = clamp(nr_profile, 0, max); + mutex_lock(&tas_priv->codec_lock); + if (tas_priv->rcabin.profile_cfg_id != val) { tas_priv->rcabin.profile_cfg_id = val; ret = 1; } + mutex_unlock(&tas_priv->codec_lock); + return ret; } @@ -235,8 +243,12 @@ static int tasdevice_program_get(struct { struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol); + mutex_lock(&tas_priv->codec_lock); + ucontrol->value.integer.value[0] = tas_priv->cur_prog; + mutex_unlock(&tas_priv->codec_lock); + return 0; } @@ -251,11 +263,15 @@ static int tasdevice_program_put(struct val = clamp(nr_program, 0, max); + mutex_lock(&tas_priv->codec_lock); + if (tas_priv->cur_prog != val) { tas_priv->cur_prog = val; ret = 1; } + mutex_unlock(&tas_priv->codec_lock); + return ret; } @@ -264,8 +280,12 @@ static int tasdevice_config_get(struct s { struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol); + mutex_lock(&tas_priv->codec_lock); + ucontrol->value.integer.value[0] = tas_priv->cur_conf; + mutex_unlock(&tas_priv->codec_lock); + return 0; } @@ -280,11 +300,15 @@ static int tasdevice_config_put(struct s val = clamp(nr_config, 0, max); + mutex_lock(&tas_priv->codec_lock); + if (tas_priv->cur_conf != val) { tas_priv->cur_conf = val; ret = 1; } + mutex_unlock(&tas_priv->codec_lock); + return ret; } @@ -294,8 +318,15 @@ static int tas2781_amp_getvol(struct snd struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol); struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; + int ret; - return tasdevice_amp_getvol(tas_priv, ucontrol, mc); + mutex_lock(&tas_priv->codec_lock); + + ret = tasdevice_amp_getvol(tas_priv, ucontrol, mc); + + mutex_unlock(&tas_priv->codec_lock); + + return ret; } static int tas2781_amp_putvol(struct snd_kcontrol *kcontrol, @@ -304,9 +335,16 @@ static int tas2781_amp_putvol(struct snd struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol); struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; + int ret; + + mutex_lock(&tas_priv->codec_lock); /* The check of the given value is in tasdevice_amp_putvol. */ - return tasdevice_amp_putvol(tas_priv, ucontrol, mc); + ret = tasdevice_amp_putvol(tas_priv, ucontrol, mc); + + mutex_unlock(&tas_priv->codec_lock); + + return ret; } static int tas2781_force_fwload_get(struct snd_kcontrol *kcontrol, @@ -314,10 +352,14 @@ static int tas2781_force_fwload_get(stru { struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol); + mutex_lock(&tas_priv->codec_lock); + ucontrol->value.integer.value[0] = (int)tas_priv->force_fwload_status; dev_dbg(tas_priv->dev, "%s : Force FWload %s\n", __func__, tas_priv->force_fwload_status ? "ON" : "OFF"); + mutex_unlock(&tas_priv->codec_lock); + return 0; } @@ -327,6 +369,8 @@ static int tas2781_force_fwload_put(stru struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol); bool change, val = (bool)ucontrol->value.integer.value[0]; + mutex_lock(&tas_priv->codec_lock); + if (tas_priv->force_fwload_status == val) change = false; else { @@ -336,6 +380,8 @@ static int tas2781_force_fwload_put(stru dev_dbg(tas_priv->dev, "%s : Force FWload %s\n", __func__, tas_priv->force_fwload_status ? "ON" : "OFF"); + mutex_unlock(&tas_priv->codec_lock); + return change; } Patches currently in stable-queue which might be from soyer@xxxxxx are queue-6.6/alsa-hda-tas2781-remove-digital-gain-kcontrol.patch queue-6.6/alsa-hda-tas2781-add-locks-to-kcontrols.patch