ALSA: info: Register proc entries recursively, too

The commit [c560a6797e3b: ALSA: core: Remove child proc file elements
recursively] converted snd_card_proc_new() with the normal
snd_info_*() call and removed snd_device chain for such info
entries. However, it misses one point: the creation of the proc entry
was managed by snd_device chain in the former code, and now it's also
gone, which results in no proc files creation at all.  Mea culpa.

This patch makes snd_info_card_register() creating the all pending
child proc entries in a shot.  Also, since snd_card_register() might
be called multiple times, this function is also changed to be callable
multiple times.

Along with the changes above, now the linked list of snd_info_entry is
added at creation time instead of snd_info_register() for keeping eyes
of pending info entries.

Fixes: c560a6797e3b ('ALSA: core: Remove child proc file elements recursively')
Reported-by: "Lu, Han" <han.lu@intel.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
diff --git a/sound/core/info.c b/sound/core/info.c
index 5662793..13b1744 100644
--- a/sound/core/info.c
+++ b/sound/core/info.c
@@ -515,22 +515,51 @@
 	return 0;
 }
 
+/* register all pending info entries */
+static int snd_info_register_recursive(struct snd_info_entry *entry)
+{
+	struct snd_info_entry *p;
+	int err;
+
+	if (!entry->p) {
+		err = snd_info_register(entry);
+		if (err < 0)
+			return err;
+	}
+
+	list_for_each_entry(p, &entry->children, list) {
+		err = snd_info_register_recursive(p);
+		if (err < 0)
+			return err;
+	}
+
+	return 0;
+}
+
 /*
  * register the card proc file
  * called from init.c
+ * can be called multiple times for reinitialization
  */
 int snd_info_card_register(struct snd_card *card)
 {
 	struct proc_dir_entry *p;
+	int err;
 
 	if (snd_BUG_ON(!card))
 		return -ENXIO;
 
+	err = snd_info_register_recursive(card->proc_root);
+	if (err < 0)
+		return err;
+
 	if (!strcmp(card->id, card->proc_root->name))
 		return 0;
 
+	if (card->proc_root_link)
+		return 0;
 	p = proc_symlink(card->id, snd_proc_root->p, card->proc_root->name);
-	if (p == NULL)
+	if (!p)
 		return -ENOMEM;
 	card->proc_root_link = p;
 	return 0;
@@ -705,6 +734,8 @@
 	if (entry) {
 		entry->module = module;
 		entry->parent = parent;
+		if (parent)
+			list_add_tail(&entry->list, &parent->children);
 	}
 	return entry;
 }
@@ -730,6 +761,8 @@
 		entry->module = card->module;
 		entry->card = card;
 		entry->parent = parent;
+		if (parent)
+			list_add_tail(&entry->list, &parent->children);
 	}
 	return entry;
 }
@@ -816,8 +849,6 @@
 		proc_set_size(p, entry->size);
 	}
 	entry->p = p;
-	if (entry->parent)
-		list_add_tail(&entry->list, &entry->parent->children);
 	mutex_unlock(&info_mutex);
 	return 0;
 }