diff options
author | Peter Wu <peter@lekensteyn.nl> | 2016-07-15 15:12:15 +0200 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2016-07-30 10:19:29 +0200 |
commit | df42194a9ac2678bf086c2c5372e125e742b0ee7 (patch) | |
tree | dad115f02e302179e8eb4be7fb87a8322fd7f858 /drivers/gpu | |
parent | drm/nouveau/fbcon: fix font width not divisible by 8 (diff) | |
download | linux-df42194a9ac2678bf086c2c5372e125e742b0ee7.tar.xz linux-df42194a9ac2678bf086c2c5372e125e742b0ee7.zip |
drm/nouveau/acpi: ensure matching ACPI handle and supported functions
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>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_acpi.c | 58 |
1 files changed, 26 insertions, 32 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c index db76b94e6e26..886a67c18a6c 100644 --- a/drivers/gpu/drm/nouveau/nouveau_acpi.c +++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c @@ -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", |