summaryrefslogtreecommitdiffstats
path: root/drivers/pci/pci-acpi.c
diff options
context:
space:
mode:
authorMika Westerberg <mika.westerberg@linux.intel.com>2018-05-23 17:24:08 -0500
committerBjorn Helgaas <bhelgaas@google.com>2018-06-02 00:18:28 -0500
commit5352a44a561d708f1a975a90f5ce16a054fe265c (patch)
treece141dc89652f25a3288ea4069563ee9b9b18f41 /drivers/pci/pci-acpi.c
parent9310f0dc1c6430ca9e370a8341bea9f5dc85f40b (diff)
downloadlinux-0-day-5352a44a561d708f1a975a90f5ce16a054fe265c.tar.gz
linux-0-day-5352a44a561d708f1a975a90f5ce16a054fe265c.tar.xz
PCI: pciehp: Make pciehp_is_native() stricter
Previously pciehp_is_native() returned true for any PCI device in a hierarchy where _OSC says we can use pciehp. This is incorrect because bridges without PCI_EXP_SLTCAP_HPC capability should be managed by acpiphp instead. Improve pciehp_is_native() to return true only when PCI_EXP_SLTCAP_HPC is set and the pciehp driver is present. In any other case return false to let acpiphp handle those. Suggested-by: Bjorn Helgaas <bhelgaas@google.com> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com> [bhelgaas: remove NULL pointer check] Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/pci/pci-acpi.c')
-rw-r--r--drivers/pci/pci-acpi.c26
1 files changed, 14 insertions, 12 deletions
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index 1abdbf267c196..52b8434d4d6e2 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -370,26 +370,28 @@ EXPORT_SYMBOL_GPL(pci_get_hp_params);
/**
* pciehp_is_native - Check whether a hotplug port is handled by the OS
- * @pdev: Hotplug port to check
+ * @bridge: Hotplug port to check
*
- * Walk up from @pdev to the host bridge, obtain its cached _OSC Control Field
- * and return the value of the "PCI Express Native Hot Plug control" bit.
- * On failure to obtain the _OSC Control Field return %false.
+ * Returns true if the given @bridge is handled by the native PCIe hotplug
+ * driver.
*/
-bool pciehp_is_native(struct pci_dev *pdev)
+bool pciehp_is_native(struct pci_dev *bridge)
{
- struct acpi_pci_root *root;
- acpi_handle handle;
+ const struct pci_host_bridge *host;
+ u32 slot_cap;
- handle = acpi_find_root_bridge_handle(pdev);
- if (!handle)
+ if (!IS_ENABLED(CONFIG_HOTPLUG_PCI_PCIE))
return false;
- root = acpi_pci_find_root(handle);
- if (!root)
+ pcie_capability_read_dword(bridge, PCI_EXP_SLTCAP, &slot_cap);
+ if (!(slot_cap & PCI_EXP_SLTCAP_HPC))
return false;
- return root->osc_control_set & OSC_PCI_EXPRESS_NATIVE_HP_CONTROL;
+ if (pcie_ports_native)
+ return true;
+
+ host = pci_find_host_bridge(bridge->bus);
+ return host->native_pcie_hotplug;
}
/**