diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2019-06-15 02:23:57 +0200 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2019-06-22 01:11:53 +0200 |
commit | a78cf9657ba5426f54aa93a067c10d097944c082 (patch) | |
tree | aa6cbc8b7f5808ff37b46a51ab37de03964fea79 | |
parent | Linux 5.2-rc1 (diff) | |
download | linux-a78cf9657ba5426f54aa93a067c10d097944c082.tar.xz linux-a78cf9657ba5426f54aa93a067c10d097944c082.zip |
PCI/ACPI: Evaluate PCI Boot Configuration _DSM
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>
-rw-r--r-- | drivers/acpi/pci_root.c | 12 | ||||
-rw-r--r-- | include/linux/pci-acpi.h | 7 | ||||
-rw-r--r-- | include/linux/pci.h | 2 |
3 files changed, 18 insertions, 3 deletions
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index c36781a9b493..0d57f817ef1e 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -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); diff --git a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h index 8082b612f561..62b7fdcc661c 100644 --- a/include/linux/pci-acpi.h +++ b/include/linux/pci-acpi.h @@ -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) { } diff --git a/include/linux/pci.h b/include/linux/pci.h index 4a5a84d7bdd4..5e2b309363a3 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -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, |