diff options
Diffstat (limited to 'drivers/pci/hotplug/acpiphp_glue.c')
| -rw-r--r-- | drivers/pci/hotplug/acpiphp_glue.c | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 12f4b351be67..5b1f271c6034 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -226,9 +226,9 @@ static void acpiphp_post_dock_fixup(struct acpi_device *adev) static acpi_status acpiphp_add_context(acpi_handle handle, u32 lvl, void *data, void **rv) { + struct acpi_device *adev = acpi_fetch_acpi_dev(handle); struct acpiphp_bridge *bridge = data; struct acpiphp_context *context; - struct acpi_device *adev; struct acpiphp_slot *slot; struct acpiphp_func *newfunc; acpi_status status = AE_OK; @@ -238,6 +238,9 @@ static acpi_status acpiphp_add_context(acpi_handle handle, u32 lvl, void *data, struct pci_dev *pdev = bridge->pci_dev; u32 val; + if (!adev) + return AE_OK; + status = acpi_evaluate_integer(handle, "_ADR", NULL, &adr); if (ACPI_FAILURE(status)) { if (status != AE_NOT_FOUND) @@ -245,8 +248,6 @@ static acpi_status acpiphp_add_context(acpi_handle handle, u32 lvl, void *data, "can't evaluate _ADR (%#x)\n", status); return AE_OK; } - if (acpi_bus_get_device(handle, &adev)) - return AE_OK; device = (adr >> 16) & 0xffff; function = adr & 0xffff; @@ -410,6 +411,14 @@ static void check_hotplug_bridge(struct acpiphp_slot *slot, struct pci_dev *dev) if (dev->is_hotplug_bridge) return; + /* + * In the PCIe case, only Root Ports and Downstream Ports are capable of + * accommodating hotplug devices, so avoid marking Upstream Ports as + * "hotplug bridges". + */ + if (pci_is_pcie(dev) && pci_pcie_type(dev) == PCI_EXP_TYPE_UPSTREAM) + return; + list_for_each_entry(func, &slot->funcs, sibling) { if (PCI_FUNC(dev->devfn) == func->function) { dev->is_hotplug_bridge = 1; |
