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>
This commit is contained in:
parent
28668f43b8
commit
df42194a9a
@ -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",
|
||||
|
Loading…
Reference in New Issue
Block a user