ALSA: Allow to pass the device object to snd_register_device*()

This is a preliminary patch for the further work on embedding struct
device into each sound device instance.  It changes
snd_register_device*() helpers to receive the device object directly
for skipping creating a device there.

Reviewed-by: Jaroslav Kysela <perex@perex.cz>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
Takashi Iwai 2015-01-29 15:53:51 +01:00
parent e36f014edf
commit 92b7952da8
4 changed files with 45 additions and 30 deletions

View File

@ -186,6 +186,7 @@ struct snd_minor {
int type; /* SNDRV_DEVICE_TYPE_XXX */ int type; /* SNDRV_DEVICE_TYPE_XXX */
int card; /* card number */ int card; /* card number */
int device; /* device number */ int device; /* device number */
bool created;
const struct file_operations *f_ops; /* file operations */ const struct file_operations *f_ops; /* file operations */
void *private_data; /* private data for f_ops->open */ void *private_data; /* private data for f_ops->open */
struct device *dev; /* device for sysfs */ struct device *dev; /* device for sysfs */
@ -206,12 +207,10 @@ extern struct class *sound_class;
void snd_request_card(int card); void snd_request_card(int card);
int snd_register_device_for_dev(int type, struct snd_card *card, int snd_register_device_for_dev(int type, struct snd_card *card, int dev,
int dev,
const struct file_operations *f_ops, const struct file_operations *f_ops,
void *private_data, void *private_data, struct device *device,
const char *name, struct device *parent, const char *name);
struct device *device);
/** /**
* snd_register_device - Register the ALSA device file for the card * snd_register_device - Register the ALSA device file for the card
@ -236,8 +235,9 @@ static inline int snd_register_device(int type, struct snd_card *card, int dev,
const char *name) const char *name)
{ {
return snd_register_device_for_dev(type, card, dev, f_ops, return snd_register_device_for_dev(type, card, dev, f_ops,
private_data, name, private_data, NULL,
snd_card_get_device_link(card)); snd_card_get_device_link(card),
name);
} }
int snd_unregister_device(int type, struct snd_card *card, int dev); int snd_unregister_device(int type, struct snd_card *card, int dev);

View File

@ -433,7 +433,8 @@ static int snd_hwdep_dev_register(struct snd_device *device)
dev = snd_card_get_device_link(hwdep->card); dev = snd_card_get_device_link(hwdep->card);
err = snd_register_device_for_dev(SNDRV_DEVICE_TYPE_HWDEP, err = snd_register_device_for_dev(SNDRV_DEVICE_TYPE_HWDEP,
hwdep->card, hwdep->device, hwdep->card, hwdep->device,
&snd_hwdep_f_ops, hwdep, name, dev); &snd_hwdep_f_ops, hwdep,
NULL, dev, name);
if (err < 0) { if (err < 0) {
dev_err(dev, dev_err(dev,
"unable to register hardware dependent device %i:%i\n", "unable to register hardware dependent device %i:%i\n",

View File

@ -1115,7 +1115,7 @@ static int snd_pcm_dev_register(struct snd_device *device)
err = snd_register_device_for_dev(devtype, pcm->card, err = snd_register_device_for_dev(devtype, pcm->card,
pcm->device, pcm->device,
&snd_pcm_f_ops[cidx], &snd_pcm_f_ops[cidx],
pcm, str, dev); pcm, NULL, dev, str);
if (err < 0) { if (err < 0) {
list_del(&pcm->list); list_del(&pcm->list);
mutex_unlock(&register_mutex); mutex_unlock(&register_mutex);

View File

@ -248,8 +248,9 @@ static int snd_kernel_minor(int type, struct snd_card *card, int dev)
* @dev: the device index * @dev: the device index
* @f_ops: the file operations * @f_ops: the file operations
* @private_data: user pointer for f_ops->open() * @private_data: user pointer for f_ops->open()
* @name: the device file name * @device: the device to register, NULL to create a new one
* @device: the &struct device to link this new device to * @parent: the &struct device to link this new device to (only for device=NULL)
* @name: the device file name (only for device=NULL)
* *
* Registers an ALSA device file for the given card. * Registers an ALSA device file for the given card.
* The operators have to be set in reg parameter. * The operators have to be set in reg parameter.
@ -258,14 +259,13 @@ static int snd_kernel_minor(int type, struct snd_card *card, int dev)
*/ */
int snd_register_device_for_dev(int type, struct snd_card *card, int dev, int snd_register_device_for_dev(int type, struct snd_card *card, int dev,
const struct file_operations *f_ops, const struct file_operations *f_ops,
void *private_data, void *private_data, struct device *device,
const char *name, struct device *device) struct device *parent, const char *name)
{ {
int minor; int minor;
int err = 0;
struct snd_minor *preg; struct snd_minor *preg;
if (snd_BUG_ON(!name))
return -EINVAL;
preg = kmalloc(sizeof *preg, GFP_KERNEL); preg = kmalloc(sizeof *preg, GFP_KERNEL);
if (preg == NULL) if (preg == NULL)
return -ENOMEM; return -ENOMEM;
@ -284,23 +284,32 @@ int snd_register_device_for_dev(int type, struct snd_card *card, int dev,
minor = -EBUSY; minor = -EBUSY;
#endif #endif
if (minor < 0) { if (minor < 0) {
mutex_unlock(&sound_mutex); err = minor;
kfree(preg); goto error;
return minor;
}
snd_minors[minor] = preg;
preg->dev = device_create(sound_class, device, MKDEV(major, minor),
private_data, "%s", name);
if (IS_ERR(preg->dev)) {
snd_minors[minor] = NULL;
mutex_unlock(&sound_mutex);
minor = PTR_ERR(preg->dev);
kfree(preg);
return minor;
} }
if (device) {
preg->created = false;
preg->dev = device;
device->devt = MKDEV(major, minor);
err = device_add(device);
} else {
preg->created = true;
preg->dev = device_create(sound_class, parent,
MKDEV(major, minor), private_data,
"%s", name);
if (IS_ERR(preg->dev))
err = PTR_ERR(preg->dev);
}
if (err < 0)
goto error;
snd_minors[minor] = preg;
error:
mutex_unlock(&sound_mutex); mutex_unlock(&sound_mutex);
return 0; if (err < 0)
kfree(preg);
return err;
} }
EXPORT_SYMBOL(snd_register_device_for_dev); EXPORT_SYMBOL(snd_register_device_for_dev);
@ -337,6 +346,7 @@ static int find_snd_minor(int type, struct snd_card *card, int dev)
int snd_unregister_device(int type, struct snd_card *card, int dev) int snd_unregister_device(int type, struct snd_card *card, int dev)
{ {
int minor; int minor;
struct snd_minor *preg;
mutex_lock(&sound_mutex); mutex_lock(&sound_mutex);
minor = find_snd_minor(type, card, dev); minor = find_snd_minor(type, card, dev);
@ -345,7 +355,11 @@ int snd_unregister_device(int type, struct snd_card *card, int dev)
return -EINVAL; return -EINVAL;
} }
device_destroy(sound_class, MKDEV(major, minor)); preg = snd_minors[minor];
if (preg && !preg->created)
device_del(preg->dev);
else
device_destroy(sound_class, MKDEV(major, minor));
kfree(snd_minors[minor]); kfree(snd_minors[minor]);
snd_minors[minor] = NULL; snd_minors[minor] = NULL;