@@ -96,6 +96,7 @@ struct macaudio_snd_data {
9696 int speaker_sample_rate ;
9797 struct snd_kcontrol * speaker_sample_rate_kctl ;
9898
99+ struct mutex volume_lock_mutex ;
99100 bool speaker_volume_unlocked ;
100101 bool speaker_volume_was_locked ;
101102 struct snd_kcontrol * speaker_lock_kctl ;
@@ -284,10 +285,12 @@ static void macaudio_vlimit_update(struct macaudio_snd_data *ma)
284285
285286static void macaudio_vlimit_enable_timeout (struct macaudio_snd_data * ma )
286287{
287- if (ma -> speaker_lock_timeout_enabled )
288- return ;
288+ mutex_lock (& ma -> volume_lock_mutex );
289289
290- down_write (& ma -> card .snd_card -> controls_rwsem );
290+ if (ma -> speaker_lock_timeout_enabled ) {
291+ mutex_unlock (& ma -> volume_lock_mutex );
292+ return ;
293+ }
291294
292295 if (ma -> speaker_lock_remain > 0 ) {
293296 ma -> speaker_lock_timeout = ktime_add (ktime_get (), ma -> speaker_lock_remain );
@@ -298,18 +301,22 @@ static void macaudio_vlimit_enable_timeout(struct macaudio_snd_data *ma)
298301
299302 macaudio_vlimit_update (ma );
300303
301- up_write (& ma -> card .snd_card -> controls_rwsem );
302304 ma -> speaker_lock_timeout_enabled = true;
305+ mutex_unlock (& ma -> volume_lock_mutex );
303306}
304307
305308static void macaudio_vlimit_disable_timeout (struct macaudio_snd_data * ma )
306309{
307- ktime_t now = ktime_get ();
310+ ktime_t now ;
311+
312+ mutex_lock (& ma -> volume_lock_mutex );
308313
309- if (!ma -> speaker_lock_timeout_enabled )
314+ if (!ma -> speaker_lock_timeout_enabled ) {
315+ mutex_unlock (& ma -> volume_lock_mutex );
310316 return ;
317+ }
311318
312- down_write ( & ma -> card . snd_card -> controls_rwsem );
319+ now = ktime_get ( );
313320
314321 cancel_delayed_work (& ma -> lock_timeout_work );
315322
@@ -323,21 +330,22 @@ static void macaudio_vlimit_disable_timeout(struct macaudio_snd_data *ma)
323330
324331 macaudio_vlimit_update (ma );
325332
326- up_write (& ma -> card .snd_card -> controls_rwsem );
327333 ma -> speaker_lock_timeout_enabled = false;
334+
335+ mutex_unlock (& ma -> volume_lock_mutex );
328336}
329337
330338static void macaudio_vlimit_timeout_work (struct work_struct * wrk )
331339{
332340 struct macaudio_snd_data * ma = container_of (to_delayed_work (wrk ),
333341 struct macaudio_snd_data , lock_timeout_work );
334342
335- down_write (& ma -> card . snd_card -> controls_rwsem );
343+ mutex_lock (& ma -> volume_lock_mutex );
336344
337345 ma -> speaker_lock_remain = 0 ;
338346 macaudio_vlimit_update (ma );
339347
340- up_write (& ma -> card . snd_card -> controls_rwsem );
348+ mutex_unlock (& ma -> volume_lock_mutex );
341349}
342350
343351static void macaudio_vlimit_update_work (struct work_struct * wrk )
@@ -1095,7 +1103,9 @@ static int macaudio_late_probe(struct snd_soc_card *card)
10951103 ma -> speaker_sample_rate_kctl = snd_soc_card_get_kcontrol (card , "Speaker Sample Rate" );
10961104 ma -> speaker_lock_kctl = snd_soc_card_get_kcontrol (card , "Speaker Volume Unlock" );
10971105
1106+ mutex_lock (& ma -> volume_lock_mutex );
10981107 macaudio_vlimit_unlock (ma , false);
1108+ mutex_unlock (& ma -> volume_lock_mutex );
10991109
11001110 return 0 ;
11011111}
@@ -1336,6 +1346,8 @@ static int macaudio_slk_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_v
13361346 return - ETIMEDOUT ;
13371347 }
13381348
1349+ mutex_lock (& ma -> volume_lock_mutex );
1350+
13391351 cancel_delayed_work (& ma -> lock_timeout_work );
13401352
13411353 ma -> speaker_lock_remain = ms_to_ktime (SPEAKER_LOCK_TIMEOUT );
@@ -1348,6 +1360,8 @@ static int macaudio_slk_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_v
13481360 schedule_delayed_work (& ma -> lock_timeout_work , usecs_to_jiffies (ktime_to_us (ma -> speaker_lock_remain )));
13491361 }
13501362
1363+ mutex_unlock (& ma -> volume_lock_mutex );
1364+
13511365 return 0 ;
13521366}
13531367
@@ -1366,6 +1380,7 @@ static int macaudio_slk_lock(struct snd_kcontrol *kcontrol, struct snd_ctl_file
13661380 struct snd_soc_card * card = snd_kcontrol_chip (kcontrol );
13671381 struct macaudio_snd_data * ma = snd_soc_card_get_drvdata (card );
13681382
1383+ mutex_lock (& ma -> volume_lock_mutex );
13691384 ma -> speaker_lock_owner = owner ;
13701385 macaudio_vlimit_update (ma );
13711386
@@ -1377,6 +1392,8 @@ static int macaudio_slk_lock(struct snd_kcontrol *kcontrol, struct snd_ctl_file
13771392 */
13781393 ma -> speaker_volume_was_locked = false;
13791394
1395+ mutex_unlock (& ma -> volume_lock_mutex );
1396+
13801397 return 0 ;
13811398}
13821399
@@ -1469,6 +1486,7 @@ static int macaudio_snd_platform_probe(struct platform_device *pdev)
14691486 card = & data -> card ;
14701487 snd_soc_card_set_drvdata (card , data );
14711488 dev_set_drvdata (& pdev -> dev , data );
1489+ mutex_init (& data -> volume_lock_mutex );
14721490
14731491 card -> owner = THIS_MODULE ;
14741492 card -> driver_name = "macaudio" ;
0 commit comments