Skip to content

Commit

Permalink
ALSA: hda/i915: Allow delayed i915 audio component binding
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
tiwai committed Jul 24, 2018
1 parent 1ea0358 commit f9b54e1
Showing 1 changed file with 22 additions and 2 deletions.
24 changes: 22 additions & 2 deletions sound/hda/hdac_i915.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) || \
Expand Down Expand Up @@ -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
Expand All @@ -117,16 +132,21 @@ 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)
return err;
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;
Expand Down

0 comments on commit f9b54e1

Please sign in to comment.