diff options
author | Yinghai Lu <yinghai@kernel.org> | 2012-10-30 16:31:38 -0400 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2012-11-03 18:26:37 -0400 |
commit | cdfcc572be0a8b423cecfb4ab5fd735fafe9c54a (patch) | |
tree | df188f735b592a2a359969d451ed3dc51ac6e55a | |
parent | 62a08c5a3173c4462239804b959c0d29dc74493b (diff) |
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 <yinghai@kernel.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
-rw-r--r-- | drivers/pci/remove.c | 36 | ||||
-rw-r--r-- | include/linux/pci.h | 2 |
2 files changed, 38 insertions, 0 deletions
diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index 513972f3ed1..7c0fd9252e6 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) | |||
111 | pci_remove_bus_device(dev); | 111 | pci_remove_bus_device(dev); |
112 | } | 112 | } |
113 | EXPORT_SYMBOL(pci_stop_and_remove_bus_device); | 113 | EXPORT_SYMBOL(pci_stop_and_remove_bus_device); |
114 | |||
115 | void pci_stop_root_bus(struct pci_bus *bus) | ||
116 | { | ||
117 | struct pci_dev *child, *tmp; | ||
118 | struct pci_host_bridge *host_bridge; | ||
119 | |||
120 | if (!pci_is_root_bus(bus)) | ||
121 | return; | ||
122 | |||
123 | host_bridge = to_pci_host_bridge(bus->bridge); | ||
124 | list_for_each_entry_safe_reverse(child, tmp, | ||
125 | &bus->devices, bus_list) | ||
126 | pci_stop_bus_device(child); | ||
127 | |||
128 | /* stop the host bridge */ | ||
129 | device_del(&host_bridge->dev); | ||
130 | } | ||
131 | |||
132 | void pci_remove_root_bus(struct pci_bus *bus) | ||
133 | { | ||
134 | struct pci_dev *child, *tmp; | ||
135 | struct pci_host_bridge *host_bridge; | ||
136 | |||
137 | if (!pci_is_root_bus(bus)) | ||
138 | return; | ||
139 | |||
140 | host_bridge = to_pci_host_bridge(bus->bridge); | ||
141 | list_for_each_entry_safe(child, tmp, | ||
142 | &bus->devices, bus_list) | ||
143 | pci_remove_bus_device(child); | ||
144 | pci_remove_bus(bus); | ||
145 | host_bridge->bus = NULL; | ||
146 | |||
147 | /* remove the host bridge */ | ||
148 | put_device(&host_bridge->dev); | ||
149 | } | ||
diff --git a/include/linux/pci.h b/include/linux/pci.h index f543eb3b1c0..786094254d5 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
@@ -712,6 +712,8 @@ extern struct pci_dev *pci_dev_get(struct pci_dev *dev); | |||
712 | extern void pci_dev_put(struct pci_dev *dev); | 712 | extern void pci_dev_put(struct pci_dev *dev); |
713 | extern void pci_remove_bus(struct pci_bus *b); | 713 | extern void pci_remove_bus(struct pci_bus *b); |
714 | extern void pci_stop_and_remove_bus_device(struct pci_dev *dev); | 714 | extern void pci_stop_and_remove_bus_device(struct pci_dev *dev); |
715 | void pci_stop_root_bus(struct pci_bus *bus); | ||
716 | void pci_remove_root_bus(struct pci_bus *bus); | ||
715 | void pci_setup_cardbus(struct pci_bus *bus); | 717 | void pci_setup_cardbus(struct pci_bus *bus); |
716 | extern void pci_sort_breadthfirst(void); | 718 | extern void pci_sort_breadthfirst(void); |
717 | #define dev_is_pci(d) ((d)->bus == &pci_bus_type) | 719 | #define dev_is_pci(d) ((d)->bus == &pci_bus_type) |