Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit df42194a authored by Peter Wu's avatar Peter Wu Committed by Ben Skeggs
Browse files

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: default avatarHans de Goede <hdegoede@redhat.com>
Signed-off-by: default avatarPeter Wu <peter@lekensteyn.nl>
Acked-by: default avatarDave Airlie <airlied@redhat.com>
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 28668f43
Loading
Loading
Loading
Loading
+26 −32
Original line number Diff line number Diff line
@@ -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",