Skip to content

Commit 15bc306

Browse files
soyersoyertiwai
authored andcommitted
ALSA: hda/tas2781: add locks to kcontrols
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: [email protected] Signed-off-by: Gergo Koteles <[email protected]> Message-ID: <e35b867f6fe5fa1f869dd658a0a1f2118b737f57.1711469583.git.soyer@irl.hu> Signed-off-by: Takashi Iwai <[email protected]>
1 parent ae065d0 commit 15bc306

File tree

1 file changed

+48
-2
lines changed

1 file changed

+48
-2
lines changed

sound/pci/hda/tas2781_hda_i2c.c

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,8 +185,12 @@ static int tasdevice_get_profile_id(struct snd_kcontrol *kcontrol,
185185
{
186186
struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol);
187187

188+
mutex_lock(&tas_priv->codec_lock);
189+
188190
ucontrol->value.integer.value[0] = tas_priv->rcabin.profile_cfg_id;
189191

192+
mutex_unlock(&tas_priv->codec_lock);
193+
190194
return 0;
191195
}
192196

@@ -200,11 +204,15 @@ static int tasdevice_set_profile_id(struct snd_kcontrol *kcontrol,
200204

201205
val = clamp(nr_profile, 0, max);
202206

207+
mutex_lock(&tas_priv->codec_lock);
208+
203209
if (tas_priv->rcabin.profile_cfg_id != val) {
204210
tas_priv->rcabin.profile_cfg_id = val;
205211
ret = 1;
206212
}
207213

214+
mutex_unlock(&tas_priv->codec_lock);
215+
208216
return ret;
209217
}
210218

@@ -241,8 +249,12 @@ static int tasdevice_program_get(struct snd_kcontrol *kcontrol,
241249
{
242250
struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol);
243251

252+
mutex_lock(&tas_priv->codec_lock);
253+
244254
ucontrol->value.integer.value[0] = tas_priv->cur_prog;
245255

256+
mutex_unlock(&tas_priv->codec_lock);
257+
246258
return 0;
247259
}
248260

@@ -257,11 +269,15 @@ static int tasdevice_program_put(struct snd_kcontrol *kcontrol,
257269

258270
val = clamp(nr_program, 0, max);
259271

272+
mutex_lock(&tas_priv->codec_lock);
273+
260274
if (tas_priv->cur_prog != val) {
261275
tas_priv->cur_prog = val;
262276
ret = 1;
263277
}
264278

279+
mutex_unlock(&tas_priv->codec_lock);
280+
265281
return ret;
266282
}
267283

@@ -270,8 +286,12 @@ static int tasdevice_config_get(struct snd_kcontrol *kcontrol,
270286
{
271287
struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol);
272288

289+
mutex_lock(&tas_priv->codec_lock);
290+
273291
ucontrol->value.integer.value[0] = tas_priv->cur_conf;
274292

293+
mutex_unlock(&tas_priv->codec_lock);
294+
275295
return 0;
276296
}
277297

@@ -286,11 +306,15 @@ static int tasdevice_config_put(struct snd_kcontrol *kcontrol,
286306

287307
val = clamp(nr_config, 0, max);
288308

309+
mutex_lock(&tas_priv->codec_lock);
310+
289311
if (tas_priv->cur_conf != val) {
290312
tas_priv->cur_conf = val;
291313
ret = 1;
292314
}
293315

316+
mutex_unlock(&tas_priv->codec_lock);
317+
294318
return ret;
295319
}
296320

@@ -300,8 +324,15 @@ static int tas2781_amp_getvol(struct snd_kcontrol *kcontrol,
300324
struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol);
301325
struct soc_mixer_control *mc =
302326
(struct soc_mixer_control *)kcontrol->private_value;
327+
int ret;
328+
329+
mutex_lock(&tas_priv->codec_lock);
330+
331+
ret = tasdevice_amp_getvol(tas_priv, ucontrol, mc);
332+
333+
mutex_unlock(&tas_priv->codec_lock);
303334

304-
return tasdevice_amp_getvol(tas_priv, ucontrol, mc);
335+
return ret;
305336
}
306337

307338
static int tas2781_amp_putvol(struct snd_kcontrol *kcontrol,
@@ -310,20 +341,31 @@ static int tas2781_amp_putvol(struct snd_kcontrol *kcontrol,
310341
struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol);
311342
struct soc_mixer_control *mc =
312343
(struct soc_mixer_control *)kcontrol->private_value;
344+
int ret;
345+
346+
mutex_lock(&tas_priv->codec_lock);
313347

314348
/* The check of the given value is in tasdevice_amp_putvol. */
315-
return tasdevice_amp_putvol(tas_priv, ucontrol, mc);
349+
ret = tasdevice_amp_putvol(tas_priv, ucontrol, mc);
350+
351+
mutex_unlock(&tas_priv->codec_lock);
352+
353+
return ret;
316354
}
317355

318356
static int tas2781_force_fwload_get(struct snd_kcontrol *kcontrol,
319357
struct snd_ctl_elem_value *ucontrol)
320358
{
321359
struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol);
322360

361+
mutex_lock(&tas_priv->codec_lock);
362+
323363
ucontrol->value.integer.value[0] = (int)tas_priv->force_fwload_status;
324364
dev_dbg(tas_priv->dev, "%s : Force FWload %s\n", __func__,
325365
tas_priv->force_fwload_status ? "ON" : "OFF");
326366

367+
mutex_unlock(&tas_priv->codec_lock);
368+
327369
return 0;
328370
}
329371

@@ -333,6 +375,8 @@ static int tas2781_force_fwload_put(struct snd_kcontrol *kcontrol,
333375
struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol);
334376
bool change, val = (bool)ucontrol->value.integer.value[0];
335377

378+
mutex_lock(&tas_priv->codec_lock);
379+
336380
if (tas_priv->force_fwload_status == val)
337381
change = false;
338382
else {
@@ -342,6 +386,8 @@ static int tas2781_force_fwload_put(struct snd_kcontrol *kcontrol,
342386
dev_dbg(tas_priv->dev, "%s : Force FWload %s\n", __func__,
343387
tas_priv->force_fwload_status ? "ON" : "OFF");
344388

389+
mutex_unlock(&tas_priv->codec_lock);
390+
345391
return change;
346392
}
347393

0 commit comments

Comments
 (0)