Blob Blame History Raw
From 8748b850beccdbc87aa8776d63abd6b5628720c8 Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai@suse.de>
Date: Wed, 27 Mar 2019 16:42:51 +0100
Subject: [PATCH] ALSA: timer: Unify timer callback process code
Git-commit: 8748b850beccdbc87aa8776d63abd6b5628720c8
Patch-mainline: v5.2-rc1
References: bsc#1051510

The timer core has two almost identical code for processing callbacks:
once in snd_timer_interrupt() for fast callbacks and another in
snd_timer_tasklet() for delayed callbacks.  Let's unify them.

In the new version, the resolution is read from ti->resolution at each
call, and this must be fine; ti->resolution is set in the preparation
step in snd_timer_interrupt().

Signed-off-by: Takashi Iwai <tiwai@suse.de>

---
 sound/core/timer.c | 62 +++++++++++++++++++++++-------------------------------
 1 file changed, 26 insertions(+), 36 deletions(-)

diff --git a/sound/core/timer.c b/sound/core/timer.c
index 61a0cec6e1f6..fdcddfb756b4 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -720,29 +720,19 @@ static void snd_timer_reschedule(struct snd_timer * timer, unsigned long ticks_l
 	timer->sticks = ticks;
 }
 
-/*
- * timer tasklet
- *
- */
-static void snd_timer_tasklet(unsigned long arg)
+/* call callbacks in timer ack list */
+static void snd_timer_process_callbacks(struct snd_timer *timer,
+					struct list_head *head)
 {
-	struct snd_timer *timer = (struct snd_timer *) arg;
 	struct snd_timer_instance *ti;
-	struct list_head *p;
 	unsigned long resolution, ticks;
-	unsigned long flags;
 
-	if (timer->card && timer->card->shutdown)
-		return;
-
-	spin_lock_irqsave(&timer->lock, flags);
-	/* now process all callbacks */
-	while (!list_empty(&timer->sack_list_head)) {
-		p = timer->sack_list_head.next;		/* get first item */
-		ti = list_entry(p, struct snd_timer_instance, ack_list);
+	while (!list_empty(head)) {
+		ti = list_first_entry(head, struct snd_timer_instance,
+				      ack_list);
 
 		/* remove from ack_list and make empty */
-		list_del_init(p);
+		list_del_init(&ti->ack_list);
 
 		ticks = ti->pticks;
 		ti->pticks = 0;
@@ -755,6 +745,22 @@ static void snd_timer_tasklet(unsigned long arg)
 		spin_lock(&timer->lock);
 		ti->flags &= ~SNDRV_TIMER_IFLG_CALLBACK;
 	}
+}
+
+/*
+ * timer tasklet
+ *
+ */
+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)
+		return;
+
+	spin_lock_irqsave(&timer->lock, flags);
+	snd_timer_process_callbacks(timer, &timer->sack_list_head);
 	spin_unlock_irqrestore(&timer->lock, flags);
 }
 
@@ -767,8 +773,8 @@ static void snd_timer_tasklet(unsigned long arg)
 void snd_timer_interrupt(struct snd_timer * timer, unsigned long ticks_left)
 {
 	struct snd_timer_instance *ti, *ts, *tmp;
-	unsigned long resolution, ticks;
-	struct list_head *p, *ack_list_head;
+	unsigned long resolution;
+	struct list_head *ack_list_head;
 	unsigned long flags;
 	int use_tasklet = 0;
 
@@ -839,23 +845,7 @@ void snd_timer_interrupt(struct snd_timer * timer, unsigned long ticks_left)
 	}
 
 	/* now process all fast callbacks */
-	while (!list_empty(&timer->ack_list_head)) {
-		p = timer->ack_list_head.next;		/* get first item */
-		ti = list_entry(p, struct snd_timer_instance, ack_list);
-
-		/* remove from ack_list and make empty */
-		list_del_init(p);
-
-		ticks = ti->pticks;
-		ti->pticks = 0;
-
-		ti->flags |= SNDRV_TIMER_IFLG_CALLBACK;
-		spin_unlock(&timer->lock);
-		if (ti->callback)
-			ti->callback(ti, resolution, ticks);
-		spin_lock(&timer->lock);
-		ti->flags &= ~SNDRV_TIMER_IFLG_CALLBACK;
-	}
+	snd_timer_process_callbacks(timer, &timer->ack_list_head);
 
 	/* do we have any slow callbacks? */
 	use_tasklet = !list_empty(&timer->sack_list_head);
-- 
2.16.4