diff options
author | Jiri Kosina <jkosina@suse.cz> | 2011-11-13 23:55:35 +0400 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2011-11-13 23:55:53 +0400 |
commit | 2290c0d06d82faee87b1ab2d9d4f7bf81ef64379 (patch) | |
tree | e075e4d5534193f28e6059904f61e5ca03958d3c /sound/core/vmaster.c | |
parent | 4da669a2e3e5bc70b30a0465f3641528681b5f77 (diff) | |
parent | 52e4c2a05256cb83cda12f3c2137ab1533344edb (diff) | |
download | linux-2290c0d06d82faee87b1ab2d9d4f7bf81ef64379.tar.xz |
Merge branch 'master' into for-next
Sync with Linus tree to have 157550ff ("mtd: add GPMI-NAND driver
in the config and Makefile") as I have patch depending on that one.
Diffstat (limited to 'sound/core/vmaster.c')
-rw-r--r-- | sound/core/vmaster.c | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/sound/core/vmaster.c b/sound/core/vmaster.c index a39d3d8c2f9c..130cfe677d60 100644 --- a/sound/core/vmaster.c +++ b/sound/core/vmaster.c @@ -10,6 +10,7 @@ */ #include <linux/slab.h> +#include <linux/export.h> #include <sound/core.h> #include <sound/control.h> #include <sound/tlv.h> @@ -51,6 +52,7 @@ struct link_slave { struct link_ctl_info info; int vals[2]; /* current values */ unsigned int flags; + struct snd_kcontrol *kctl; /* original kcontrol pointer */ struct snd_kcontrol slave; /* the copy of original control entry */ }; @@ -251,6 +253,7 @@ int _snd_ctl_add_slave(struct snd_kcontrol *master, struct snd_kcontrol *slave, slave->count * sizeof(*slave->vd), GFP_KERNEL); if (!srec) return -ENOMEM; + srec->kctl = slave; srec->slave = *slave; memcpy(srec->slave.vd, slave->vd, slave->count * sizeof(*slave->vd)); srec->master = master_link; @@ -332,10 +335,18 @@ static int master_put(struct snd_kcontrol *kcontrol, static void master_free(struct snd_kcontrol *kcontrol) { struct link_master *master = snd_kcontrol_chip(kcontrol); - struct link_slave *slave; - - list_for_each_entry(slave, &master->slaves, list) - slave->master = NULL; + struct link_slave *slave, *n; + + /* free all slave links and retore the original slave kctls */ + list_for_each_entry_safe(slave, n, &master->slaves, list) { + struct snd_kcontrol *sctl = slave->kctl; + struct list_head olist = sctl->list; + memcpy(sctl, &slave->slave, sizeof(*sctl)); + memcpy(sctl->vd, slave->slave.vd, + sctl->count * sizeof(*sctl->vd)); + sctl->list = olist; /* keep the current linked-list */ + kfree(slave); + } kfree(master); } |