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@vger.kernel.org Signed-off-by: Gergo Koteles soyer@irl.hu --- sound/pci/hda/tas2781_hda_i2c.c | 50 +++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-)
diff --git a/sound/pci/hda/tas2781_hda_i2c.c b/sound/pci/hda/tas2781_hda_i2c.c index 5acb475c10a7..9a43f563bb9e 100644 --- a/sound/pci/hda/tas2781_hda_i2c.c +++ b/sound/pci/hda/tas2781_hda_i2c.c @@ -185,8 +185,12 @@ static int tasdevice_get_profile_id(struct snd_kcontrol *kcontrol, { 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; }
@@ -200,11 +204,15 @@ static int tasdevice_set_profile_id(struct snd_kcontrol *kcontrol,
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; }
@@ -241,8 +249,12 @@ static int tasdevice_program_get(struct snd_kcontrol *kcontrol, { 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; }
@@ -257,11 +269,15 @@ static int tasdevice_program_put(struct snd_kcontrol *kcontrol,
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; }
@@ -270,8 +286,12 @@ static int tasdevice_config_get(struct snd_kcontrol *kcontrol, { 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; }
@@ -286,11 +306,15 @@ static int tasdevice_config_put(struct snd_kcontrol *kcontrol,
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; }
@@ -300,8 +324,15 @@ static int tas2781_amp_getvol(struct snd_kcontrol *kcontrol, 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); + + ret = tasdevice_amp_getvol(tas_priv, ucontrol, mc); + + mutex_unlock(&tas_priv->codec_lock);
- return tasdevice_amp_getvol(tas_priv, ucontrol, mc); + return ret; }
static int tas2781_amp_putvol(struct snd_kcontrol *kcontrol, @@ -310,9 +341,16 @@ static int tas2781_amp_putvol(struct snd_kcontrol *kcontrol, 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, @@ -320,10 +358,14 @@ static int tas2781_force_fwload_get(struct snd_kcontrol *kcontrol, { 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; }
@@ -333,6 +375,8 @@ static int tas2781_force_fwload_put(struct snd_kcontrol *kcontrol, 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 { @@ -342,6 +386,8 @@ static int tas2781_force_fwload_put(struct snd_kcontrol *kcontrol, 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; }