remove.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include <linux/pci.h>
  3. #include <linux/module.h>
  4. #include <linux/of.h>
  5. #include <linux/of_platform.h>
  6. #include <linux/platform_device.h>
  7. #include "pci.h"
  8. static void pci_free_resources(struct pci_dev *dev)
  9. {
  10. struct resource *res;
  11. pci_dev_for_each_resource(dev, res) {
  12. if (res->parent)
  13. release_resource(res);
  14. }
  15. }
  16. static void pci_stop_dev(struct pci_dev *dev)
  17. {
  18. pci_pme_active(dev, false);
  19. if (!pci_dev_test_and_clear_added(dev))
  20. return;
  21. device_release_driver(&dev->dev);
  22. pci_proc_detach_device(dev);
  23. pci_remove_sysfs_dev_files(dev);
  24. of_pci_remove_node(dev);
  25. }
  26. static void pci_destroy_dev(struct pci_dev *dev)
  27. {
  28. if (pci_dev_test_and_set_removed(dev))
  29. return;
  30. pci_doe_sysfs_teardown(dev);
  31. pci_npem_remove(dev);
  32. /*
  33. * While device is in D0 drop the device from TSM link operations
  34. * including unbind and disconnect (IDE + SPDM teardown).
  35. */
  36. pci_tsm_destroy(dev);
  37. device_del(&dev->dev);
  38. down_write(&pci_bus_sem);
  39. list_del(&dev->bus_list);
  40. up_write(&pci_bus_sem);
  41. pci_doe_destroy(dev);
  42. pci_ide_destroy(dev);
  43. pcie_aspm_exit_link_state(dev);
  44. pci_bridge_d3_update(dev);
  45. pci_free_resources(dev);
  46. put_device(&dev->dev);
  47. }
  48. void pci_remove_bus(struct pci_bus *bus)
  49. {
  50. pci_proc_detach_bus(bus);
  51. down_write(&pci_bus_sem);
  52. list_del(&bus->node);
  53. pci_bus_release_busn_res(bus);
  54. up_write(&pci_bus_sem);
  55. pci_remove_legacy_files(bus);
  56. if (bus->ops->remove_bus)
  57. bus->ops->remove_bus(bus);
  58. pcibios_remove_bus(bus);
  59. device_unregister(&bus->dev);
  60. }
  61. EXPORT_SYMBOL(pci_remove_bus);
  62. static void pci_stop_bus_device(struct pci_dev *dev)
  63. {
  64. struct pci_bus *bus = dev->subordinate;
  65. struct pci_dev *child, *tmp;
  66. /*
  67. * Stopping an SR-IOV PF device removes all the associated VFs,
  68. * which will update the bus->devices list and confuse the
  69. * iterator. Therefore, iterate in reverse so we remove the VFs
  70. * first, then the PF.
  71. */
  72. if (bus) {
  73. list_for_each_entry_safe_reverse(child, tmp,
  74. &bus->devices, bus_list)
  75. pci_stop_bus_device(child);
  76. }
  77. pci_stop_dev(dev);
  78. }
  79. static void pci_remove_bus_device(struct pci_dev *dev)
  80. {
  81. struct pci_bus *bus = dev->subordinate;
  82. struct pci_dev *child, *tmp;
  83. if (bus) {
  84. list_for_each_entry_safe(child, tmp,
  85. &bus->devices, bus_list)
  86. pci_remove_bus_device(child);
  87. pci_remove_bus(bus);
  88. dev->subordinate = NULL;
  89. }
  90. pci_destroy_dev(dev);
  91. }
  92. /**
  93. * pci_stop_and_remove_bus_device - remove a PCI device and any children
  94. * @dev: the device to remove
  95. *
  96. * Remove a PCI device from the device lists, informing the drivers
  97. * that the device has been removed. We also remove any subordinate
  98. * buses and children in a depth-first manner.
  99. *
  100. * For each device we remove, delete the device structure from the
  101. * device lists, remove the /proc entry, and notify userspace
  102. * (/sbin/hotplug).
  103. */
  104. void pci_stop_and_remove_bus_device(struct pci_dev *dev)
  105. {
  106. lockdep_assert_held(&pci_rescan_remove_lock);
  107. pci_stop_bus_device(dev);
  108. pci_remove_bus_device(dev);
  109. }
  110. EXPORT_SYMBOL(pci_stop_and_remove_bus_device);
  111. void pci_stop_and_remove_bus_device_locked(struct pci_dev *dev)
  112. {
  113. pci_lock_rescan_remove();
  114. pci_stop_and_remove_bus_device(dev);
  115. pci_unlock_rescan_remove();
  116. }
  117. EXPORT_SYMBOL_GPL(pci_stop_and_remove_bus_device_locked);
  118. void pci_stop_root_bus(struct pci_bus *bus)
  119. {
  120. struct pci_dev *child, *tmp;
  121. struct pci_host_bridge *host_bridge;
  122. if (!pci_is_root_bus(bus))
  123. return;
  124. host_bridge = to_pci_host_bridge(bus->bridge);
  125. list_for_each_entry_safe_reverse(child, tmp,
  126. &bus->devices, bus_list)
  127. pci_stop_bus_device(child);
  128. of_pci_remove_host_bridge_node(host_bridge);
  129. /* stop the host bridge */
  130. device_release_driver(&host_bridge->dev);
  131. }
  132. EXPORT_SYMBOL_GPL(pci_stop_root_bus);
  133. void pci_remove_root_bus(struct pci_bus *bus)
  134. {
  135. struct pci_dev *child, *tmp;
  136. struct pci_host_bridge *host_bridge;
  137. if (!pci_is_root_bus(bus))
  138. return;
  139. host_bridge = to_pci_host_bridge(bus->bridge);
  140. list_for_each_entry_safe(child, tmp,
  141. &bus->devices, bus_list)
  142. pci_remove_bus_device(child);
  143. #ifdef CONFIG_PCI_DOMAINS_GENERIC
  144. /* Release domain_nr if it was dynamically allocated */
  145. if (host_bridge->domain_nr == PCI_DOMAIN_NR_NOT_SET)
  146. pci_bus_release_domain_nr(host_bridge->dev.parent, bus->domain_nr);
  147. #endif
  148. pci_remove_bus(bus);
  149. host_bridge->bus = NULL;
  150. /* remove the host bridge */
  151. device_del(&host_bridge->dev);
  152. }
  153. EXPORT_SYMBOL_GPL(pci_remove_root_bus);