Skip to content

Commit f9b54e1

Browse files
committed
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 <[email protected]>
1 parent 1ea0358 commit f9b54e1

File tree

1 file changed

+22
-2
lines changed

1 file changed

+22
-2
lines changed

sound/hda/hdac_i915.c

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
#include <sound/hda_i915.h>
2121
#include <sound/hda_register.h>
2222

23+
static struct completion bind_complete;
24+
2325
#define CONTROLLER_IN_GPU(pci) (((pci)->device == 0x0a0c) || \
2426
((pci)->device == 0x0c0c) || \
2527
((pci)->device == 0x0d0c) || \
@@ -97,6 +99,19 @@ static bool i915_gfx_present(void)
9799
return pci_dev_present(ids);
98100
}
99101

102+
static int i915_master_bind(struct device *dev,
103+
struct drm_audio_component *acomp)
104+
{
105+
complete_all(&bind_complete);
106+
/* clear audio_ops here as it was needed only for completion call */
107+
acomp->audio_ops = NULL;
108+
return 0;
109+
}
110+
111+
static const struct drm_audio_component_audio_ops i915_init_ops = {
112+
.master_bind = i915_master_bind
113+
};
114+
100115
/**
101116
* snd_hdac_i915_init - Initialize i915 audio component
102117
* @bus: HDA core bus
@@ -117,16 +132,21 @@ int snd_hdac_i915_init(struct hdac_bus *bus)
117132
if (!i915_gfx_present())
118133
return -ENODEV;
119134

120-
err = snd_hdac_acomp_init(bus, NULL,
135+
init_completion(&bind_complete);
136+
137+
err = snd_hdac_acomp_init(bus, &i915_init_ops,
121138
i915_component_master_match,
122139
sizeof(struct i915_audio_component) - sizeof(*acomp));
123140
if (err < 0)
124141
return err;
125142
acomp = bus->audio_component;
126143
if (!acomp)
127144
return -ENODEV;
128-
if (!acomp->ops)
145+
if (!acomp->ops) {
129146
request_module("i915");
147+
/* 10s timeout */
148+
wait_for_completion_timeout(&bind_complete, 10 * 1000);
149+
}
130150
if (!acomp->ops) {
131151
snd_hdac_acomp_exit(bus);
132152
return -ENODEV;

0 commit comments

Comments
 (0)