|
@@ -215,11 +215,13 @@ static void snd_timer_check_master(struct snd_timer_instance *master)
|
|
slave->slave_id == master->slave_id) {
|
|
slave->slave_id == master->slave_id) {
|
|
list_move_tail(&slave->open_list, &master->slave_list_head);
|
|
list_move_tail(&slave->open_list, &master->slave_list_head);
|
|
spin_lock_irq(&slave_active_lock);
|
|
spin_lock_irq(&slave_active_lock);
|
|
|
|
+ spin_lock(&master->timer->lock);
|
|
slave->master = master;
|
|
slave->master = master;
|
|
slave->timer = master->timer;
|
|
slave->timer = master->timer;
|
|
if (slave->flags & SNDRV_TIMER_IFLG_RUNNING)
|
|
if (slave->flags & SNDRV_TIMER_IFLG_RUNNING)
|
|
list_add_tail(&slave->active_list,
|
|
list_add_tail(&slave->active_list,
|
|
&master->slave_active_head);
|
|
&master->slave_active_head);
|
|
|
|
+ spin_unlock(&master->timer->lock);
|
|
spin_unlock_irq(&slave_active_lock);
|
|
spin_unlock_irq(&slave_active_lock);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -346,15 +348,18 @@ int snd_timer_close(struct snd_timer_instance *timeri)
|
|
timer->hw.close)
|
|
timer->hw.close)
|
|
timer->hw.close(timer);
|
|
timer->hw.close(timer);
|
|
/* remove slave links */
|
|
/* remove slave links */
|
|
|
|
+ spin_lock_irq(&slave_active_lock);
|
|
|
|
+ spin_lock(&timer->lock);
|
|
list_for_each_entry_safe(slave, tmp, &timeri->slave_list_head,
|
|
list_for_each_entry_safe(slave, tmp, &timeri->slave_list_head,
|
|
open_list) {
|
|
open_list) {
|
|
- spin_lock_irq(&slave_active_lock);
|
|
|
|
- _snd_timer_stop(slave, 1, SNDRV_TIMER_EVENT_RESOLUTION);
|
|
|
|
list_move_tail(&slave->open_list, &snd_timer_slave_list);
|
|
list_move_tail(&slave->open_list, &snd_timer_slave_list);
|
|
slave->master = NULL;
|
|
slave->master = NULL;
|
|
slave->timer = NULL;
|
|
slave->timer = NULL;
|
|
- spin_unlock_irq(&slave_active_lock);
|
|
|
|
|
|
+ list_del_init(&slave->ack_list);
|
|
|
|
+ list_del_init(&slave->active_list);
|
|
}
|
|
}
|
|
|
|
+ spin_unlock(&timer->lock);
|
|
|
|
+ spin_unlock_irq(&slave_active_lock);
|
|
mutex_unlock(®ister_mutex);
|
|
mutex_unlock(®ister_mutex);
|
|
}
|
|
}
|
|
out:
|
|
out:
|
|
@@ -441,9 +446,12 @@ static int snd_timer_start_slave(struct snd_timer_instance *timeri)
|
|
|
|
|
|
spin_lock_irqsave(&slave_active_lock, flags);
|
|
spin_lock_irqsave(&slave_active_lock, flags);
|
|
timeri->flags |= SNDRV_TIMER_IFLG_RUNNING;
|
|
timeri->flags |= SNDRV_TIMER_IFLG_RUNNING;
|
|
- if (timeri->master)
|
|
|
|
|
|
+ if (timeri->master && timeri->timer) {
|
|
|
|
+ spin_lock(&timeri->timer->lock);
|
|
list_add_tail(&timeri->active_list,
|
|
list_add_tail(&timeri->active_list,
|
|
&timeri->master->slave_active_head);
|
|
&timeri->master->slave_active_head);
|
|
|
|
+ spin_unlock(&timeri->timer->lock);
|
|
|
|
+ }
|
|
spin_unlock_irqrestore(&slave_active_lock, flags);
|
|
spin_unlock_irqrestore(&slave_active_lock, flags);
|
|
return 1; /* delayed start */
|
|
return 1; /* delayed start */
|
|
}
|
|
}
|
|
@@ -489,6 +497,8 @@ static int _snd_timer_stop(struct snd_timer_instance * timeri,
|
|
if (!keep_flag) {
|
|
if (!keep_flag) {
|
|
spin_lock_irqsave(&slave_active_lock, flags);
|
|
spin_lock_irqsave(&slave_active_lock, flags);
|
|
timeri->flags &= ~SNDRV_TIMER_IFLG_RUNNING;
|
|
timeri->flags &= ~SNDRV_TIMER_IFLG_RUNNING;
|
|
|
|
+ list_del_init(&timeri->ack_list);
|
|
|
|
+ list_del_init(&timeri->active_list);
|
|
spin_unlock_irqrestore(&slave_active_lock, flags);
|
|
spin_unlock_irqrestore(&slave_active_lock, flags);
|
|
}
|
|
}
|
|
goto __end;
|
|
goto __end;
|