diff options
author | Takashi Iwai <tiwai@suse.de> | 2017-11-13 15:43:04 +0100 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2017-11-13 15:43:13 +0100 |
commit | c429bda21ffafb28f02fb2eb4055b4ab6879ed58 (patch) | |
tree | 80715bf534bfa3bcb69ef77cf1dc5f9d98919b44 /sound/hda/hdac_sysfs.c | |
parent | ALSA: hda - fix headset mic problem for Dell machines with alc274 (diff) | |
parent | ALSA: ice1712: define i2c eeprom addr to header file (diff) | |
download | linux-c429bda21ffafb28f02fb2eb4055b4ab6879ed58.tar.gz linux-c429bda21ffafb28f02fb2eb4055b4ab6879ed58.tar.bz2 linux-c429bda21ffafb28f02fb2eb4055b4ab6879ed58.zip |
Merge branch 'for-next' into for-linus
Pull 4.15 updates to take over the previous urgent fixes.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/hda/hdac_sysfs.c')
-rw-r--r-- | sound/hda/hdac_sysfs.c | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/sound/hda/hdac_sysfs.c b/sound/hda/hdac_sysfs.c index 42d61bf41969..e123ba6b2e81 100644 --- a/sound/hda/hdac_sysfs.c +++ b/sound/hda/hdac_sysfs.c @@ -414,3 +414,50 @@ void hda_widget_sysfs_exit(struct hdac_device *codec) { widget_tree_free(codec); } + +int hda_widget_sysfs_reinit(struct hdac_device *codec, + hda_nid_t start_nid, int num_nodes) +{ + struct hdac_widget_tree *tree; + hda_nid_t end_nid = start_nid + num_nodes; + hda_nid_t nid; + int i; + + if (!codec->widgets) + return hda_widget_sysfs_init(codec); + + tree = kmemdup(codec->widgets, sizeof(*tree), GFP_KERNEL); + if (!tree) + return -ENOMEM; + + tree->nodes = kcalloc(num_nodes + 1, sizeof(*tree->nodes), GFP_KERNEL); + if (!tree->nodes) { + kfree(tree); + return -ENOMEM; + } + + /* prune non-existing nodes */ + for (i = 0, nid = codec->start_nid; i < codec->num_nodes; i++, nid++) { + if (nid < start_nid || nid >= end_nid) + free_widget_node(codec->widgets->nodes[i], + &widget_node_group); + } + + /* add new nodes */ + for (i = 0, nid = start_nid; i < num_nodes; i++, nid++) { + if (nid < codec->start_nid || nid >= codec->end_nid) + add_widget_node(tree->root, nid, &widget_node_group, + &tree->nodes[i]); + else + tree->nodes[i] = + codec->widgets->nodes[nid - codec->start_nid]; + } + + /* replace with the new tree */ + kfree(codec->widgets->nodes); + kfree(codec->widgets); + codec->widgets = tree; + + kobject_uevent(tree->root, KOBJ_CHANGE); + return 0; +} |