summaryrefslogtreecommitdiffstats
path: root/sound/hda
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2018-07-11 15:05:06 +0200
committerTakashi Iwai <tiwai@suse.de>2018-07-24 12:32:44 +0200
commitf9b54e1961c7052e7d7817d707826eb2b9a1ca09 (patch)
treee2e2b9291737039322a6f899f146419990ff6d5e /sound/hda
parentALSA: usb-audio: Generic DSD detection for Thesycon-based implementations (diff)
downloadlinux-f9b54e1961c7052e7d7817d707826eb2b9a1ca09.tar.xz
linux-f9b54e1961c7052e7d7817d707826eb2b9a1ca09.zip
ALSA: hda/i915: Allow delayed i915 audio component binding
Currently HD-audio i915 audio binding doesn't support any delayed binding, and supposes that the i915 driver registers the component immediately. This has been OK, so far, but the work-in-progress change in i915 may introduce the asynchronous binding, which effectively delays the component registration. For addressing it, implement a completion to be synced with the master binding. The timeout is set to 10 seconds which should be long enough and hopefully be not too annoying if anyone boots up a debugging session with i915 KMS turned off. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/hda')
-rw-r--r--sound/hda/hdac_i915.c24
1 files changed, 22 insertions, 2 deletions
diff --git a/sound/hda/hdac_i915.c b/sound/hda/hdac_i915.c
index 8f2aa8bc1185..b5282cbbe489 100644
--- a/sound/hda/hdac_i915.c
+++ b/sound/hda/hdac_i915.c
@@ -20,6 +20,8 @@
#include <sound/hda_i915.h>
#include <sound/hda_register.h>
+static struct completion bind_complete;
+
#define CONTROLLER_IN_GPU(pci) (((pci)->device == 0x0a0c) || \
((pci)->device == 0x0c0c) || \
((pci)->device == 0x0d0c) || \
@@ -97,6 +99,19 @@ static bool i915_gfx_present(void)
return pci_dev_present(ids);
}
+static int i915_master_bind(struct device *dev,
+ struct drm_audio_component *acomp)
+{
+ complete_all(&bind_complete);
+ /* clear audio_ops here as it was needed only for completion call */
+ acomp->audio_ops = NULL;
+ return 0;
+}
+
+static const struct drm_audio_component_audio_ops i915_init_ops = {
+ .master_bind = i915_master_bind
+};
+
/**
* snd_hdac_i915_init - Initialize i915 audio component
* @bus: HDA core bus
@@ -117,7 +132,9 @@ int snd_hdac_i915_init(struct hdac_bus *bus)
if (!i915_gfx_present())
return -ENODEV;
- err = snd_hdac_acomp_init(bus, NULL,
+ init_completion(&bind_complete);
+
+ err = snd_hdac_acomp_init(bus, &i915_init_ops,
i915_component_master_match,
sizeof(struct i915_audio_component) - sizeof(*acomp));
if (err < 0)
@@ -125,8 +142,11 @@ int snd_hdac_i915_init(struct hdac_bus *bus)
acomp = bus->audio_component;
if (!acomp)
return -ENODEV;
- if (!acomp->ops)
+ if (!acomp->ops) {
request_module("i915");
+ /* 10s timeout */
+ wait_for_completion_timeout(&bind_complete, 10 * 1000);
+ }
if (!acomp->ops) {
snd_hdac_acomp_exit(bus);
return -ENODEV;