ALSA: hda - Use generic array for loopback list management

Signed-off-by: Takashi Iwai <tiwai@suse.de>
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index c2cd3d6..6af5ade 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -42,6 +42,7 @@
 {
 	snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32);
 	snd_array_init(&spec->paths, sizeof(struct nid_path), 8);
+	snd_array_init(&spec->loopback_list, sizeof(struct hda_amp_list), 8);
 	mutex_init(&spec->pcm_mutex);
 	return 0;
 }
@@ -82,6 +83,7 @@
 		return;
 	free_kctls(spec);
 	snd_array_free(&spec->paths);
+	snd_array_free(&spec->loopback_list);
 }
 EXPORT_SYMBOL_HDA(snd_hda_gen_spec_free);
 
@@ -2484,18 +2486,18 @@
  */
 
 /* add the powersave loopback-list entry */
-static void add_loopback_list(struct hda_gen_spec *spec, hda_nid_t mix, int idx)
+static int add_loopback_list(struct hda_gen_spec *spec, hda_nid_t mix, int idx)
 {
 	struct hda_amp_list *list;
 
-	if (spec->num_loopbacks >= ARRAY_SIZE(spec->loopback_list) - 1)
-		return;
-	list = spec->loopback_list + spec->num_loopbacks;
+	list = snd_array_new(&spec->loopback_list);
+	if (!list)
+		return -ENOMEM;
 	list->nid = mix;
 	list->dir = HDA_INPUT;
 	list->idx = idx;
-	spec->num_loopbacks++;
-	spec->loopback.amplist = spec->loopback_list;
+	spec->loopback.amplist = spec->loopback_list.list;
+	return 0;
 }
 
 /* create input playback/capture controls for the given pin */
@@ -2536,7 +2538,9 @@
 	}
 
 	path->active = true;
-	add_loopback_list(spec, mix_nid, idx);
+	err = add_loopback_list(spec, mix_nid, idx);
+	if (err < 0)
+		return err;
 
 	if (spec->mixer_nid != spec->mixer_merge_nid &&
 	    !spec->loopback_merge_path) {
diff --git a/sound/pci/hda/hda_generic.h b/sound/pci/hda/hda_generic.h
index d5348dd..009b57b 100644
--- a/sound/pci/hda/hda_generic.h
+++ b/sound/pci/hda/hda_generic.h
@@ -228,8 +228,7 @@
 	struct hda_vmaster_mute_hook vmaster_mute;
 
 	struct hda_loopback_check loopback;
-	int num_loopbacks;
-	struct hda_amp_list loopback_list[8];
+	struct snd_array loopback_list;
 
 	/* multi-io */
 	int multi_ios;
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index ca7d962..c35338a 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -355,10 +355,12 @@
 {
 	struct via_spec *spec = codec->spec;
 	const struct hda_amp_list *p;
-	int i, ch, v;
+	int ch, v;
 
-	for (i = 0; i < spec->gen.num_loopbacks; i++) {
-		p = &spec->gen.loopback_list[i];
+	p = spec->gen.loopback.amplist;
+	if (!p)
+		return true;
+	for (; p->nid; p++) {
 		for (ch = 0; ch < 2; ch++) {
 			v = snd_hda_codec_amp_read(codec, p->nid, ch, p->dir,
 						   p->idx);