diff options
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/hotplug/acpiphp_glue.c | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 803d9ddd6e75..a33794d9e0dc 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c | |||
@@ -38,6 +38,8 @@ | |||
38 | * - The one in acpiphp_bridge has its refcount elevated by pci_get_slot() | 38 | * - The one in acpiphp_bridge has its refcount elevated by pci_get_slot() |
39 | * when the bridge is scanned and it loses a refcount when the bridge | 39 | * when the bridge is scanned and it loses a refcount when the bridge |
40 | * is removed. | 40 | * is removed. |
41 | * - When a P2P bridge is present, we elevate the refcount on the subordinate | ||
42 | * bus. It loses the refcount when the the driver unloads. | ||
41 | */ | 43 | */ |
42 | 44 | ||
43 | #include <linux/init.h> | 45 | #include <linux/init.h> |
@@ -440,6 +442,12 @@ static void add_p2p_bridge(acpi_handle *handle, struct pci_dev *pci_dev) | |||
440 | goto err; | 442 | goto err; |
441 | } | 443 | } |
442 | 444 | ||
445 | /* | ||
446 | * Grab a ref to the subordinate PCI bus in case the bus is | ||
447 | * removed via PCI core logical hotplug. The ref pins the bus | ||
448 | * (which we access during module unload). | ||
449 | */ | ||
450 | get_device(&bridge->pci_bus->dev); | ||
443 | spin_lock_init(&bridge->res_lock); | 451 | spin_lock_init(&bridge->res_lock); |
444 | 452 | ||
445 | init_bridge_misc(bridge); | 453 | init_bridge_misc(bridge); |
@@ -619,6 +627,12 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge) | |||
619 | slot = next; | 627 | slot = next; |
620 | } | 628 | } |
621 | 629 | ||
630 | /* | ||
631 | * Only P2P bridges have a pci_dev | ||
632 | */ | ||
633 | if (bridge->pci_dev) | ||
634 | put_device(&bridge->pci_bus->dev); | ||
635 | |||
622 | pci_dev_put(bridge->pci_dev); | 636 | pci_dev_put(bridge->pci_dev); |
623 | list_del(&bridge->list); | 637 | list_del(&bridge->list); |
624 | kfree(bridge); | 638 | kfree(bridge); |