ALSA: hda/i915 - skip acomp init if no matching display

In systems with only a discrete i915 GPU, the acomp init will
always timeout for the PCH HDA controller instance.

Avoid the timeout by checking the PCI device hierarchy
whether any display class PCI device can be found on the system,
and at the same level as the HDA PCI device. If found, proceed
with the acomp init, which will wait until i915 probe is complete
and component binding can proceed. If no matching display
device is found, the audio component bind can be safely skipped.

The bind timeout will still be hit if the display is present
in the system, but i915 driver does not bind to it by configuration
choice or probe error. In this case the 60sec timeout will be
hit.

Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Acked-by: Lucas De Marchi <lucas.demarchi@intel.com>
Link: https://lore.kernel.org/r/20220405123622.2874457-1-kai.vehmanen@linux.intel.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
Kai Vehmanen 2022-04-05 15:36:22 +03:00 committed by Takashi Iwai
parent bc55cfd571
commit c9db8a30d9
1 changed files with 19 additions and 10 deletions

View File

@ -116,16 +116,25 @@ static int i915_component_master_match(struct device *dev, int subcomponent,
return 0; return 0;
} }
/* check whether intel graphics is present */ /* check whether Intel graphics is present and reachable */
static bool i915_gfx_present(void) static int i915_gfx_present(struct pci_dev *hdac_pci)
{ {
static const struct pci_device_id ids[] = { unsigned int class = PCI_BASE_CLASS_DISPLAY << 16;
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_ANY_ID), struct pci_dev *display_dev = NULL;
.class = PCI_BASE_CLASS_DISPLAY << 16, bool match = false;
.class_mask = 0xff << 16 },
{} do {
}; display_dev = pci_get_class(class, display_dev);
return pci_dev_present(ids);
if (display_dev && display_dev->vendor == PCI_VENDOR_ID_INTEL &&
connectivity_check(display_dev, hdac_pci))
match = true;
pci_dev_put(display_dev);
} while (!match && display_dev);
return match;
} }
/** /**
@ -145,7 +154,7 @@ int snd_hdac_i915_init(struct hdac_bus *bus)
struct drm_audio_component *acomp; struct drm_audio_component *acomp;
int err; int err;
if (!i915_gfx_present()) if (!i915_gfx_present(to_pci_dev(bus->dev)))
return -ENODEV; return -ENODEV;
err = snd_hdac_acomp_init(bus, NULL, err = snd_hdac_acomp_init(bus, NULL,