diff mbox

[linux-pm,7/8] ACPI / PCI: Do not preserve _OSC control bits returned by a query (v2)

Message ID 201008050151.27501.rjw@sisk.pl (mailing list archive)
State New, archived
Headers show

Commit Message

Rafael Wysocki Aug. 4, 2010, 11:51 p.m. UTC
None
diff mbox

Patch

Index: linux-2.6/drivers/acpi/pci_root.c
===================================================================
--- linux-2.6.orig/drivers/acpi/pci_root.c
+++ linux-2.6/drivers/acpi/pci_root.c
@@ -472,6 +472,30 @@  out:
 }
 EXPORT_SYMBOL(acpi_pci_osc_control_set);
 
+/**
+ * acpi_pci_osc_control_set_safe - Query and set _OSC control bit mask.
+ * @handle: ACPI handle of a PCI root bridge (or PCIe Root Complex).
+ * @flags: Mask of _OSC bits to query and set.
+ *
+ * Check if the BIOS is willing to grant control of the features represented
+ * by @flags and request control of these features from it.
+ **/
+acpi_status acpi_pci_osc_control_set_safe(acpi_handle handle, u32 flags)
+{
+	acpi_status status;
+	u32 ctrl = flags;
+
+	status = acpi_pci_osc_control_query(handle, &flags);
+	if (ACPI_FAILURE(status))
+		return status;
+	if ((ctrl & flags) != ctrl)
+		return AE_SUPPORT;
+
+	status = acpi_pci_osc_control_set(handle, flags);
+	return status;
+}
+EXPORT_SYMBOL(acpi_pci_osc_control_set_safe);
+
 static int __devinit acpi_pci_root_add(struct acpi_device *device)
 {
 	unsigned long long segment, bus;
Index: linux-2.6/drivers/pci/hotplug/acpi_pcihp.c
===================================================================
--- linux-2.6.orig/drivers/pci/hotplug/acpi_pcihp.c
+++ linux-2.6/drivers/pci/hotplug/acpi_pcihp.c
@@ -358,7 +358,7 @@  int acpi_get_hp_hw_control_from_firmware
 		acpi_get_name(handle, ACPI_FULL_PATHNAME, &string);
 		dbg("Trying to get hotplug control for %s\n",
 				(char *)string.pointer);
-		status = acpi_pci_osc_control_set(handle, flags);
+		status = acpi_pci_osc_control_set_safe(handle, flags);
 		if (ACPI_SUCCESS(status))
 			goto got_one;
 		if (status == AE_SUPPORT)
Index: linux-2.6/include/linux/acpi.h
===================================================================
--- linux-2.6.orig/include/linux/acpi.h
+++ linux-2.6/include/linux/acpi.h
@@ -307,6 +307,7 @@  acpi_status acpi_run_osc(acpi_handle han
 
 extern acpi_status acpi_pci_osc_control_query(acpi_handle handle, u32 *mask);
 extern acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 flags);
+extern acpi_status acpi_pci_osc_control_set_safe(acpi_handle handle, u32 flags);
 extern void acpi_early_init(void);
 
 #else	/* !CONFIG_ACPI */