PCI/ACPI: Evaluate PCI Boot Configuration _DSM
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>
Sat, 15 Jun 2019 00:23:57 +0000 (10:23 +1000)
committerBjorn Helgaas <bhelgaas@google.com>
Fri, 21 Jun 2019 23:11:53 +0000 (18:11 -0500)
Evaluate _DSM Function #5, the "PCI Boot Configuration" function.  If the
result is 0, the OS should preserve any resource assignments made by the
firmware.

Link: https://lore.kernel.org/r/20190615002359.29577-2-benh@kernel.crashing.org
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
[bhelgaas: commit log]
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
drivers/acpi/pci_root.c
include/linux/pci-acpi.h
include/linux/pci.h

index c36781a9b493c1f8fb5bf3de1b37e5ef9b8cbe1e..0d57f817ef1e5f033d5d73e2ba03ec015acba96c 100644 (file)
@@ -894,6 +894,7 @@ struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
        int node = acpi_get_node(device->handle);
        struct pci_bus *bus;
        struct pci_host_bridge *host_bridge;
+       union acpi_object *obj;
 
        info->root = root;
        info->bridge = device;
@@ -930,6 +931,17 @@ struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
        if (!(root->osc_control_set & OSC_PCI_EXPRESS_LTR_CONTROL))
                host_bridge->native_ltr = 0;
 
+       /*
+        * Evaluate the "PCI Boot Configuration" _DSM Function.  If it
+        * exists and returns 0, we must preserve any PCI resource
+        * assignments made by firmware for this host bridge.
+        */
+       obj = acpi_evaluate_dsm(ACPI_HANDLE(bus->bridge), &pci_acpi_dsm_guid, 1,
+                               IGNORE_PCI_BOOT_CONFIG_DSM, NULL);
+       if (obj && obj->type == ACPI_TYPE_INTEGER && obj->integer.value == 0)
+               host_bridge->preserve_config = 1;
+       ACPI_FREE(obj);
+
        pci_scan_child_bus(bus);
        pci_set_host_bridge_release(host_bridge, acpi_pci_root_release_info,
                                    info);
index 8082b612f5612edb0e10b3b54cb8cc9d30306a27..62b7fdcc661c30e03d1650baaea199c3f095bf81 100644 (file)
@@ -107,9 +107,10 @@ static inline void acpiphp_check_host_bridge(struct acpi_device *adev) { }
 #endif
 
 extern const guid_t pci_acpi_dsm_guid;
-#define DEVICE_LABEL_DSM       0x07
-#define RESET_DELAY_DSM                0x08
-#define FUNCTION_DELAY_DSM     0x09
+#define IGNORE_PCI_BOOT_CONFIG_DSM     0x05
+#define DEVICE_LABEL_DSM               0x07
+#define RESET_DELAY_DSM                        0x08
+#define FUNCTION_DELAY_DSM             0x09
 
 #else  /* CONFIG_ACPI */
 static inline void acpi_pci_add_bus(struct pci_bus *bus) { }
index 4a5a84d7bdd43edad868dc8247b8995ca478dec9..5e2b309363a3414d4074a55789e845d5f5cfc471 100644 (file)
@@ -505,6 +505,8 @@ struct pci_host_bridge {
        unsigned int    native_shpc_hotplug:1;  /* OS may use SHPC hotplug */
        unsigned int    native_pme:1;           /* OS may use PCIe PME */
        unsigned int    native_ltr:1;           /* OS may use PCIe LTR */
+       unsigned int    preserve_config:1;      /* Preserve FW resource setup */
+
        /* Resource alignment requirements */
        resource_size_t (*align_resource)(struct pci_dev *dev,
                        const struct resource *res,