diff options
| author | Jonathan Corbet <[email protected]> | 2016-12-27 12:53:44 -0700 |
|---|---|---|
| committer | Jonathan Corbet <[email protected]> | 2016-12-27 12:53:44 -0700 |
| commit | 54ab6db0909061ab7ee07233d3cab86d29f86e6c (patch) | |
| tree | a7650ab5c0fa3a6a3841de8e8693041b3e009054 /drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c | |
| parent | 217e2bfab22e740227df09f22165e834cddd8a3b (diff) | |
| parent | 7ce7d89f48834cefece7804d38fc5d85382edf77 (diff) | |
Merge tag 'v4.10-rc1' into docs-next
Linux 4.10-rc1
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c index dae35a96a694..6c343a933182 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c @@ -34,6 +34,7 @@ struct amdgpu_atpx { static struct amdgpu_atpx_priv { bool atpx_detected; + bool bridge_pm_usable; /* handle for device - and atpx */ acpi_handle dhandle; acpi_handle other_handle; @@ -205,7 +206,11 @@ static int amdgpu_atpx_validate(struct amdgpu_atpx *atpx) atpx->is_hybrid = false; if (valid_bits & ATPX_MS_HYBRID_GFX_SUPPORTED) { printk("ATPX Hybrid Graphics\n"); - atpx->functions.power_cntl = false; + /* + * Disable legacy PM methods only when pcie port PM is usable, + * otherwise the device might fail to power off or power on. + */ + atpx->functions.power_cntl = !amdgpu_atpx_priv.bridge_pm_usable; atpx->is_hybrid = true; } @@ -555,17 +560,25 @@ static bool amdgpu_atpx_detect(void) struct pci_dev *pdev = NULL; bool has_atpx = false; int vga_count = 0; + bool d3_supported = false; + struct pci_dev *parent_pdev; while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) { vga_count++; has_atpx |= (amdgpu_atpx_pci_probe_handle(pdev) == true); + + parent_pdev = pci_upstream_bridge(pdev); + d3_supported |= parent_pdev && parent_pdev->bridge_d3; } while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_OTHER << 8, pdev)) != NULL) { vga_count++; has_atpx |= (amdgpu_atpx_pci_probe_handle(pdev) == true); + + parent_pdev = pci_upstream_bridge(pdev); + d3_supported |= parent_pdev && parent_pdev->bridge_d3; } if (has_atpx && vga_count == 2) { @@ -573,6 +586,7 @@ static bool amdgpu_atpx_detect(void) printk(KERN_INFO "vga_switcheroo: detected switching method %s handle\n", acpi_method_name); amdgpu_atpx_priv.atpx_detected = true; + amdgpu_atpx_priv.bridge_pm_usable = d3_supported; amdgpu_atpx_init(); return true; } |