From 7bb4a8a2cc9382da720b46988bc976ebccaa49fd Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 27 Mar 2019 16:51:58 +0100 Subject: ALSA: timer: Make sure to clear pending ack list When a card is under disconnection, we bail out immediately at each timer interrupt or tasklet. This might leave some items left in ack list. For a better integration of the upcoming change to check ack_list emptiness, clear out the whole list upon the emergency exit route. Signed-off-by: Takashi Iwai --- sound/core/timer.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'sound/core/timer.c') diff --git a/sound/core/timer.c b/sound/core/timer.c index fdcddfb756b4..107d8ebeeb2e 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c @@ -747,6 +747,18 @@ static void snd_timer_process_callbacks(struct snd_timer *timer, } } +/* clear pending instances from ack list */ +static void snd_timer_clear_callbacks(struct snd_timer *timer, + struct list_head *head) +{ + unsigned long flags; + + spin_lock_irqsave(&timer->lock, flags); + while (!list_empty(head)) + list_del_init(head->next); + spin_unlock_irqrestore(&timer->lock, flags); +} + /* * timer tasklet * @@ -756,8 +768,10 @@ static void snd_timer_tasklet(unsigned long arg) struct snd_timer *timer = (struct snd_timer *) arg; unsigned long flags; - if (timer->card && timer->card->shutdown) + if (timer->card && timer->card->shutdown) { + snd_timer_clear_callbacks(timer, &timer->sack_list_head); return; + } spin_lock_irqsave(&timer->lock, flags); snd_timer_process_callbacks(timer, &timer->sack_list_head); @@ -781,8 +795,10 @@ void snd_timer_interrupt(struct snd_timer * timer, unsigned long ticks_left) if (timer == NULL) return; - if (timer->card && timer->card->shutdown) + if (timer->card && timer->card->shutdown) { + snd_timer_clear_callbacks(timer, &timer->ack_list_head); return; + } spin_lock_irqsave(&timer->lock, flags); -- cgit