Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Lukas Wunner and committed by
Bjorn Helgaas
437eb7bf 6ef13824

+27 -27
+1 -27
drivers/pci/hotplug/acpiphp_glue.c
··· 222 222 acpiphp_let_context_go(context); 223 223 } 224 224 225 - /* Check whether the PCI device is managed by native PCIe hotplug driver */ 226 - static bool device_is_managed_by_native_pciehp(struct pci_dev *pdev) 227 - { 228 - acpi_handle tmp; 229 - struct acpi_pci_root *root; 230 - 231 - /* Check whether the PCIe port supports native PCIe hotplug */ 232 - if (!pdev->is_hotplug_bridge) 233 - return false; 234 - 235 - /* 236 - * Check whether native PCIe hotplug has been enabled for 237 - * this PCIe hierarchy. 238 - */ 239 - tmp = acpi_find_root_bridge_handle(pdev); 240 - if (!tmp) 241 - return false; 242 - root = acpi_pci_find_root(tmp); 243 - if (!root) 244 - return false; 245 - if (!(root->osc_control_set & OSC_PCI_EXPRESS_NATIVE_HP_CONTROL)) 246 - return false; 247 - 248 - return true; 249 - } 250 - 251 225 /** 252 226 * acpiphp_add_context - Add ACPIPHP context to an ACPI device object. 253 227 * @handle: ACPI handle of the object to add a context to. ··· 305 331 * expose slots to user space in those cases. 306 332 */ 307 333 if ((acpi_pci_check_ejectable(pbus, handle) || is_dock_device(adev)) 308 - && !(pdev && device_is_managed_by_native_pciehp(pdev))) { 334 + && !(pdev && pdev->is_hotplug_bridge && pciehp_is_native(pdev))) { 309 335 unsigned long long sun; 310 336 int retval; 311 337
+24
drivers/pci/pci-acpi.c
··· 294 294 EXPORT_SYMBOL_GPL(pci_get_hp_params); 295 295 296 296 /** 297 + * pciehp_is_native - Check whether a hotplug port is handled by the OS 298 + * @pdev: Hotplug port to check 299 + * 300 + * Walk up from @pdev to the host bridge, obtain its cached _OSC Control Field 301 + * and return the value of the "PCI Express Native Hot Plug control" bit. 302 + * On failure to obtain the _OSC Control Field return %false. 303 + */ 304 + bool pciehp_is_native(struct pci_dev *pdev) 305 + { 306 + struct acpi_pci_root *root; 307 + acpi_handle handle; 308 + 309 + handle = acpi_find_root_bridge_handle(pdev); 310 + if (!handle) 311 + return false; 312 + 313 + root = acpi_pci_find_root(handle); 314 + if (!root) 315 + return false; 316 + 317 + return root->osc_control_set & OSC_PCI_EXPRESS_NATIVE_HP_CONTROL; 318 + } 319 + 320 + /** 297 321 * pci_acpi_wake_bus - Root bus wakeup notification fork function. 298 322 * @work: Work item to handle. 299 323 */
+2
include/linux/pci_hotplug.h
··· 176 176 #ifdef CONFIG_ACPI 177 177 #include <linux/acpi.h> 178 178 int pci_get_hp_params(struct pci_dev *dev, struct hotplug_params *hpp); 179 + bool pciehp_is_native(struct pci_dev *pdev); 179 180 int acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev, u32 flags); 180 181 int acpi_pci_check_ejectable(struct pci_bus *pbus, acpi_handle handle); 181 182 int acpi_pci_detect_ejectable(acpi_handle handle); ··· 186 185 { 187 186 return -ENODEV; 188 187 } 188 + static inline bool pciehp_is_native(struct pci_dev *pdev) { return true; } 189 189 #endif 190 190 #endif