aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/hotplug/acpiphp_glue.c14
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);