aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/drivers/pci/pci-acpi.c
diff options
context:
space:
mode:
authorShanker Donthineni <sdonthineni@nvidia.com>2021-08-17 23:34:58 +0530
committerBjorn Helgaas <bhelgaas@google.com>2021-08-18 17:16:46 -0500
commit375553a93201a58a52f142eab19545a07aa1eaf5 (patch)
tree65b05651a18791e8a770264ada2f33b63f84c9cb /drivers/pci/pci-acpi.c
parentPCI: Use acpi_pci_power_manageable() (diff)
downloadwireguard-linux-375553a93201a58a52f142eab19545a07aa1eaf5.tar.xz
wireguard-linux-375553a93201a58a52f142eab19545a07aa1eaf5.zip
PCI: Setup ACPI fwnode early and at the same time with OF
Previously, the ACPI_COMPANION() of a pci_dev was usually set by acpi_bind_one() in this path: pci_device_add pci_configure_device pci_init_capabilities device_add device_platform_notify acpi_platform_notify acpi_device_notify # KOBJ_ADD acpi_bind_one ACPI_COMPANION_SET However, things like pci_configure_device() and pci_init_capabilities() that run before device_add() need the ACPI_COMPANION, e.g., acpi_pci_bridge_d3() uses a _DSD method to learn about D3 support. These places had special-case code to manually look up the ACPI_COMPANION. Set the ACPI_COMPANION earlier, in pci_setup_device(), so it will be available while configuring the device. This covers both paths to creating pci_dev objects: pci_scan_single_device # for normal non-SR-IOV devices pci_scan_device pci_setup_device pci_set_acpi_fwnode pci_device_add pci_iov_add_virtfn # for SR-IOV virtual functions pci_setup_device pci_set_acpi_fwnode Also move the OF fwnode setup to the same spot. [bhelgaas: commit log] Link: https://lore.kernel.org/r/20210817180500.1253-8-ameynarkhede03@gmail.com Signed-off-by: Shanker Donthineni <sdonthineni@nvidia.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Alex Williamson <alex.williamson@redhat.com>
Diffstat (limited to 'drivers/pci/pci-acpi.c')
-rw-r--r--drivers/pci/pci-acpi.c34
1 files changed, 12 insertions, 22 deletions
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index af2341d98860..c27dbb2294e3 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -952,46 +952,36 @@ static bool acpi_pci_power_manageable(struct pci_dev *dev)
static bool acpi_pci_bridge_d3(struct pci_dev *dev)
{
- const struct fwnode_handle *fwnode;
+ const union acpi_object *obj;
struct acpi_device *adev;
- struct pci_dev *root;
- u8 val;
+ struct pci_dev *rpdev;
if (!dev->is_hotplug_bridge)
return false;
/* Assume D3 support if the bridge is power-manageable by ACPI. */
- pci_set_acpi_fwnode(dev);
-
if (acpi_pci_power_manageable(dev))
return true;
/*
- * Look for a special _DSD property for the root port and if it
- * is set we know the hierarchy behind it supports D3 just fine.
+ * The ACPI firmware will provide the device-specific properties through
+ * _DSD configuration object. Look for the 'HotPlugSupportInD3' property
+ * for the root port and if it is set we know the hierarchy behind it
+ * supports D3 just fine.
*/
- root = pcie_find_root_port(dev);
- if (!root)
+ rpdev = pcie_find_root_port(dev);
+ if (!rpdev)
return false;
- adev = ACPI_COMPANION(&root->dev);
- if (root == dev) {
- /*
- * It is possible that the ACPI companion is not yet bound
- * for the root port so look it up manually here.
- */
- if (!adev && !pci_dev_is_added(root))
- adev = acpi_pci_find_companion(&root->dev);
- }
-
+ adev = ACPI_COMPANION(&rpdev->dev);
if (!adev)
return false;
- fwnode = acpi_fwnode_handle(adev);
- if (fwnode_property_read_u8(fwnode, "HotPlugSupportInD3", &val))
+ if (acpi_dev_get_property(adev, "HotPlugSupportInD3",
+ ACPI_TYPE_INTEGER, &obj) < 0)
return false;
- return val == 1;
+ return obj->integer.value == 1;
}
static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state)