From cdfcc572be0a8b423cecfb4ab5fd735fafe9c54a Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Tue, 30 Oct 2012 14:31:38 -0600 Subject: PCI: Add pci_stop_and_remove_root_bus() It supports both PCI root bus and PCI bus under PCI bridge. Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- drivers/pci/remove.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'drivers/pci/remove.c') diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index 513972f3ed13..7c0fd9252e6f 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c @@ -111,3 +111,39 @@ void pci_stop_and_remove_bus_device(struct pci_dev *dev) pci_remove_bus_device(dev); } EXPORT_SYMBOL(pci_stop_and_remove_bus_device); + +void pci_stop_root_bus(struct pci_bus *bus) +{ + struct pci_dev *child, *tmp; + struct pci_host_bridge *host_bridge; + + if (!pci_is_root_bus(bus)) + return; + + host_bridge = to_pci_host_bridge(bus->bridge); + list_for_each_entry_safe_reverse(child, tmp, + &bus->devices, bus_list) + pci_stop_bus_device(child); + + /* stop the host bridge */ + device_del(&host_bridge->dev); +} + +void pci_remove_root_bus(struct pci_bus *bus) +{ + struct pci_dev *child, *tmp; + struct pci_host_bridge *host_bridge; + + if (!pci_is_root_bus(bus)) + return; + + host_bridge = to_pci_host_bridge(bus->bridge); + list_for_each_entry_safe(child, tmp, + &bus->devices, bus_list) + pci_remove_bus_device(child); + pci_remove_bus(bus); + host_bridge->bus = NULL; + + /* remove the host bridge */ + put_device(&host_bridge->dev); +} -- cgit v1.2.3