提交 827c1a6c 编写于 作者: J John Rose 提交者: Paul Mackerras

[PATCH] powerpc: fix dynamic PCI probe regression

Some hotplug driver functions were migrated to the kernel for use by EEH
in commit 2bf6a8fa.

Previously, the PCI Hotplug module had been changed to use the new
OFDT-based PCI probe when appropriate:
5fa80fcd

When rpaphp_pci_config_slot() was moved from the rpaphp driver to the
new kernel function pcibios_add_pci_devices(), the OFDT-based probe
stuff was dropped.  This patch restores it.
Signed-off-by: NJohn Rose <johnrose@austin.ibm.com>
Signed-off-by: NPaul Mackerras <paulus@samba.org>
上级 a8b76b49
......@@ -893,6 +893,20 @@ void eeh_add_device_tree_early(struct device_node *dn)
}
EXPORT_SYMBOL_GPL(eeh_add_device_tree_early);
void eeh_add_device_tree_late(struct pci_bus *bus)
{
struct pci_dev *dev;
list_for_each_entry(dev, &bus->devices, bus_list) {
eeh_add_device_late(dev);
if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
struct pci_bus *subbus = dev->subordinate;
if (subbus)
eeh_add_device_tree_late(subbus);
}
}
}
/**
* eeh_add_device_late - perform EEH initialization for the indicated pci device
* @dev: pci device for which to set up EEH
......
......@@ -106,6 +106,8 @@ pcibios_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus)
}
}
}
eeh_add_device_tree_late(bus);
}
EXPORT_SYMBOL_GPL(pcibios_fixup_new_pci_devices);
......@@ -114,7 +116,6 @@ pcibios_pci_config_bridge(struct pci_dev *dev)
{
u8 sec_busno;
struct pci_bus *child_bus;
struct pci_dev *child_dev;
/* Get busno of downstream bus */
pci_read_config_byte(dev, PCI_SECONDARY_BUS, &sec_busno);
......@@ -129,10 +130,6 @@ pcibios_pci_config_bridge(struct pci_dev *dev)
pci_scan_child_bus(child_bus);
list_for_each_entry(child_dev, &child_bus->devices, bus_list) {
eeh_add_device_late(child_dev);
}
/* Fixup new pci devices without touching bus struct */
pcibios_fixup_new_pci_devices(child_bus, 0);
......@@ -160,18 +157,25 @@ pcibios_add_pci_devices(struct pci_bus * bus)
eeh_add_device_tree_early(dn);
/* pci_scan_slot should find all children */
slotno = PCI_SLOT(PCI_DN(dn->child)->devfn);
num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0));
if (num) {
pcibios_fixup_new_pci_devices(bus, 1);
pci_bus_add_devices(bus);
}
if (_machine == PLATFORM_PSERIES_LPAR) {
/* use ofdt-based probe */
of_scan_bus(dn, bus);
if (!list_empty(&bus->devices)) {
pcibios_fixup_new_pci_devices(bus, 0);
pci_bus_add_devices(bus);
}
} else {
/* use legacy probe */
slotno = PCI_SLOT(PCI_DN(dn->child)->devfn);
num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0));
if (num) {
pcibios_fixup_new_pci_devices(bus, 1);
pci_bus_add_devices(bus);
}
list_for_each_entry(dev, &bus->devices, bus_list) {
eeh_add_device_late (dev);
if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)
pcibios_pci_config_bridge(dev);
list_for_each_entry(dev, &bus->devices, bus_list)
if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)
pcibios_pci_config_bridge(dev);
}
}
EXPORT_SYMBOL_GPL(pcibios_add_pci_devices);
......@@ -27,6 +27,7 @@
#include <linux/string.h>
struct pci_dev;
struct pci_bus;
struct device_node;
#ifdef CONFIG_EEH
......@@ -61,7 +62,7 @@ void __init pci_addr_cache_build(void);
*/
void eeh_add_device_early(struct device_node *);
void eeh_add_device_tree_early(struct device_node *);
void eeh_add_device_late(struct pci_dev *);
void eeh_add_device_tree_late(struct pci_bus *);
/**
* eeh_remove_device - undo EEH setup for the indicated pci device
......@@ -116,12 +117,12 @@ static inline void pci_addr_cache_build(void) { }
static inline void eeh_add_device_early(struct device_node *dn) { }
static inline void eeh_add_device_late(struct pci_dev *dev) { }
static inline void eeh_remove_device(struct pci_dev *dev) { }
static inline void eeh_add_device_tree_early(struct device_node *dn) { }
static inline void eeh_add_device_tree_late(struct pci_bus *bus) { }
static inline void eeh_remove_bus_device(struct pci_dev *dev) { }
#define EEH_POSSIBLE_ERROR(val, type) (0)
#define EEH_IO_ERROR_VALUE(size) (-1UL)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册