ALSA: Allow to pass the device object to snd_register_device*()
authorTakashi Iwai <tiwai@suse.de>
Thu, 29 Jan 2015 14:53:51 +0000 (15:53 +0100)
committerTakashi Iwai <tiwai@suse.de>
Mon, 2 Feb 2015 13:21:07 +0000 (14:21 +0100)
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>
include/sound/core.h
sound/core/hwdep.c
sound/core/pcm.c
sound/core/sound.c

index 1df3f2fe5350f8a886e65d17cb7caebced128b20..39d14234961d954df32bf347220d7ffd55975e02 100644 (file)
@@ -186,6 +186,7 @@ struct snd_minor {
        int type;                       /* SNDRV_DEVICE_TYPE_XXX */
        int card;                       /* card number */
        int device;                     /* device number */
+       bool created;
        const struct file_operations *f_ops;    /* file operations */
        void *private_data;             /* private data for f_ops->open */
        struct device *dev;             /* device for sysfs */
@@ -206,12 +207,10 @@ extern struct class *sound_class;
 
 void snd_request_card(int card);
 
-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,
-                               void *private_data,
-                               const char *name,
-                               struct device *device);
+                               void *private_data, struct device *device,
+                               struct device *parent, const char *name);
 
 /**
  * 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)
 {
        return snd_register_device_for_dev(type, card, dev, f_ops,
-                                          private_data, name,
-                                          snd_card_get_device_link(card));
+                                          private_data, NULL,
+                                          snd_card_get_device_link(card),
+                                          name);
 }
 
 int snd_unregister_device(int type, struct snd_card *card, int dev);
index 69459e5f712e9e50c51f5d3aedb360616afe5c1b..85096a150edab697839e309313ebb5a043f75771 100644 (file)
@@ -433,7 +433,8 @@ static int snd_hwdep_dev_register(struct snd_device *device)
                dev = snd_card_get_device_link(hwdep->card);
        err = snd_register_device_for_dev(SNDRV_DEVICE_TYPE_HWDEP,
                                          hwdep->card, hwdep->device,
-                                         &snd_hwdep_f_ops, hwdep, name, dev);
+                                         &snd_hwdep_f_ops, hwdep,
+                                         NULL, dev, name);
        if (err < 0) {
                dev_err(dev,
                        "unable to register hardware dependent device %i:%i\n",
index cfc56c806964ed3a804f744c6297d6ea813b8fb2..dba5180e5b8072e220e35a38330c24c41ec3bf47 100644 (file)
@@ -1115,7 +1115,7 @@ static int snd_pcm_dev_register(struct snd_device *device)
                err = snd_register_device_for_dev(devtype, pcm->card,
                                                  pcm->device,
                                                  &snd_pcm_f_ops[cidx],
-                                                 pcm, str, dev);
+                                                 pcm, NULL, dev, str);
                if (err < 0) {
                        list_del(&pcm->list);
                        mutex_unlock(&register_mutex);
index f1333060bf1cc71bb391673017a5bd84a6e8123a..ea1af1acdbe96653f70e3463e4a7daa23f2d8381 100644 (file)
@@ -248,8 +248,9 @@ static int snd_kernel_minor(int type, struct snd_card *card, int dev)
  * @dev: the device index
  * @f_ops: the file operations
  * @private_data: user pointer for f_ops->open()
- * @name: the device file name
- * @device: the &struct device to link this new device to
+ * @device: the device to register, NULL to create a new one
+ * @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.
  * 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,
                                const struct file_operations *f_ops,
-                               void *private_data,
-                               const char *name, struct device *device)
+                               void *private_data, struct device *device,
+                               struct device *parent, const char *name)
 {
        int minor;
+       int err = 0;
        struct snd_minor *preg;
 
-       if (snd_BUG_ON(!name))
-               return -EINVAL;
        preg = kmalloc(sizeof *preg, GFP_KERNEL);
        if (preg == NULL)
                return -ENOMEM;
@@ -284,23 +284,32 @@ int snd_register_device_for_dev(int type, struct snd_card *card, int dev,
                minor = -EBUSY;
 #endif
        if (minor < 0) {
-               mutex_unlock(&sound_mutex);
-               kfree(preg);
-               return minor;
+               err = minor;
+               goto error;
        }
-       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);
-       return 0;
+       if (err < 0)
+               kfree(preg);
+       return err;
 }
 
 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 minor;
+       struct snd_minor *preg;
 
        mutex_lock(&sound_mutex);
        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;
        }
 
-       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]);
        snd_minors[minor] = NULL;