summaryrefslogtreecommitdiff
path: root/include/sound/core.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/sound/core.h')
-rw-r--r--include/sound/core.h42
1 files changed, 34 insertions, 8 deletions
diff --git a/include/sound/core.h b/include/sound/core.h
index 64327e971122..2ca24ac7e37f 100644
--- a/include/sound/core.h
+++ b/include/sound/core.h
@@ -75,6 +75,27 @@ struct snd_device {
#define snd_device(n) list_entry(n, struct snd_device, list)
+/*
+ * A simple reference counter with a wait queue;
+ * typically used for usage counts, and you can synchronize at finishing
+ * via snd_refcount_sync(), which is woken up when the refcount reaches to
+ * zero again.
+ */
+struct snd_refcount {
+ atomic_t count;
+ wait_queue_head_t waiter;
+};
+
+void snd_refcount_init(struct snd_refcount *ref);
+
+static inline void snd_refcount_get(struct snd_refcount *ref)
+{
+ atomic_inc(&ref->count);
+}
+
+void snd_refcount_put(struct snd_refcount *ref);
+void snd_refcount_sync(struct snd_refcount *ref);
+
/* main structure for soundcard */
struct snd_card {
@@ -87,8 +108,8 @@ struct snd_card {
char longname[80]; /* name of this soundcard */
char irq_descr[32]; /* Interrupt description */
char mixername[80]; /* mixer name */
- char components[128]; /* card components delimited with
- space */
+ char *components; /* card components, space-delimited */
+ unsigned int components_alloc_size; /* current allocation size of components */
struct module *module; /* top-level module */
void *private_data; /* private data for soundcard */
@@ -133,18 +154,22 @@ struct snd_card {
#ifdef CONFIG_SND_DEBUG
struct dentry *debugfs_root; /* debugfs root for card */
#endif
+#ifdef CONFIG_SND_CTL_DEBUG
+ struct snd_ctl_elem_value *value_buf; /* buffer for kctl->put() verification */
+#endif
#ifdef CONFIG_PM
unsigned int power_state; /* power state */
- atomic_t power_ref;
wait_queue_head_t power_sleep;
- wait_queue_head_t power_ref_sleep;
+ struct snd_refcount power_ref;
#endif
#if IS_ENABLED(CONFIG_SND_MIXER_OSS)
struct snd_mixer_oss *mixer_oss;
int mixer_oss_change_count;
#endif
+
+ unsigned char private_data_area[] __aligned(__alignof__(unsigned long long));
};
#define dev_to_snd_card(p) container_of(p, struct snd_card, card_dev)
@@ -171,7 +196,7 @@ static inline void snd_power_change_state(struct snd_card *card, unsigned int st
*/
static inline void snd_power_ref(struct snd_card *card)
{
- atomic_inc(&card->power_ref);
+ snd_refcount_get(&card->power_ref);
}
/**
@@ -180,8 +205,7 @@ static inline void snd_power_ref(struct snd_card *card)
*/
static inline void snd_power_unref(struct snd_card *card)
{
- if (atomic_dec_and_test(&card->power_ref))
- wake_up(&card->power_ref_sleep);
+ snd_refcount_put(&card->power_ref);
}
/**
@@ -193,7 +217,7 @@ static inline void snd_power_unref(struct snd_card *card)
*/
static inline void snd_power_sync_ref(struct snd_card *card)
{
- wait_event(card->power_ref_sleep, !atomic_read(&card->power_ref));
+ snd_refcount_sync(&card->power_ref);
}
/* init.c */
@@ -314,6 +338,8 @@ static inline void snd_card_unref(struct snd_card *card)
put_device(&card->card_dev);
}
+DEFINE_FREE(snd_card_unref, struct snd_card *, if (_T) snd_card_unref(_T))
+
#define snd_card_set_dev(card, devptr) ((card)->dev = (devptr))
/* device.c */