diff --git a/include/sound/core.h b/include/sound/core.h index daa91a46a16b..657b12e1e95b 100644 --- a/include/sound/core.h +++ b/include/sound/core.h @@ -84,6 +84,7 @@ struct snd_device { struct snd_refcount { atomic_t count; wait_queue_head_t waiter; + spinlock_t lock; }; void snd_refcount_init(struct snd_refcount *ref); diff --git a/sound/core/misc.c b/sound/core/misc.c index 066fb9ecdcdc..6fe199e76e83 100644 --- a/sound/core/misc.c +++ b/sound/core/misc.c @@ -183,11 +183,13 @@ void snd_refcount_init(struct snd_refcount *ref) { atomic_set(&ref->count, 0); init_waitqueue_head(&ref->waiter); + spin_lock_init(&ref->lock); } EXPORT_SYMBOL_GPL(snd_refcount_init); void snd_refcount_put(struct snd_refcount *ref) { + guard(spinlock_irqsave)(&ref->lock); if (atomic_dec_and_test(&ref->count)) wake_up(&ref->waiter); } @@ -195,6 +197,7 @@ EXPORT_SYMBOL_GPL(snd_refcount_put); void snd_refcount_sync(struct snd_refcount *ref) { - wait_event(ref->waiter, !atomic_read(&ref->count)); + guard(spinlock_irq)(&ref->lock); + wait_event_lock_irq(ref->waiter, !atomic_read(&ref->count), ref->lock); } EXPORT_SYMBOL_GPL(snd_refcount_sync);