aboutsummaryrefslogtreecommitdiff
path: root/drivers/pci/remove.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/remove.c')
-rw-r--r--drivers/pci/remove.c21
1 files changed, 16 insertions, 5 deletions
diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c
index 1576851028db..8bd76c9ba21c 100644
--- a/drivers/pci/remove.c
+++ b/drivers/pci/remove.c
@@ -7,8 +7,6 @@ static void pci_free_resources(struct pci_dev *dev)
{
int i;
- msi_remove_pci_irq_vectors(dev);
-
pci_cleanup_rom(dev);
for (i = 0; i < PCI_NUM_RESOURCES; i++) {
struct resource *res = dev->resource + i;
@@ -24,7 +22,7 @@ static void pci_stop_dev(struct pci_dev *dev)
if (dev->is_added) {
pci_proc_detach_device(dev);
pci_remove_sysfs_dev_files(dev);
- device_del(&dev->dev);
+ device_release_driver(&dev->dev);
dev->is_added = 0;
}
@@ -34,6 +32,11 @@ static void pci_stop_dev(struct pci_dev *dev)
static void pci_destroy_dev(struct pci_dev *dev)
{
+ if (!dev->dev.kobj.parent)
+ return;
+
+ device_del(&dev->dev);
+
down_write(&pci_bus_sem);
list_del(&dev->bus_list);
up_write(&pci_bus_sem);
@@ -112,6 +115,14 @@ void pci_stop_and_remove_bus_device(struct pci_dev *dev)
}
EXPORT_SYMBOL(pci_stop_and_remove_bus_device);
+void pci_stop_and_remove_bus_device_locked(struct pci_dev *dev)
+{
+ pci_lock_rescan_remove();
+ pci_stop_and_remove_bus_device(dev);
+ pci_unlock_rescan_remove();
+}
+EXPORT_SYMBOL_GPL(pci_stop_and_remove_bus_device_locked);
+
void pci_stop_root_bus(struct pci_bus *bus)
{
struct pci_dev *child, *tmp;
@@ -126,7 +137,7 @@ void pci_stop_root_bus(struct pci_bus *bus)
pci_stop_bus_device(child);
/* stop the host bridge */
- device_del(&host_bridge->dev);
+ device_release_driver(&host_bridge->dev);
}
void pci_remove_root_bus(struct pci_bus *bus)
@@ -145,5 +156,5 @@ void pci_remove_root_bus(struct pci_bus *bus)
host_bridge->bus = NULL;
/* remove the host bridge */
- put_device(&host_bridge->dev);
+ device_unregister(&host_bridge->dev);
}