summaryrefslogtreecommitdiff
path: root/sound/hda/hdac_component.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2020-10-06 19:17:22 +0300
committerTakashi Iwai <tiwai@suse.de>2020-10-09 16:46:04 +0200
commit96e503f9000f2ad17d550cd884a5e386eb7f532f (patch)
tree560eba52b0a526645c0a2a24d181f19a8ed97b46 /sound/hda/hdac_component.c
parent7dcd56123e312e8b17f85a597b33552a704ce45f (diff)
downloadlinux-96e503f9000f2ad17d550cd884a5e386eb7f532f.tar.gz
ALSA: hda/i915 - fix list corruption with concurrent probes
Current hdac_i915 uses a static completion instance to wait for i915 driver to complete the component bind. This design is not safe if multiple HDA controllers are active and communicating with different i915 instances, and can lead to list corruption and failed audio driver probe. Fix the design by moving completion mechanism to common acomp code and remove the related code from hdac_i915. Fixes: 7b882fe3e3e8 ("ALSA: hda - handle multiple i915 device instances") Co-developed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com> Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com> Link: https://lore.kernel.org/r/20201006161722.500256-1-kai.vehmanen@linux.intel.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/hda/hdac_component.c')
-rw-r--r--sound/hda/hdac_component.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/sound/hda/hdac_component.c b/sound/hda/hdac_component.c
index 89126c6fd216..bb37e7e0bd79 100644
--- a/sound/hda/hdac_component.c
+++ b/sound/hda/hdac_component.c
@@ -210,12 +210,14 @@ static int hdac_component_master_bind(struct device *dev)
goto module_put;
}
+ complete_all(&acomp->master_bind_complete);
return 0;
module_put:
module_put(acomp->ops->owner);
out_unbind:
component_unbind_all(dev, acomp);
+ complete_all(&acomp->master_bind_complete);
return ret;
}
@@ -296,6 +298,7 @@ int snd_hdac_acomp_init(struct hdac_bus *bus,
if (!acomp)
return -ENOMEM;
acomp->audio_ops = aops;
+ init_completion(&acomp->master_bind_complete);
bus->audio_component = acomp;
devres_add(dev, acomp);