aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiang Liu <liuj97@gmail.com>2013-04-12 01:44:20 -0400
committerBjorn Helgaas <bhelgaas@google.com>2013-04-12 17:38:25 -0400
commit10a9574756201fbbdd0cac11f370f00d3d02bfa1 (patch)
tree3e2985b5a56e2c5bbc95b1e81e043a2f3ae20f83
parentce15d873d05ebf3bf38579c4e0252140e28f1781 (diff)
PCI: Add pcibios hooks for adding and removing PCI buses
On ACPI-based platforms, the pci_slot driver creates PCI slot devices according to information from ACPI tables by registering an ACPI PCI subdriver. The ACPI PCI subdriver will only be called when creating/ destroying PCI root buses, and it won't be called when hot-plugging P2P bridges. It may cause stale PCI slot devices after hot-removing a P2P bridge if that bridge has associated PCI slots. And the acpiphp driver has the same issue too. This patch introduces two hook points into the PCI core, which will be invoked when creating/destroying PCI buses for PCI host and P2P bridges. They could be used to setup/destroy platform dependent stuff in a unified way, both at boot time and for PCI hotplug operations. Signed-off-by: Jiang Liu <jiang.liu@huawei.com> Signed-off-by: Yijing Wang <wangyijing@huawei.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Yinghai Lu <yinghai@kernel.org> Cc: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com> Cc: Toshi Kani <toshi.kani@hp.com> Cc: Tony Luck <tony.luck@intel.com> Cc: Fenghua Yu <fenghua.yu@intel.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Ingo Molnar <mingo@redhat.com> Cc: "H. Peter Anvin" <hpa@zytor.com> Cc: Myron Stowe <myron.stowe@redhat.com>
-rw-r--r--drivers/pci/probe.c12
-rw-r--r--drivers/pci/remove.c1
-rw-r--r--include/linux/pci.h2
3 files changed, 15 insertions, 0 deletions
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 45c93b39af35..43ece5d41d36 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -673,6 +673,8 @@ add_dev:
673 ret = device_register(&child->dev); 673 ret = device_register(&child->dev);
674 WARN_ON(ret < 0); 674 WARN_ON(ret < 0);
675 675
676 pcibios_add_bus(child);
677
676 /* Create legacy_io and legacy_mem files for this bus */ 678 /* Create legacy_io and legacy_mem files for this bus */
677 pci_create_legacy_files(child); 679 pci_create_legacy_files(child);
678 680
@@ -1660,6 +1662,14 @@ int __weak pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
1660 return 0; 1662 return 0;
1661} 1663}
1662 1664
1665void __weak pcibios_add_bus(struct pci_bus *bus)
1666{
1667}
1668
1669void __weak pcibios_remove_bus(struct pci_bus *bus)
1670{
1671}
1672
1663struct pci_bus *pci_create_root_bus(struct device *parent, int bus, 1673struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
1664 struct pci_ops *ops, void *sysdata, struct list_head *resources) 1674 struct pci_ops *ops, void *sysdata, struct list_head *resources)
1665{ 1675{
@@ -1714,6 +1724,8 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
1714 if (error) 1724 if (error)
1715 goto class_dev_reg_err; 1725 goto class_dev_reg_err;
1716 1726
1727 pcibios_add_bus(b);
1728
1717 /* Create legacy_io and legacy_mem files for this bus */ 1729 /* Create legacy_io and legacy_mem files for this bus */
1718 pci_create_legacy_files(b); 1730 pci_create_legacy_files(b);
1719 1731
diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c
index a8318801c092..8fc54b7327bc 100644
--- a/drivers/pci/remove.c
+++ b/drivers/pci/remove.c
@@ -51,6 +51,7 @@ void pci_remove_bus(struct pci_bus *bus)
51 pci_bus_release_busn_res(bus); 51 pci_bus_release_busn_res(bus);
52 up_write(&pci_bus_sem); 52 up_write(&pci_bus_sem);
53 pci_remove_legacy_files(bus); 53 pci_remove_legacy_files(bus);
54 pcibios_remove_bus(bus);
54 device_unregister(&bus->dev); 55 device_unregister(&bus->dev);
55} 56}
56EXPORT_SYMBOL(pci_remove_bus); 57EXPORT_SYMBOL(pci_remove_bus);
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 2461033a7987..be9399452133 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -678,6 +678,8 @@ extern struct list_head pci_root_buses; /* list of all known PCI buses */
678extern int no_pci_devices(void); 678extern int no_pci_devices(void);
679 679
680void pcibios_resource_survey_bus(struct pci_bus *bus); 680void pcibios_resource_survey_bus(struct pci_bus *bus);
681void pcibios_add_bus(struct pci_bus *bus);
682void pcibios_remove_bus(struct pci_bus *bus);
681void pcibios_fixup_bus(struct pci_bus *); 683void pcibios_fixup_bus(struct pci_bus *);
682int __must_check pcibios_enable_device(struct pci_dev *, int mask); 684int __must_check pcibios_enable_device(struct pci_dev *, int mask);
683/* Architecture specific versions may override this (weak) */ 685/* Architecture specific versions may override this (weak) */