diff options
author | Lukas Wunner <lukas@wunner.de> | 2016-10-28 10:52:06 +0200 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2016-11-17 18:47:58 -0600 |
commit | 437eb7bf7b28472f8b7689e166dc1dd691367121 (patch) | |
tree | 38424a7a9621aef9217a38d4c34812cce9595a9b /drivers | |
parent | 6ef13824e0d897858ea4510a2c61b00445922fad (diff) |
ACPI / hotplug / PCI: Make device_is_managed_by_native_pciehp() public
We're about to add runtime PM of hotplug ports, but we need to restrict it
to ports that are handled natively by the OS: If they're handled by the
firmware (which is the case for Thunderbolt on non-Macs), things would
break if the OS put the ports into D3hot behind the firmware's back.
To determine if a hotplug port is handled natively, one has to walk up from
the port to the root bridge and check the cached _OSC Control Field for the
value of the "PCI Express Native Hot Plug control" bit. There's already a
function to do that, device_is_managed_by_native_pciehp(), but it's private
to drivers/pci/hotplug/acpiphp_glue.c and only compiled in if
CONFIG_HOTPLUG_PCI_ACPI is enabled.
Make it public and move it to drivers/pci/pci-acpi.c, so that it is
available in the more general CONFIG_ACPI case.
The function contains a check if the device in question is a hotplug port
and returns false if it's not. The caller we're going to add doesn't need
this as it only calls the function if it actually *is* a hotplug port.
Move the check out of the function into the single existing caller.
Rename it to pciehp_is_native() and add some kerneldoc and polish.
No functional change intended.
Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/pci/hotplug/acpiphp_glue.c | 28 | ||||
-rw-r--r-- | drivers/pci/pci-acpi.c | 24 |
2 files changed, 25 insertions, 27 deletions
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index b286a56e84b3..5ed2dcaa8e27 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -222,32 +222,6 @@ static void acpiphp_post_dock_fixup(struct acpi_device *adev) acpiphp_let_context_go(context); } -/* Check whether the PCI device is managed by native PCIe hotplug driver */ -static bool device_is_managed_by_native_pciehp(struct pci_dev *pdev) -{ - acpi_handle tmp; - struct acpi_pci_root *root; - - /* Check whether the PCIe port supports native PCIe hotplug */ - if (!pdev->is_hotplug_bridge) - return false; - - /* - * Check whether native PCIe hotplug has been enabled for - * this PCIe hierarchy. - */ - tmp = acpi_find_root_bridge_handle(pdev); - if (!tmp) - return false; - root = acpi_pci_find_root(tmp); - if (!root) - return false; - if (!(root->osc_control_set & OSC_PCI_EXPRESS_NATIVE_HP_CONTROL)) - return false; - - return true; -} - /** * acpiphp_add_context - Add ACPIPHP context to an ACPI device object. * @handle: ACPI handle of the object to add a context to. @@ -331,7 +305,7 @@ static acpi_status acpiphp_add_context(acpi_handle handle, u32 lvl, void *data, * expose slots to user space in those cases. */ if ((acpi_pci_check_ejectable(pbus, handle) || is_dock_device(adev)) - && !(pdev && device_is_managed_by_native_pciehp(pdev))) { + && !(pdev && pdev->is_hotplug_bridge && pciehp_is_native(pdev))) { unsigned long long sun; int retval; diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index d966d47c9e80..ed3daa8e7658 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c @@ -294,6 +294,30 @@ int pci_get_hp_params(struct pci_dev *dev, struct hotplug_params *hpp) 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 + * + * 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. + */ +bool pciehp_is_native(struct pci_dev *pdev) +{ + struct acpi_pci_root *root; + acpi_handle handle; + + handle = acpi_find_root_bridge_handle(pdev); + if (!handle) + return false; + + root = acpi_pci_find_root(handle); + if (!root) + return false; + + return root->osc_control_set & OSC_PCI_EXPRESS_NATIVE_HP_CONTROL; +} + +/** * pci_acpi_wake_bus - Root bus wakeup notification fork function. * @work: Work item to handle. */ |