===================================================================
@@ -224,21 +224,32 @@ static acpi_status acpi_pci_run_osc(acpi
return status;
}
-static acpi_status acpi_pci_query_osc(struct acpi_pci_root *root, u32 flags)
+static acpi_status acpi_pci_query_osc(struct acpi_pci_root *root,
+ u32 support,
+ u32 *control)
{
acpi_status status;
- u32 support_set, capbuf[3];
+ u32 capbuf[3];
+
+ support &= OSC_PCI_SUPPORT_MASKS;
+ support |= root->osc_support_set;
/* do _OSC query for all possible controls */
- support_set = root->osc_support_set | (flags & OSC_PCI_SUPPORT_MASKS);
capbuf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE;
- capbuf[OSC_SUPPORT_TYPE] = support_set;
- capbuf[OSC_CONTROL_TYPE] = OSC_PCI_CONTROL_MASKS;
+ capbuf[OSC_SUPPORT_TYPE] = support;
+ if (control) {
+ *control &= OSC_PCI_CONTROL_MASKS;
+ capbuf[OSC_CONTROL_TYPE] = *control;
+ } else {
+ capbuf[OSC_CONTROL_TYPE] = OSC_PCI_CONTROL_MASKS;
+ }
status = acpi_pci_run_osc(root->device->handle, capbuf);
if (ACPI_SUCCESS(status)) {
- root->osc_support_set = support_set;
+ root->osc_support_set = support;
root->osc_control_qry = capbuf[OSC_CONTROL_TYPE];
+ if (control)
+ *control = capbuf[OSC_CONTROL_TYPE];
root->osc_queried = 1;
}
return status;
@@ -253,7 +264,7 @@ static acpi_status acpi_pci_osc_support(
if (ACPI_FAILURE(status))
return status;
mutex_lock(&osc_lock);
- status = acpi_pci_query_osc(root, flags);
+ status = acpi_pci_query_osc(root, flags, NULL);
mutex_unlock(&osc_lock);
return status;
}
@@ -362,6 +373,35 @@ out:
}
EXPORT_SYMBOL_GPL(acpi_get_pci_dev);
+ /**
+ * acpi_pci_root_osc_query - Get the _OSC bits the kernel can control.
+ * @handle: ACPI handle of a PCI root bridge (or PCIe Root Complex).
+ * @ctrl_mask: Mask of _OSC bits to query and the place to put the result into.
+ **/
+acpi_status acpi_pci_root_osc_query(acpi_handle handle, u32 *ctrl_mask)
+{
+ acpi_status status;
+ acpi_handle tmp;
+ struct acpi_pci_root *root;
+
+ if (!ctrl_mask || !(*ctrl_mask & OSC_PCI_CONTROL_MASKS))
+ return AE_BAD_PARAMETER;
+
+ root = acpi_pci_find_root(handle);
+ if (!root)
+ return AE_NOT_EXIST;
+
+ status = acpi_get_handle(handle, "_OSC", &tmp);
+ if (ACPI_FAILURE(status))
+ return status;
+
+ mutex_lock(&osc_lock);
+ status = acpi_pci_query_osc(root, root->osc_support_set, ctrl_mask);
+ mutex_unlock(&osc_lock);
+
+ return status;
+}
+
/**
* acpi_pci_osc_control_set - commit requested control to Firmware
* @handle: acpi_handle for the target ACPI object
@@ -395,7 +435,7 @@ acpi_status acpi_pci_osc_control_set(acp
/* Need to query controls first before requesting them */
if (!root->osc_queried) {
- status = acpi_pci_query_osc(root, root->osc_support_set);
+ status = acpi_pci_query_osc(root, root->osc_support_set, NULL);
if (ACPI_FAILURE(status))
goto out;
}
===================================================================
@@ -305,6 +305,7 @@ acpi_status acpi_run_osc(acpi_handle han
OSC_PCI_EXPRESS_AER_CONTROL | \
OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL)
+extern acpi_status acpi_pci_root_osc_query(acpi_handle handle, u32 *ctrl_mask);
extern acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 flags);
extern void acpi_early_init(void);