Skip to content

Commit

Permalink
ALSA: hda/tas2781: add locks to kcontrols
Browse files Browse the repository at this point in the history
commit 15bc306 upstream.

The rcabin.profile_cfg_id, cur_prog, cur_conf, force_fwload_status
variables are acccessible from multiple threads and therefore require
locking.

Fixes: 5be27f1 ("ALSA: hda/tas2781: Add tas2781 HDA driver")
CC: stable@vger.kernel.org
Signed-off-by: Gergo Koteles <soyer@irl.hu>
Message-ID: <e35b867f6fe5fa1f869dd658a0a1f2118b737f57.1711469583.git.soyer@irl.hu>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
soyersoyer authored and gregkh committed Apr 3, 2024
1 parent 7316ccd commit 6dfc6b1
Showing 1 changed file with 48 additions and 2 deletions.
50 changes: 48 additions & 2 deletions sound/pci/hda/tas2781_hda_i2c.c
Expand Up @@ -179,8 +179,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;
}

Expand All @@ -194,11 +198,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;
}

Expand Down Expand Up @@ -235,8 +243,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;
}

Expand All @@ -251,11 +263,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;
}

Expand All @@ -264,8 +280,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;
}

Expand All @@ -280,11 +300,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;
}

Expand All @@ -294,8 +318,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,
Expand All @@ -304,20 +335,31 @@ 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,
struct snd_ctl_elem_value *ucontrol)
{
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;
}

Expand All @@ -327,6 +369,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 {
Expand All @@ -336,6 +380,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;
}

Expand Down

0 comments on commit 6dfc6b1

Please sign in to comment.