ALSA: Create sysfs attribute files via groups

Instead of calling each time device_create_file(), create the groups
of sysfs attribute files at once in a normal way.  Add a new helper
function, snd_get_device(), to return the associated device object,
so that we can handle the sysfs addition locally.

Since the sysfs file addition is done differently now,
snd_add_device_sysfs_file() helper function is removed.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
diff --git a/sound/core/hwdep.c b/sound/core/hwdep.c
index 8c77865..99f7e85 100644
--- a/sound/core/hwdep.c
+++ b/sound/core/hwdep.c
@@ -436,6 +436,20 @@
 		mutex_unlock(&register_mutex);
 		return err;
 	}
+
+	if (hwdep->groups) {
+		struct device *d = snd_get_device(SNDRV_DEVICE_TYPE_HWDEP,
+						  hwdep->card, hwdep->device);
+		if (d) {
+			err = sysfs_create_groups(&d->kobj, hwdep->groups);
+			if (err < 0)
+				dev_warn(card->dev,
+					 "hwdep %d:%d: cannot create sysfs groups\n",
+					 card->number, hwdep->device);
+			put_device(d);
+		}
+	}
+
 #ifdef CONFIG_SND_OSSEMUL
 	hwdep->ossreg = 0;
 	if (hwdep->oss_type >= 0) {
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index 9defdae..43932e8 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -1018,8 +1018,20 @@
         return snprintf(buf, PAGE_SIZE, "%s\n", str);
 }
 
-static struct device_attribute pcm_attrs =
-	__ATTR(pcm_class, S_IRUGO, show_pcm_class, NULL);
+static DEVICE_ATTR(pcm_class, S_IRUGO, show_pcm_class, NULL);
+static struct attribute *pcm_dev_attrs[] = {
+	&dev_attr_pcm_class.attr,
+	NULL
+};
+
+static struct attribute_group pcm_dev_attr_group = {
+	.attrs	= pcm_dev_attrs,
+};
+
+static const struct attribute_group *pcm_dev_attr_groups[] = {
+	&pcm_dev_attr_group,
+	NULL
+};
 
 static int snd_pcm_dev_register(struct snd_device *device)
 {
@@ -1069,8 +1081,18 @@
 			mutex_unlock(&register_mutex);
 			return err;
 		}
-		snd_add_device_sysfs_file(devtype, pcm->card, pcm->device,
-					  &pcm_attrs);
+
+		dev = snd_get_device(devtype, pcm->card, pcm->device);
+		if (dev) {
+			err = sysfs_create_groups(&dev->kobj,
+						  pcm_dev_attr_groups);
+			if (err < 0)
+				dev_warn(dev,
+					 "pcm %d:%d: cannot create sysfs groups\n",
+					 pcm->card->number, pcm->device);
+			put_device(dev);
+		}
+
 		for (substream = pcm->streams[cidx].substream; substream; substream = substream->next)
 			snd_pcm_timer_init(substream);
 	}
diff --git a/sound/core/sound.c b/sound/core/sound.c
index 60ab9b1..38ad1a0 100644
--- a/sound/core/sound.c
+++ b/sound/core/sound.c
@@ -355,22 +355,25 @@
 
 EXPORT_SYMBOL(snd_unregister_device);
 
-int snd_add_device_sysfs_file(int type, struct snd_card *card, int dev,
-			      struct device_attribute *attr)
+/* get the assigned device to the given type and device number;
+ * the caller needs to release it via put_device() after using it
+ */
+struct device *snd_get_device(int type, struct snd_card *card, int dev)
 {
-	int minor, ret = -EINVAL;
-	struct device *d;
+	int minor;
+	struct device *d = NULL;
 
 	mutex_lock(&sound_mutex);
 	minor = find_snd_minor(type, card, dev);
-	if (minor >= 0 && (d = snd_minors[minor]->dev) != NULL)
-		ret = device_create_file(d, attr);
+	if (minor >= 0) {
+		d = snd_minors[minor]->dev;
+		if (d)
+			get_device(d);
+	}
 	mutex_unlock(&sound_mutex);
-	return ret;
-
+	return d;
 }
-
-EXPORT_SYMBOL(snd_add_device_sysfs_file);
+EXPORT_SYMBOL(snd_get_device);
 
 #ifdef CONFIG_PROC_FS
 /*