drm/nouveau/acpi: ensure matching ACPI handle and supported functions
authorPeter Wu <peter@lekensteyn.nl>
Fri, 15 Jul 2016 13:12:15 +0000 (15:12 +0200)
committerBen Skeggs <bskeggs@redhat.com>
Sat, 30 Jul 2016 08:19:29 +0000 (18:19 +1000)
Ensure that the returned set of supported DSM functions (MUX, Optimus)
match the ACPI handle that is set in nouveau_dsm_pci_probe.

As there are no machines with a MUX function on just one PCI device and
an Optimus on another, there should not be a functional impact. This
change however makes this implicit assumption more obvious.

Convert int to bool and rename has_dsm to has_mux while at it. Let the
caller set nouveau_dsm_priv.dhandle as needed.

 v2: pass dhandle to the caller.

Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Peter Wu <peter@lekensteyn.nl>
Acked-by: Dave Airlie <airlied@redhat.com
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/nouveau_acpi.c

index db76b94..886a67c 100644 (file)
@@ -57,9 +57,6 @@ bool nouveau_is_v1_dsm(void) {
        return nouveau_dsm_priv.dsm_detected;
 }
 
-#define NOUVEAU_DSM_HAS_MUX 0x1
-#define NOUVEAU_DSM_HAS_OPT 0x2
-
 #ifdef CONFIG_VGA_SWITCHEROO
 static const char nouveau_dsm_muid[] = {
        0xA0, 0xA0, 0x95, 0x9D, 0x60, 0x00, 0x48, 0x4D,
@@ -212,26 +209,33 @@ static const struct vga_switcheroo_handler nouveau_dsm_handler = {
        .get_client_id = nouveau_dsm_get_client_id,
 };
 
-static int nouveau_dsm_pci_probe(struct pci_dev *pdev)
+static void nouveau_dsm_pci_probe(struct pci_dev *pdev, acpi_handle *dhandle_out,
+                                 bool *has_mux, bool *has_opt)
 {
        acpi_handle dhandle;
-       int retval = 0;
+       bool supports_mux;
+       bool supports_opt;
 
        dhandle = ACPI_HANDLE(&pdev->dev);
        if (!dhandle)
-               return false;
+               return;
 
        if (!acpi_has_method(dhandle, "_DSM"))
-               return false;
+               return;
 
-       if (acpi_check_dsm(dhandle, nouveau_dsm_muid, 0x00000102,
-                          1 << NOUVEAU_DSM_POWER))
-               retval |= NOUVEAU_DSM_HAS_MUX;
+       supports_mux = acpi_check_dsm(dhandle, nouveau_dsm_muid, 0x00000102,
+                                     1 << NOUVEAU_DSM_POWER);
+       supports_opt = nouveau_check_optimus_dsm(dhandle);
 
-       if (nouveau_check_optimus_dsm(dhandle))
-               retval |= NOUVEAU_DSM_HAS_OPT;
+       /* Does not look like a Nvidia device. */
+       if (!supports_mux && !supports_opt)
+               return;
 
-       if (retval & NOUVEAU_DSM_HAS_OPT) {
+       *dhandle_out = dhandle;
+       *has_mux = supports_mux;
+       *has_opt = supports_opt;
+
+       if (supports_opt) {
                uint32_t result;
                nouveau_optimus_dsm(dhandle, NOUVEAU_DSM_OPTIMUS_CAPS, 0,
                                    &result);
@@ -240,10 +244,6 @@ static int nouveau_dsm_pci_probe(struct pci_dev *pdev)
                         (result & OPTIMUS_DYNAMIC_PWR_CAP) ? "dynamic power, " : "",
                         (result & OPTIMUS_HDA_CODEC_MASK) ? "hda bios codec supported" : "");
        }
-       if (retval)
-               nouveau_dsm_priv.dhandle = dhandle;
-
-       return retval;
 }
 
 static bool nouveau_dsm_detect(void)
@@ -251,11 +251,11 @@ static bool nouveau_dsm_detect(void)
        char acpi_method_name[255] = { 0 };
        struct acpi_buffer buffer = {sizeof(acpi_method_name), acpi_method_name};
        struct pci_dev *pdev = NULL;
-       int has_dsm = 0;
-       int has_optimus = 0;
+       acpi_handle dhandle = NULL;
+       bool has_mux = false;
+       bool has_optimus = false;
        int vga_count = 0;
        bool guid_valid;
-       int retval;
        bool ret = false;
 
        /* lookup the MXM GUID */
@@ -268,32 +268,26 @@ static bool nouveau_dsm_detect(void)
        while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) {
                vga_count++;
 
-               retval = nouveau_dsm_pci_probe(pdev);
-               if (retval & NOUVEAU_DSM_HAS_MUX)
-                       has_dsm |= 1;
-               if (retval & NOUVEAU_DSM_HAS_OPT)
-                       has_optimus = 1;
+               nouveau_dsm_pci_probe(pdev, &dhandle, &has_mux, &has_optimus);
        }
 
        while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_3D << 8, pdev)) != NULL) {
                vga_count++;
 
-               retval = nouveau_dsm_pci_probe(pdev);
-               if (retval & NOUVEAU_DSM_HAS_MUX)
-                       has_dsm |= 1;
-               if (retval & NOUVEAU_DSM_HAS_OPT)
-                       has_optimus = 1;
+               nouveau_dsm_pci_probe(pdev, &dhandle, &has_mux, &has_optimus);
        }
 
        /* find the optimus DSM or the old v1 DSM */
-       if (has_optimus == 1) {
+       if (has_optimus) {
+               nouveau_dsm_priv.dhandle = dhandle;
                acpi_get_name(nouveau_dsm_priv.dhandle, ACPI_FULL_PATHNAME,
                        &buffer);
                printk(KERN_INFO "VGA switcheroo: detected Optimus DSM method %s handle\n",
                        acpi_method_name);
                nouveau_dsm_priv.optimus_detected = true;
                ret = true;
-       } else if (vga_count == 2 && has_dsm && guid_valid) {
+       } else if (vga_count == 2 && has_mux && guid_valid) {
+               nouveau_dsm_priv.dhandle = dhandle;
                acpi_get_name(nouveau_dsm_priv.dhandle, ACPI_FULL_PATHNAME,
                        &buffer);
                printk(KERN_INFO "VGA switcheroo: detected DSM switching method %s handle\n",