]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
PCI: Move PRESERVE_BOOT_CONFIG _DSM evaluation to pci_register_host_bridge()
authorVidya Sagar <vidyas@nvidia.com>
Wed, 8 May 2024 17:41:35 +0000 (23:11 +0530)
committerBjorn Helgaas <bhelgaas@google.com>
Mon, 3 Jun 2024 21:13:38 +0000 (16:13 -0500)
Move the PRESERVE_BOOT_CONFIG _DSM evaluation from acpi_pci_root_create()
to pci_register_host_bridge().

This will help unify the ACPI _DSM path and the DT-based
"linux,pci-probe-only" paths.

This should be safe because it happens earlier than it used to:

    acpi_pci_root_create
      pci_create_root_bus
        pci_register_host_bridge
  +       bridge->preserve_config = pci_preserve_config(bridge)
            pci_acpi_preserve_config
  +           acpi_evaluate_dsm_typed(DSM_PCI_PRESERVE_BOOT_CONFIG)
  -   acpi_evaluate_dsm_typed(DSM_PCI_PRESERVE_BOOT_CONFIG)

No functional change intended.

Link: https://lore.kernel.org/r/20240508174138.3630283-2-vidyas@nvidia.com
Signed-off-by: Vidya Sagar <vidyas@nvidia.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
drivers/acpi/pci_root.c
drivers/pci/pci-acpi.c
drivers/pci/pci.h
drivers/pci/probe.c

index 58b89b8d950ed7a83bedd06087000104956030a3..ddc2b3e8911169b2909033f0a6eb513e414eac3c 100644 (file)
@@ -1008,7 +1008,6 @@ 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;
@@ -1050,17 +1049,6 @@ struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
        if (!(root->osc_ext_control_set & OSC_CXL_ERROR_REPORTING_CONTROL))
                host_bridge->native_cxl_error = 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_typed(ACPI_HANDLE(bus->bridge), &pci_acpi_dsm_guid, 1,
-                                     DSM_PCI_PRESERVE_BOOT_CONFIG, NULL, ACPI_TYPE_INTEGER);
-       if (obj && obj->integer.value == 0)
-               host_bridge->preserve_config = 1;
-       ACPI_FREE(obj);
-
        acpi_dev_power_up_children_with_adr(device);
 
        pci_scan_child_bus(bus);
index 004575091596462f69224ffc3d3213c68fe17de9..9cc447da9475d8b673b5bcc83ff3a729a7cff5ad 100644 (file)
@@ -119,6 +119,28 @@ phys_addr_t acpi_pci_root_get_mcfg_addr(acpi_handle handle)
        return (phys_addr_t)mcfg_addr;
 }
 
+bool pci_acpi_preserve_config(struct pci_host_bridge *host_bridge)
+{
+       if (ACPI_HANDLE(&host_bridge->dev)) {
+               union acpi_object *obj;
+
+               /*
+                * 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_typed(ACPI_HANDLE(&host_bridge->dev),
+                                             &pci_acpi_dsm_guid,
+                                             1, DSM_PCI_PRESERVE_BOOT_CONFIG,
+                                             NULL, ACPI_TYPE_INTEGER);
+               if (obj && obj->integer.value == 0)
+                       return true;
+               ACPI_FREE(obj);
+       }
+
+       return false;
+}
+
 /* _HPX PCI Setting Record (Type 0); same as _HPP */
 struct hpx_type0 {
        u32 revision;           /* Not present in _HPP */
index fd44565c47562868bacdad9b1bb2e017cae09795..0df6bab385cd59910040cfb232e505ab431df683 100644 (file)
@@ -732,6 +732,7 @@ static inline void pci_restore_aer_state(struct pci_dev *dev) { }
 #endif
 
 #ifdef CONFIG_ACPI
+bool pci_acpi_preserve_config(struct pci_host_bridge *bridge);
 int pci_acpi_program_hp_params(struct pci_dev *dev);
 extern const struct attribute_group pci_dev_acpi_attr_group;
 void pci_set_acpi_fwnode(struct pci_dev *dev);
@@ -745,6 +746,10 @@ int acpi_pci_wakeup(struct pci_dev *dev, bool enable);
 bool acpi_pci_need_resume(struct pci_dev *dev);
 pci_power_t acpi_pci_choose_state(struct pci_dev *pdev);
 #else
+static inline bool pci_acpi_preserve_config(struct pci_host_bridge *bridge)
+{
+       return false;
+}
 static inline int pci_dev_acpi_reset(struct pci_dev *dev, bool probe)
 {
        return -ENOTTY;
index 8e696e547565c3bbb7700c8c61196d3e435f66f2..fd6525277061f059042579792a518fd443896540 100644 (file)
@@ -889,6 +889,14 @@ static void pci_set_bus_msi_domain(struct pci_bus *bus)
        dev_set_msi_domain(&bus->dev, d);
 }
 
+static bool pci_preserve_config(struct pci_host_bridge *host_bridge)
+{
+       if (pci_acpi_preserve_config(host_bridge))
+               return true;
+
+       return false;
+}
+
 static int pci_register_host_bridge(struct pci_host_bridge *bridge)
 {
        struct device *parent = bridge->dev.parent;
@@ -983,6 +991,9 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
        if (nr_node_ids > 1 && pcibus_to_node(bus) == NUMA_NO_NODE)
                dev_warn(&bus->dev, "Unknown NUMA node; performance will be reduced\n");
 
+       /* Check if the boot configuration by FW needs to be preserved */
+       bridge->preserve_config = pci_preserve_config(bridge);
+
        /* Coalesce contiguous windows */
        resource_list_for_each_entry_safe(window, n, &resources) {
                if (list_is_last(&window->node, &resources))