[PATCH 17/19] ALSA: hda/hdmi - fix vgaswitcheroo detection for AMD

Takashi Iwai tiwai at suse.de
Thu Oct 17 07:55:34 UTC 2019


On Fri, 11 Oct 2019 03:45:34 +0200,
Alex Deucher wrote:
> 
> Only enable the vga_switcheroo logic on systems with the
> ATPX ACPI method.  This logic is not needed for asics
> that are not part of a PX (PowerXpress)/HG (Hybrid Graphics)
> platform.
> 
> Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
> ---
>  sound/pci/hda/hda_intel.c | 39 +++++++++++++++++++++++++++++++++++++++
>  1 file changed, 39 insertions(+)
> 
> diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
> index 1e14d7270adf..9b90312d7314 100644
> --- a/sound/pci/hda/hda_intel.c
> +++ b/sound/pci/hda/hda_intel.c
> @@ -35,6 +35,9 @@
>  #include <linux/clocksource.h>
>  #include <linux/time.h>
>  #include <linux/completion.h>
> +#ifdef SUPPORT_VGA_SWITCHEROO
> +#include <linux/acpi.h>
> +#endif
>  
>  #ifdef CONFIG_X86
>  /* for snoop control */
> @@ -1345,6 +1348,26 @@ static int azx_dev_free(struct snd_device *device)
>  }
>  
>  #ifdef SUPPORT_VGA_SWITCHEROO
> +/* ATPX is in the integrated GPU's namespace */
> +static struct pci_dev *atpx_present(void)
> +{
> +	struct pci_dev *pdev = NULL;
> +	acpi_handle dhandle, atpx_handle;
> +	acpi_status status;
> +
> +	while ((pdev = pci_get_class(PCI_BASE_CLASS_DISPLAY << 16, pdev)) != NULL) {
> +		dhandle = ACPI_HANDLE(&pdev->dev);
> +		if (!dhandle)
> +			continue;
> +
> +		status = acpi_get_handle(dhandle, "ATPX", &atpx_handle);
> +		if (ACPI_FAILURE(status))
> +			continue;
> +		return pdev;
> +	}
> +	return NULL;
> +}
> +
>  /*
>   * Check of disabled HDMI controller by vga_switcheroo
>   */
> @@ -1356,6 +1379,22 @@ static struct pci_dev *get_bound_vga(struct pci_dev *pci)
>  	switch (pci->vendor) {
>  	case PCI_VENDOR_ID_ATI:
>  	case PCI_VENDOR_ID_AMD:
> +		if (pci->devfn == 1) {
> +			p = pci_get_domain_bus_and_slot(pci_domain_nr(pci->bus),
> +							pci->bus->number, 0);
> +			if (p) {
> +				/* ATPX is in the integrated GPU's ACPI namespace
> +				 * rather than the dGPU's namespace. However,
> +				 * the dGPU is the one who is involved in
> +				 * vgaswitcheroo.
> +				 */
> +				if (((p->class >> 16) == PCI_BASE_CLASS_DISPLAY) &&
> +				    atpx_present())
> +					return p;

Won't this lead to the unbalanced refcount for the device returned
from atpx_present()?


thanks,

Takashi

> +				pci_dev_put(p);
> +			}
> +		}
> +		break;
>  	case PCI_VENDOR_ID_NVIDIA:
>  		if (pci->devfn == 1) {
>  			p = pci_get_domain_bus_and_slot(pci_domain_nr(pci->bus),
> -- 
> 2.20.1
> 


More information about the amd-gfx mailing list