aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/core/timer.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/sound/core/timer.c b/sound/core/timer.c
index 3810ee8f1205..4e8d7bfffff6 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -215,11 +215,13 @@ static void snd_timer_check_master(struct snd_timer_instance *master)
215 slave->slave_id == master->slave_id) { 215 slave->slave_id == master->slave_id) {
216 list_move_tail(&slave->open_list, &master->slave_list_head); 216 list_move_tail(&slave->open_list, &master->slave_list_head);
217 spin_lock_irq(&slave_active_lock); 217 spin_lock_irq(&slave_active_lock);
218 spin_lock(&master->timer->lock);
218 slave->master = master; 219 slave->master = master;
219 slave->timer = master->timer; 220 slave->timer = master->timer;
220 if (slave->flags & SNDRV_TIMER_IFLG_RUNNING) 221 if (slave->flags & SNDRV_TIMER_IFLG_RUNNING)
221 list_add_tail(&slave->active_list, 222 list_add_tail(&slave->active_list,
222 &master->slave_active_head); 223 &master->slave_active_head);
224 spin_unlock(&master->timer->lock);
223 spin_unlock_irq(&slave_active_lock); 225 spin_unlock_irq(&slave_active_lock);
224 } 226 }
225 } 227 }
@@ -346,15 +348,18 @@ int snd_timer_close(struct snd_timer_instance *timeri)
346 timer->hw.close) 348 timer->hw.close)
347 timer->hw.close(timer); 349 timer->hw.close(timer);
348 /* remove slave links */ 350 /* remove slave links */
351 spin_lock_irq(&slave_active_lock);
352 spin_lock(&timer->lock);
349 list_for_each_entry_safe(slave, tmp, &timeri->slave_list_head, 353 list_for_each_entry_safe(slave, tmp, &timeri->slave_list_head,
350 open_list) { 354 open_list) {
351 spin_lock_irq(&slave_active_lock);
352 _snd_timer_stop(slave, 1, SNDRV_TIMER_EVENT_RESOLUTION);
353 list_move_tail(&slave->open_list, &snd_timer_slave_list); 355 list_move_tail(&slave->open_list, &snd_timer_slave_list);
354 slave->master = NULL; 356 slave->master = NULL;
355 slave->timer = NULL; 357 slave->timer = NULL;
356 spin_unlock_irq(&slave_active_lock); 358 list_del_init(&slave->ack_list);
359 list_del_init(&slave->active_list);
357 } 360 }
361 spin_unlock(&timer->lock);
362 spin_unlock_irq(&slave_active_lock);
358 mutex_unlock(&register_mutex); 363 mutex_unlock(&register_mutex);
359 } 364 }
360 out: 365 out:
@@ -441,9 +446,12 @@ static int snd_timer_start_slave(struct snd_timer_instance *timeri)
441 446
442 spin_lock_irqsave(&slave_active_lock, flags); 447 spin_lock_irqsave(&slave_active_lock, flags);
443 timeri->flags |= SNDRV_TIMER_IFLG_RUNNING; 448 timeri->flags |= SNDRV_TIMER_IFLG_RUNNING;
444 if (timeri->master) 449 if (timeri->master && timeri->timer) {
450 spin_lock(&timeri->timer->lock);
445 list_add_tail(&timeri->active_list, 451 list_add_tail(&timeri->active_list,
446 &timeri->master->slave_active_head); 452 &timeri->master->slave_active_head);
453 spin_unlock(&timeri->timer->lock);
454 }
447 spin_unlock_irqrestore(&slave_active_lock, flags); 455 spin_unlock_irqrestore(&slave_active_lock, flags);
448 return 1; /* delayed start */ 456 return 1; /* delayed start */
449} 457}
@@ -489,6 +497,8 @@ static int _snd_timer_stop(struct snd_timer_instance * timeri,
489 if (!keep_flag) { 497 if (!keep_flag) {
490 spin_lock_irqsave(&slave_active_lock, flags); 498 spin_lock_irqsave(&slave_active_lock, flags);
491 timeri->flags &= ~SNDRV_TIMER_IFLG_RUNNING; 499 timeri->flags &= ~SNDRV_TIMER_IFLG_RUNNING;
500 list_del_init(&timeri->ack_list);
501 list_del_init(&timeri->active_list);
492 spin_unlock_irqrestore(&slave_active_lock, flags); 502 spin_unlock_irqrestore(&slave_active_lock, flags);
493 } 503 }
494 goto __end; 504 goto __end;