aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorPeter Wu <peter@lekensteyn.nl>2016-08-26 01:00:54 +0200
committerDave Airlie <airlied@redhat.com>2016-08-31 16:54:05 +1000
commit279cf3f23870f7eb8ca071115e06d3d5ca0a2b9e (patch)
tree22742864be6b52c5f6a89a356d125a01e5eb03c5 /drivers
parentLinux 4.8-rc4 (diff)
downloadlinux-dev-279cf3f23870f7eb8ca071115e06d3d5ca0a2b9e.tar.xz
linux-dev-279cf3f23870f7eb8ca071115e06d3d5ca0a2b9e.zip
drm/nouveau/acpi: use DSM if bridge does not support D3cold
Even if PR3 support is available on the bridge, it will not be used if the PCI layer considers it unavailable (i.e. on all laptops from 2013 and 2014). Ensure that this condition is checked to allow a fallback to the Optimus DSM for device poweroff. Initially I wanted to call pci_d3cold_enable before checking bridge_d3 (in case the user changed d3cold_allowed), but that is such an unlikely case and likely fragile anyway. The current patch is suggested by Mika in http://www.spinics.net/lists/linux-pci/msg52599.html Cc: Mika Westerberg <mika.westerberg@linux.intel.com> Signed-off-by: Peter Wu <peter@lekensteyn.nl> Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_acpi.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c
index f2ad17aa33f0..dc57b628e074 100644
--- a/drivers/gpu/drm/nouveau/nouveau_acpi.c
+++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c
@@ -225,6 +225,17 @@ static bool nouveau_pr3_present(struct pci_dev *pdev)
if (!parent_pdev)
return false;
+ if (!parent_pdev->bridge_d3) {
+ /*
+ * Parent PCI bridge is currently not power managed.
+ * Since userspace can change these afterwards to be on
+ * the safe side we stick with _DSM and prevent usage of
+ * _PR3 from the bridge.
+ */
+ pci_d3cold_disable(pdev);
+ return false;
+ }
+
parent_adev = ACPI_COMPANION(&parent_pdev->dev);
if (!parent_adev)
return false;