All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH RFC 0/3] Embed card device into struct snd_card
@ 2014-02-12 11:20 Takashi Iwai
  2014-02-12 11:20 ` [PATCH 1/3] ALSA: " Takashi Iwai
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Takashi Iwai @ 2014-02-12 11:20 UTC (permalink / raw)
  To: alsa-devel

The third batch is a more intensive change; now struct device for
card-object is embedded in snd_card struct.  This makes the presence
of the device object presistent, which can be later referred by
other devices at the object creation time.

Also, along with this change, the refcounting of the card object
was changed just to use the standard device refcount.  This needs
to move the destructor into the device release callback.

Onre more batch will follow.

Takashi

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/3] ALSA: Embed card device into struct snd_card
  2014-02-12 11:20 [PATCH RFC 0/3] Embed card device into struct snd_card Takashi Iwai
@ 2014-02-12 11:20 ` Takashi Iwai
  2014-02-12 11:20 ` [PATCH 2/3] ALSA: Use static groups for id and number card sysfs attr files Takashi Iwai
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Takashi Iwai @ 2014-02-12 11:20 UTC (permalink / raw)
  To: alsa-devel

As prepared in the previous patch, we are ready to create a device
struct for the card object in snd_card_create() now.  This patch
changes the scheme from the old style to:

- embed a device struct for the card object into snd_card struct,
- initialize the card device in snd_card_create() (but not register),
- registration is done in snd_card_register() via device_add()

The actual card device is stored in card->card_dev.  The card->dev
pointer is kept unchanged and pointing to the parent device as before
for compatibility reason.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 include/sound/core.h | 10 ++++++----
 sound/core/init.c    | 54 ++++++++++++++++++++++++++++++++++------------------
 2 files changed, 41 insertions(+), 23 deletions(-)

diff --git a/include/sound/core.h b/include/sound/core.h
index fb05573215d3..f072e596f21a 100644
--- a/include/sound/core.h
+++ b/include/sound/core.h
@@ -22,6 +22,7 @@
  *
  */
 
+#include <linux/device.h>
 #include <linux/sched.h>		/* wake_up() */
 #include <linux/mutex.h>		/* struct mutex */
 #include <linux/rwsem.h>		/* struct rw_semaphore */
@@ -41,8 +42,6 @@
 /* forward declarations */
 struct pci_dev;
 struct module;
-struct device;
-struct device_attribute;
 
 /* device allocation stuff */
 
@@ -131,7 +130,8 @@ struct snd_card {
 	wait_queue_head_t shutdown_sleep;
 	atomic_t refcount;		/* refcount for disconnection */
 	struct device *dev;		/* device assigned to this card */
-	struct device *card_dev;	/* cardX object for sysfs */
+	struct device card_dev;		/* cardX object for sysfs */
+	bool registered;		/* card_dev is registered? */
 
 #ifdef CONFIG_PM
 	unsigned int power_state;	/* power state */
@@ -145,6 +145,8 @@ struct snd_card {
 #endif
 };
 
+#define dev_to_snd_card(p)	container_of(p, struct snd_card, card_dev)
+
 #ifdef CONFIG_PM
 static inline void snd_power_lock(struct snd_card *card)
 {
@@ -193,7 +195,7 @@ struct snd_minor {
 /* return a device pointer linked to each sound device as a parent */
 static inline struct device *snd_card_get_device_link(struct snd_card *card)
 {
-	return card ? card->card_dev : NULL;
+	return card ? &card->card_dev : NULL;
 }
 
 /* sound.c */
diff --git a/sound/core/init.c b/sound/core/init.c
index 0115034914c9..2c0301811828 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -156,6 +156,13 @@ static int get_slot_from_bitmask(int mask, int (*check)(struct module *, int),
 	return mask; /* unchanged */
 }
 
+static int snd_card_do_free(struct snd_card *card);
+
+static void release_card_device(struct device *dev)
+{
+	snd_card_do_free(dev_to_snd_card(dev));
+}
+
 /**
  *  snd_card_new - create and initialize a soundcard structure
  *  @parent: the parent device object
@@ -189,6 +196,8 @@ int snd_card_new(struct device *parent, int idx, const char *xid,
 	card = kzalloc(sizeof(*card) + extra_size, GFP_KERNEL);
 	if (!card)
 		return -ENOMEM;
+	if (extra_size > 0)
+		card->private_data = (char *)card + sizeof(struct snd_card);
 	if (xid)
 		strlcpy(card->id, xid, sizeof(card->id));
 	err = 0;
@@ -208,7 +217,8 @@ int snd_card_new(struct device *parent, int idx, const char *xid,
 		mutex_unlock(&snd_card_mutex);
 		snd_printk(KERN_ERR "cannot find the slot for index %d (range 0-%i), error: %d\n",
 			 idx, snd_ecards_limit - 1, err);
-		goto __error;
+		kfree(card);
+		return err;
 	}
 	set_bit(idx, snd_cards_lock);		/* lock it */
 	if (idx >= snd_ecards_limit)
@@ -230,6 +240,15 @@ int snd_card_new(struct device *parent, int idx, const char *xid,
 	mutex_init(&card->power_lock);
 	init_waitqueue_head(&card->power_sleep);
 #endif
+
+	device_initialize(&card->card_dev);
+	card->card_dev.parent = parent;
+	card->card_dev.class = sound_class;
+	card->card_dev.release = release_card_device;
+	err = kobject_set_name(&card->card_dev.kobj, "card%d", idx);
+	if (err < 0)
+		goto __error;
+
 	/* the control interface cannot be accessed from the user space until */
 	/* snd_cards_bitmask and snd_cards are set with snd_card_register */
 	err = snd_ctl_create(card);
@@ -242,15 +261,13 @@ int snd_card_new(struct device *parent, int idx, const char *xid,
 		snd_printk(KERN_ERR "unable to create card info\n");
 		goto __error_ctl;
 	}
-	if (extra_size > 0)
-		card->private_data = (char *)card + sizeof(struct snd_card);
 	*card_ret = card;
 	return 0;
 
       __error_ctl:
 	snd_device_free_all(card);
       __error:
-	kfree(card);
+	put_device(&card->card_dev);
   	return err;
 }
 EXPORT_SYMBOL(snd_card_new);
@@ -407,9 +424,9 @@ int snd_card_disconnect(struct snd_card *card)
 		snd_printk(KERN_ERR "not all devices for card %i can be disconnected\n", card->number);
 
 	snd_info_card_disconnect(card);
-	if (card->card_dev) {
-		device_unregister(card->card_dev);
-		card->card_dev = NULL;
+	if (card->registered) {
+		device_del(&card->card_dev);
+		card->registered = false;
 	}
 #ifdef CONFIG_PM
 	wake_up(&card->power_sleep);
@@ -463,7 +480,7 @@ void snd_card_unref(struct snd_card *card)
 	if (atomic_dec_and_test(&card->refcount)) {
 		wake_up(&card->shutdown_sleep);
 		if (card->free_on_last_close)
-			snd_card_do_free(card);
+			put_device(&card->card_dev);
 	}
 }
 EXPORT_SYMBOL(snd_card_unref);
@@ -481,7 +498,7 @@ int snd_card_free_when_closed(struct snd_card *card)
 
 	card->free_on_last_close = 1;
 	if (atomic_dec_and_test(&card->refcount))
-		snd_card_do_free(card);
+		put_device(&card->card_dev);
 	return 0;
 }
 
@@ -495,7 +512,7 @@ int snd_card_free(struct snd_card *card)
 
 	/* wait, until all devices are ready for the free operation */
 	wait_event(card->shutdown_sleep, !atomic_read(&card->refcount));
-	snd_card_do_free(card);
+	put_device(&card->card_dev);
 	return 0;
 }
 
@@ -686,12 +703,11 @@ int snd_card_register(struct snd_card *card)
 	if (snd_BUG_ON(!card))
 		return -EINVAL;
 
-	if (!card->card_dev) {
-		card->card_dev = device_create(sound_class, card->dev,
-					       MKDEV(0, 0), card,
-					       "card%i", card->number);
-		if (IS_ERR(card->card_dev))
-			card->card_dev = NULL;
+	if (!card->registered) {
+		err = device_add(&card->card_dev);
+		if (err < 0)
+			return err;
+		card->registered = true;
 	}
 
 	if ((err = snd_device_register_all(card)) < 0)
@@ -721,11 +737,11 @@ int snd_card_register(struct snd_card *card)
 	if (snd_mixer_oss_notify_callback)
 		snd_mixer_oss_notify_callback(card, SND_MIXER_OSS_NOTIFY_REGISTER);
 #endif
-	if (card->card_dev) {
-		err = device_create_file(card->card_dev, &card_id_attrs);
+	if (card->registered) {
+		err = device_create_file(&card->card_dev, &card_id_attrs);
 		if (err < 0)
 			return err;
-		err = device_create_file(card->card_dev, &card_number_attrs);
+		err = device_create_file(&card->card_dev, &card_number_attrs);
 		if (err < 0)
 			return err;
 	}
-- 
1.8.5.2

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 2/3] ALSA: Use static groups for id and number card sysfs attr files
  2014-02-12 11:20 [PATCH RFC 0/3] Embed card device into struct snd_card Takashi Iwai
  2014-02-12 11:20 ` [PATCH 1/3] ALSA: " Takashi Iwai
@ 2014-02-12 11:20 ` Takashi Iwai
  2014-02-12 11:20 ` [PATCH 3/3] ALSA: Use standard device refcount for card accounting Takashi Iwai
  2014-02-14 12:00 ` [PATCH RFC 0/3] Embed card device into struct snd_card Takashi Iwai
  3 siblings, 0 replies; 5+ messages in thread
From: Takashi Iwai @ 2014-02-12 11:20 UTC (permalink / raw)
  To: alsa-devel

... instead of calling device_create_file() manually.
No functional change.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 sound/core/init.c | 32 +++++++++++++++++++-------------
 1 file changed, 19 insertions(+), 13 deletions(-)

diff --git a/sound/core/init.c b/sound/core/init.c
index 2c0301811828..46a9e7cb1c04 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -157,6 +157,7 @@ static int get_slot_from_bitmask(int mask, int (*check)(struct module *, int),
 }
 
 static int snd_card_do_free(struct snd_card *card);
+static const struct attribute_group *card_dev_attr_groups[];
 
 static void release_card_device(struct device *dev)
 {
@@ -245,6 +246,7 @@ int snd_card_new(struct device *parent, int idx, const char *xid,
 	card->card_dev.parent = parent;
 	card->card_dev.class = sound_class;
 	card->card_dev.release = release_card_device;
+	card->card_dev.groups = card_dev_attr_groups;
 	err = kobject_set_name(&card->card_dev.kobj, "card%d", idx);
 	if (err < 0)
 		goto __error;
@@ -671,8 +673,7 @@ card_id_store_attr(struct device *dev, struct device_attribute *attr,
 	return count;
 }
 
-static struct device_attribute card_id_attrs =
-	__ATTR(id, S_IRUGO | S_IWUSR, card_id_show_attr, card_id_store_attr);
+static DEVICE_ATTR(id, S_IRUGO | S_IWUSR, card_id_show_attr, card_id_store_attr);
 
 static ssize_t
 card_number_show_attr(struct device *dev,
@@ -682,8 +683,22 @@ card_number_show_attr(struct device *dev,
 	return snprintf(buf, PAGE_SIZE, "%i\n", card ? card->number : -1);
 }
 
-static struct device_attribute card_number_attrs =
-	__ATTR(number, S_IRUGO, card_number_show_attr, NULL);
+static DEVICE_ATTR(number, S_IRUGO, card_number_show_attr, NULL);
+
+static struct attribute *card_dev_attrs[] = {
+	&dev_attr_id.attr,
+	&dev_attr_number.attr,
+	NULL
+};
+
+static struct attribute_group card_dev_attr_group = {
+	.attrs	= card_dev_attrs,
+};
+
+static const struct attribute_group *card_dev_attr_groups[] = {
+	&card_dev_attr_group,
+	NULL
+};
 
 /**
  *  snd_card_register - register the soundcard
@@ -737,15 +752,6 @@ int snd_card_register(struct snd_card *card)
 	if (snd_mixer_oss_notify_callback)
 		snd_mixer_oss_notify_callback(card, SND_MIXER_OSS_NOTIFY_REGISTER);
 #endif
-	if (card->registered) {
-		err = device_create_file(&card->card_dev, &card_id_attrs);
-		if (err < 0)
-			return err;
-		err = device_create_file(&card->card_dev, &card_number_attrs);
-		if (err < 0)
-			return err;
-	}
-
 	return 0;
 }
 
-- 
1.8.5.2

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 3/3] ALSA: Use standard device refcount for card accounting
  2014-02-12 11:20 [PATCH RFC 0/3] Embed card device into struct snd_card Takashi Iwai
  2014-02-12 11:20 ` [PATCH 1/3] ALSA: " Takashi Iwai
  2014-02-12 11:20 ` [PATCH 2/3] ALSA: Use static groups for id and number card sysfs attr files Takashi Iwai
@ 2014-02-12 11:20 ` Takashi Iwai
  2014-02-14 12:00 ` [PATCH RFC 0/3] Embed card device into struct snd_card Takashi Iwai
  3 siblings, 0 replies; 5+ messages in thread
From: Takashi Iwai @ 2014-02-12 11:20 UTC (permalink / raw)
  To: alsa-devel

Drop the own refcount but use the standard device refcounting via
get_device() and put_device().  Introduce a new completion to snd_card
instead of the wait queue for syncing the last release, which is used
in snd_card_free().

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 include/sound/core.h   |  7 +++----
 sound/core/init.c      | 53 ++++++++++++++------------------------------------
 sound/core/sound.c     |  2 +-
 sound/core/sound_oss.c |  2 +-
 4 files changed, 20 insertions(+), 44 deletions(-)

diff --git a/include/sound/core.h b/include/sound/core.h
index f072e596f21a..f410a49862fd 100644
--- a/include/sound/core.h
+++ b/include/sound/core.h
@@ -42,6 +42,7 @@
 /* forward declarations */
 struct pci_dev;
 struct module;
+struct completion;
 
 /* device allocation stuff */
 
@@ -126,9 +127,7 @@ struct snd_card {
 								state */
 	spinlock_t files_lock;		/* lock the files for this card */
 	int shutdown;			/* this card is going down */
-	int free_on_last_close;		/* free in context of file_release */
-	wait_queue_head_t shutdown_sleep;
-	atomic_t refcount;		/* refcount for disconnection */
+	struct completion *release_completion;
 	struct device *dev;		/* device assigned to this card */
 	struct device card_dev;		/* cardX object for sysfs */
 	bool registered;		/* card_dev is registered? */
@@ -302,7 +301,7 @@ int snd_card_info_done(void);
 int snd_component_add(struct snd_card *card, const char *component);
 int snd_card_file_add(struct snd_card *card, struct file *file);
 int snd_card_file_remove(struct snd_card *card, struct file *file);
-void snd_card_unref(struct snd_card *card);
+#define snd_card_unref(card)	put_device(&(card)->card_dev)
 
 #define snd_card_set_dev(card, devptr) ((card)->dev = (devptr))
 
diff --git a/sound/core/init.c b/sound/core/init.c
index 46a9e7cb1c04..3fdb4e2ce5ea 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -28,6 +28,7 @@
 #include <linux/time.h>
 #include <linux/ctype.h>
 #include <linux/pm.h>
+#include <linux/completion.h>
 
 #include <sound/core.h>
 #include <sound/control.h>
@@ -235,8 +236,6 @@ int snd_card_new(struct device *parent, int idx, const char *xid,
 	INIT_LIST_HEAD(&card->ctl_files);
 	spin_lock_init(&card->files_lock);
 	INIT_LIST_HEAD(&card->files_list);
-	init_waitqueue_head(&card->shutdown_sleep);
-	atomic_set(&card->refcount, 0);
 #ifdef CONFIG_PM
 	mutex_init(&card->power_lock);
 	init_waitqueue_head(&card->power_sleep);
@@ -466,58 +465,36 @@ static int snd_card_do_free(struct snd_card *card)
 		snd_printk(KERN_WARNING "unable to free card info\n");
 		/* Not fatal error */
 	}
+	if (card->release_completion)
+		complete(card->release_completion);
 	kfree(card);
 	return 0;
 }
 
-/**
- * snd_card_unref - release the reference counter
- * @card: the card instance
- *
- * Decrements the reference counter.  When it reaches to zero, wake up
- * the sleeper and call the destructor if needed.
- */
-void snd_card_unref(struct snd_card *card)
-{
-	if (atomic_dec_and_test(&card->refcount)) {
-		wake_up(&card->shutdown_sleep);
-		if (card->free_on_last_close)
-			put_device(&card->card_dev);
-	}
-}
-EXPORT_SYMBOL(snd_card_unref);
-
 int snd_card_free_when_closed(struct snd_card *card)
 {
-	int ret;
-
-	atomic_inc(&card->refcount);
-	ret = snd_card_disconnect(card);
-	if (ret) {
-		atomic_dec(&card->refcount);
+	int ret = snd_card_disconnect(card);
+	if (ret)
 		return ret;
-	}
-
-	card->free_on_last_close = 1;
-	if (atomic_dec_and_test(&card->refcount))
-		put_device(&card->card_dev);
+	put_device(&card->card_dev);
 	return 0;
 }
-
 EXPORT_SYMBOL(snd_card_free_when_closed);
 
 int snd_card_free(struct snd_card *card)
 {
-	int ret = snd_card_disconnect(card);
+	struct completion released;
+	int ret;
+
+	init_completion(&released);
+	card->release_completion = &released;
+	ret = snd_card_free_when_closed(card);
 	if (ret)
 		return ret;
-
 	/* wait, until all devices are ready for the free operation */
-	wait_event(card->shutdown_sleep, !atomic_read(&card->refcount));
-	put_device(&card->card_dev);
+	wait_for_completion(&released);
 	return 0;
 }
-
 EXPORT_SYMBOL(snd_card_free);
 
 /* retrieve the last word of shortname or longname */
@@ -924,7 +901,7 @@ int snd_card_file_add(struct snd_card *card, struct file *file)
 		return -ENODEV;
 	}
 	list_add(&mfile->list, &card->files_list);
-	atomic_inc(&card->refcount);
+	get_device(&card->card_dev);
 	spin_unlock(&card->files_lock);
 	return 0;
 }
@@ -967,7 +944,7 @@ int snd_card_file_remove(struct snd_card *card, struct file *file)
 		return -ENOENT;
 	}
 	kfree(found);
-	snd_card_unref(card);
+	put_device(&card->card_dev);
 	return 0;
 }
 
diff --git a/sound/core/sound.c b/sound/core/sound.c
index 437c25ea6403..4aaa53161644 100644
--- a/sound/core/sound.c
+++ b/sound/core/sound.c
@@ -118,7 +118,7 @@ void *snd_lookup_minor_data(unsigned int minor, int type)
 	if (mreg && mreg->type == type) {
 		private_data = mreg->private_data;
 		if (private_data && mreg->card_ptr)
-			atomic_inc(&mreg->card_ptr->refcount);
+			get_device(&mreg->card_ptr->card_dev);
 	} else
 		private_data = NULL;
 	mutex_unlock(&sound_mutex);
diff --git a/sound/core/sound_oss.c b/sound/core/sound_oss.c
index b19184d45f19..573a65eb2b79 100644
--- a/sound/core/sound_oss.c
+++ b/sound/core/sound_oss.c
@@ -55,7 +55,7 @@ void *snd_lookup_oss_minor_data(unsigned int minor, int type)
 	if (mreg && mreg->type == type) {
 		private_data = mreg->private_data;
 		if (private_data && mreg->card_ptr)
-			atomic_inc(&mreg->card_ptr->refcount);
+			get_device(&mreg->card_ptr->card_dev);
 	} else
 		private_data = NULL;
 	mutex_unlock(&sound_oss_mutex);
-- 
1.8.5.2

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH RFC 0/3] Embed card device into struct snd_card
  2014-02-12 11:20 [PATCH RFC 0/3] Embed card device into struct snd_card Takashi Iwai
                   ` (2 preceding siblings ...)
  2014-02-12 11:20 ` [PATCH 3/3] ALSA: Use standard device refcount for card accounting Takashi Iwai
@ 2014-02-14 12:00 ` Takashi Iwai
  3 siblings, 0 replies; 5+ messages in thread
From: Takashi Iwai @ 2014-02-14 12:00 UTC (permalink / raw)
  To: alsa-devel

At Wed, 12 Feb 2014 12:20:10 +0100,
Takashi Iwai wrote:
> 
> The third batch is a more intensive change; now struct device for
> card-object is embedded in snd_card struct.  This makes the presence
> of the device object presistent, which can be later referred by
> other devices at the object creation time.
> 
> Also, along with this change, the refcounting of the card object
> was changed just to use the standard device refcount.  This needs
> to move the destructor into the device release callback.

This patch series have been merged to for-next branch now, too.


Takashi

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2014-02-14 12:00 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-02-12 11:20 [PATCH RFC 0/3] Embed card device into struct snd_card Takashi Iwai
2014-02-12 11:20 ` [PATCH 1/3] ALSA: " Takashi Iwai
2014-02-12 11:20 ` [PATCH 2/3] ALSA: Use static groups for id and number card sysfs attr files Takashi Iwai
2014-02-12 11:20 ` [PATCH 3/3] ALSA: Use standard device refcount for card accounting Takashi Iwai
2014-02-14 12:00 ` [PATCH RFC 0/3] Embed card device into struct snd_card Takashi Iwai

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.