summaryrefslogtreecommitdiffstats
path: root/sound/core/seq/seq_timer.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/core/seq/seq_timer.c')
-rw-r--r--sound/core/seq/seq_timer.c32
1 files changed, 21 insertions, 11 deletions
diff --git a/sound/core/seq/seq_timer.c b/sound/core/seq/seq_timer.c
index 161f3170bd7e..be59b59c9be4 100644
--- a/sound/core/seq/seq_timer.c
+++ b/sound/core/seq/seq_timer.c
@@ -272,7 +272,13 @@ int snd_seq_timer_open(struct snd_seq_queue *q)
return -EINVAL;
if (tmr->alsa_id.dev_class != SNDRV_TIMER_CLASS_SLAVE)
tmr->alsa_id.dev_sclass = SNDRV_TIMER_SCLASS_SEQUENCER;
- err = snd_timer_open(&t, str, &tmr->alsa_id, q->queue);
+ t = snd_timer_instance_new(str);
+ if (!t)
+ return -ENOMEM;
+ t->callback = snd_seq_timer_interrupt;
+ t->callback_data = q;
+ t->flags |= SNDRV_TIMER_IFLG_AUTO;
+ err = snd_timer_open(t, &tmr->alsa_id, q->queue);
if (err < 0 && tmr->alsa_id.dev_class != SNDRV_TIMER_CLASS_SLAVE) {
if (tmr->alsa_id.dev_class != SNDRV_TIMER_CLASS_GLOBAL ||
tmr->alsa_id.device != SNDRV_TIMER_GLOBAL_SYSTEM) {
@@ -282,16 +288,14 @@ int snd_seq_timer_open(struct snd_seq_queue *q)
tid.dev_sclass = SNDRV_TIMER_SCLASS_SEQUENCER;
tid.card = -1;
tid.device = SNDRV_TIMER_GLOBAL_SYSTEM;
- err = snd_timer_open(&t, str, &tid, q->queue);
+ err = snd_timer_open(t, &tid, q->queue);
}
}
if (err < 0) {
pr_err("ALSA: seq fatal error: cannot create timer (%i)\n", err);
+ snd_timer_instance_free(t);
return err;
}
- t->callback = snd_seq_timer_interrupt;
- t->callback_data = q;
- t->flags |= SNDRV_TIMER_IFLG_AUTO;
spin_lock_irq(&tmr->lock);
tmr->timeri = t;
spin_unlock_irq(&tmr->lock);
@@ -310,8 +314,10 @@ int snd_seq_timer_close(struct snd_seq_queue *q)
t = tmr->timeri;
tmr->timeri = NULL;
spin_unlock_irq(&tmr->lock);
- if (t)
+ if (t) {
snd_timer_close(t);
+ snd_timer_instance_free(t);
+ }
return 0;
}
@@ -465,15 +471,19 @@ void snd_seq_info_timer_read(struct snd_info_entry *entry,
q = queueptr(idx);
if (q == NULL)
continue;
- if ((tmr = q->timer) == NULL ||
- (ti = tmr->timeri) == NULL) {
- queuefree(q);
- continue;
- }
+ mutex_lock(&q->timer_mutex);
+ tmr = q->timer;
+ if (!tmr)
+ goto unlock;
+ ti = tmr->timeri;
+ if (!ti)
+ goto unlock;
snd_iprintf(buffer, "Timer for queue %i : %s\n", q->queue, ti->timer->name);
resolution = snd_timer_resolution(ti) * tmr->ticks;
snd_iprintf(buffer, " Period time : %lu.%09lu\n", resolution / 1000000000, resolution % 1000000000);
snd_iprintf(buffer, " Skew : %u / %u\n", tmr->skew, tmr->skew_base);
+unlock:
+ mutex_unlock(&q->timer_mutex);
queuefree(q);
}
}