[PATCH] ALSA: hda/i915: Allow delayed i915 audio component binding

Takashi Iwai tiwai at suse.de
Sun Jul 22 08:47:23 UTC 2018


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 at suse.de>
---

This is applied on top of the current for-next or topic/drm_audio_component
branch of sound git tree.

 sound/hda/hdac_i915.c | 24 ++++++++++++++++++++++--
 1 file 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;
-- 
2.18.0



More information about the dri-devel mailing list