mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	ALSA: Embed card device into struct snd_card
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>
This commit is contained in:
		
							parent
							
								
									1334509530
								
							
						
					
					
						commit
						8bfb181c17
					
				
					 2 changed files with 41 additions and 23 deletions
				
			
		| 
						 | 
				
			
			@ -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 */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -135,7 +134,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 */
 | 
			
		||||
| 
						 | 
				
			
			@ -149,6 +149,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)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -197,7 +199,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 */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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, SNDRV_DEV_CMD_PRE);
 | 
			
		||||
      __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);
 | 
			
		||||
| 
						 | 
				
			
			@ -471,7 +488,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);
 | 
			
		||||
| 
						 | 
				
			
			@ -489,7 +506,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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -503,7 +520,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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -694,12 +711,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)
 | 
			
		||||
| 
						 | 
				
			
			@ -729,11 +745,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;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue