From 831e34cf02900a32819f135432946db260a78f55 Mon Sep 17 00:00:00 2001 From: Emil Velikov Date: Sun, 6 Oct 2013 22:40:43 +0100 Subject: [PATCH] drm/nouveau: consider CLASS_DISPLAY_3D devices while detecting dsm/optimus The present code assumes that optimus is present whenever two VGA (PCI_CLASS_DISPLAY_VGA) devices are present. This does not seem to be the case of newer laptops with optimus, in which case the nvidia gpu is a PCI_CLASS_DISPLAY_3D device. Rework the logic so that we count both VGA and 3D devices, when contemplating if optimus is present on the platform. v2: Use a pci_get_class derivative, which takes a mask in order to avoid looping through all possible devices twice - for VGA and 3D. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=70208 Signed-off-by: Emil Velikov --- drivers/gpu/drm/nouveau/nouveau_acpi.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c index d97f200..e66b8df 100644 --- a/drivers/gpu/drm/nouveau/nouveau_acpi.c +++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c @@ -260,6 +260,23 @@ static int nouveau_dsm_pci_probe(struct pci_dev *pdev) return retval; } +static inline struct pci_dev *nouveau_pci_get_class_masked(unsigned int class, + unsigned int mask, + struct pci_dev *from) +{ + struct pci_device_id id = { + .vendor = PCI_ANY_ID, + .device = PCI_ANY_ID, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .class_mask = mask, + .class = class, + }; + + return pci_get_dev_by_id(&id, from); +} + + static bool nouveau_dsm_detect(void) { char acpi_method_name[255] = { 0 }; @@ -279,7 +296,11 @@ static bool nouveau_dsm_detect(void) printk("MXM: GUID detected in BIOS\n"); /* now do DSM detection */ - while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) { + + while ((pdev = nouveau_pci_get_class_masked(PCI_BASE_CLASS_DISPLAY << 16, + ~(PCI_CLASS_DISPLAY_VGA | + PCI_CLASS_DISPLAY_3D) << 8, + pdev)) != NULL) { vga_count++; retval = nouveau_dsm_pci_probe(pdev); -- 1.8.4