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>
This commit is contained in:
parent
1ea0358ecb
commit
f9b54e1961
|
@ -20,6 +20,8 @@
|
||||||
#include <sound/hda_i915.h>
|
#include <sound/hda_i915.h>
|
||||||
#include <sound/hda_register.h>
|
#include <sound/hda_register.h>
|
||||||
|
|
||||||
|
static struct completion bind_complete;
|
||||||
|
|
||||||
#define CONTROLLER_IN_GPU(pci) (((pci)->device == 0x0a0c) || \
|
#define CONTROLLER_IN_GPU(pci) (((pci)->device == 0x0a0c) || \
|
||||||
((pci)->device == 0x0c0c) || \
|
((pci)->device == 0x0c0c) || \
|
||||||
((pci)->device == 0x0d0c) || \
|
((pci)->device == 0x0d0c) || \
|
||||||
|
@ -97,6 +99,19 @@ static bool i915_gfx_present(void)
|
||||||
return pci_dev_present(ids);
|
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
|
* snd_hdac_i915_init - Initialize i915 audio component
|
||||||
* @bus: HDA core bus
|
* @bus: HDA core bus
|
||||||
|
@ -117,7 +132,9 @@ int snd_hdac_i915_init(struct hdac_bus *bus)
|
||||||
if (!i915_gfx_present())
|
if (!i915_gfx_present())
|
||||||
return -ENODEV;
|
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,
|
i915_component_master_match,
|
||||||
sizeof(struct i915_audio_component) - sizeof(*acomp));
|
sizeof(struct i915_audio_component) - sizeof(*acomp));
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
|
@ -125,8 +142,11 @@ int snd_hdac_i915_init(struct hdac_bus *bus)
|
||||||
acomp = bus->audio_component;
|
acomp = bus->audio_component;
|
||||||
if (!acomp)
|
if (!acomp)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
if (!acomp->ops)
|
if (!acomp->ops) {
|
||||||
request_module("i915");
|
request_module("i915");
|
||||||
|
/* 10s timeout */
|
||||||
|
wait_for_completion_timeout(&bind_complete, 10 * 1000);
|
||||||
|
}
|
||||||
if (!acomp->ops) {
|
if (!acomp->ops) {
|
||||||
snd_hdac_acomp_exit(bus);
|
snd_hdac_acomp_exit(bus);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
Loading…
Reference in New Issue