Commit 10a95747 authored by Jiang Liu's avatar Jiang Liu Committed by Bjorn Helgaas

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: default avatarJiang Liu <jiang.liu@huawei.com>
Signed-off-by: default avatarYijing Wang <wangyijing@huawei.com>
Signed-off-by: default avatarBjorn Helgaas <bhelgaas@google.com>
Reviewed-by: default avatarYinghai 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>
parent ce15d873
...@@ -673,6 +673,8 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent, ...@@ -673,6 +673,8 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent,
ret = device_register(&child->dev); ret = device_register(&child->dev);
WARN_ON(ret < 0); WARN_ON(ret < 0);
pcibios_add_bus(child);
/* Create legacy_io and legacy_mem files for this bus */ /* Create legacy_io and legacy_mem files for this bus */
pci_create_legacy_files(child); pci_create_legacy_files(child);
...@@ -1660,6 +1662,14 @@ int __weak pcibios_root_bridge_prepare(struct pci_host_bridge *bridge) ...@@ -1660,6 +1662,14 @@ int __weak pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
return 0; return 0;
} }
void __weak pcibios_add_bus(struct pci_bus *bus)
{
}
void __weak pcibios_remove_bus(struct pci_bus *bus)
{
}
struct pci_bus *pci_create_root_bus(struct device *parent, int bus, struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
struct pci_ops *ops, void *sysdata, struct list_head *resources) struct pci_ops *ops, void *sysdata, struct list_head *resources)
{ {
...@@ -1714,6 +1724,8 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus, ...@@ -1714,6 +1724,8 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
if (error) if (error)
goto class_dev_reg_err; goto class_dev_reg_err;
pcibios_add_bus(b);
/* Create legacy_io and legacy_mem files for this bus */ /* Create legacy_io and legacy_mem files for this bus */
pci_create_legacy_files(b); pci_create_legacy_files(b);
......
...@@ -51,6 +51,7 @@ void pci_remove_bus(struct pci_bus *bus) ...@@ -51,6 +51,7 @@ void pci_remove_bus(struct pci_bus *bus)
pci_bus_release_busn_res(bus); pci_bus_release_busn_res(bus);
up_write(&pci_bus_sem); up_write(&pci_bus_sem);
pci_remove_legacy_files(bus); pci_remove_legacy_files(bus);
pcibios_remove_bus(bus);
device_unregister(&bus->dev); device_unregister(&bus->dev);
} }
EXPORT_SYMBOL(pci_remove_bus); EXPORT_SYMBOL(pci_remove_bus);
......
...@@ -678,6 +678,8 @@ extern struct list_head pci_root_buses; /* list of all known PCI buses */ ...@@ -678,6 +678,8 @@ extern struct list_head pci_root_buses; /* list of all known PCI buses */
extern int no_pci_devices(void); extern int no_pci_devices(void);
void pcibios_resource_survey_bus(struct pci_bus *bus); void pcibios_resource_survey_bus(struct pci_bus *bus);
void pcibios_add_bus(struct pci_bus *bus);
void pcibios_remove_bus(struct pci_bus *bus);
void pcibios_fixup_bus(struct pci_bus *); void pcibios_fixup_bus(struct pci_bus *);
int __must_check pcibios_enable_device(struct pci_dev *, int mask); int __must_check pcibios_enable_device(struct pci_dev *, int mask);
/* Architecture specific versions may override this (weak) */ /* Architecture specific versions may override this (weak) */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment