Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cdfcc572 authored by Yinghai Lu's avatar Yinghai Lu Committed by Bjorn Helgaas
Browse files

PCI: Add pci_stop_and_remove_root_bus()



It supports both PCI root bus and PCI bus under PCI bridge.

Signed-off-by: default avatarYinghai Lu <yinghai@kernel.org>
Signed-off-by: default avatarBjorn Helgaas <bhelgaas@google.com>
parent 62a08c5a
Loading
Loading
Loading
Loading
+36 −0
Original line number Diff line number Diff line
@@ -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);
}
+2 −0
Original line number Diff line number Diff line
@@ -712,6 +712,8 @@ extern struct pci_dev *pci_dev_get(struct pci_dev *dev);
extern void pci_dev_put(struct pci_dev *dev);
extern void pci_remove_bus(struct pci_bus *b);
extern void pci_stop_and_remove_bus_device(struct pci_dev *dev);
void pci_stop_root_bus(struct pci_bus *bus);
void pci_remove_root_bus(struct pci_bus *bus);
void pci_setup_cardbus(struct pci_bus *bus);
extern void pci_sort_breadthfirst(void);
#define dev_is_pci(d) ((d)->bus == &pci_bus_type)