diff options
| -rw-r--r-- | arch/powerpc/platforms/pseries/eeh.c | 14 | ||||
| -rw-r--r-- | arch/powerpc/platforms/pseries/pci_dlpar.c | 36 | ||||
| -rw-r--r-- | include/asm-powerpc/eeh.h | 7 |
3 files changed, 38 insertions, 19 deletions
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c index 83578313ee7e..2ab9dcdfb415 100644 --- a/arch/powerpc/platforms/pseries/eeh.c +++ b/arch/powerpc/platforms/pseries/eeh.c | |||
| @@ -893,6 +893,20 @@ void eeh_add_device_tree_early(struct device_node *dn) | |||
| 893 | } | 893 | } |
| 894 | EXPORT_SYMBOL_GPL(eeh_add_device_tree_early); | 894 | EXPORT_SYMBOL_GPL(eeh_add_device_tree_early); |
| 895 | 895 | ||
| 896 | void eeh_add_device_tree_late(struct pci_bus *bus) | ||
| 897 | { | ||
| 898 | struct pci_dev *dev; | ||
| 899 | |||
| 900 | list_for_each_entry(dev, &bus->devices, bus_list) { | ||
| 901 | eeh_add_device_late(dev); | ||
| 902 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { | ||
| 903 | struct pci_bus *subbus = dev->subordinate; | ||
| 904 | if (subbus) | ||
| 905 | eeh_add_device_tree_late(subbus); | ||
| 906 | } | ||
| 907 | } | ||
| 908 | } | ||
| 909 | |||
| 896 | /** | 910 | /** |
| 897 | * eeh_add_device_late - perform EEH initialization for the indicated pci device | 911 | * eeh_add_device_late - perform EEH initialization for the indicated pci device |
| 898 | * @dev: pci device for which to set up EEH | 912 | * @dev: pci device for which to set up EEH |
diff --git a/arch/powerpc/platforms/pseries/pci_dlpar.c b/arch/powerpc/platforms/pseries/pci_dlpar.c index bdaa8aabdaa6..f3bad900bbcf 100644 --- a/arch/powerpc/platforms/pseries/pci_dlpar.c +++ b/arch/powerpc/platforms/pseries/pci_dlpar.c | |||
| @@ -106,6 +106,8 @@ pcibios_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus) | |||
| 106 | } | 106 | } |
| 107 | } | 107 | } |
| 108 | } | 108 | } |
| 109 | |||
| 110 | eeh_add_device_tree_late(bus); | ||
| 109 | } | 111 | } |
| 110 | EXPORT_SYMBOL_GPL(pcibios_fixup_new_pci_devices); | 112 | EXPORT_SYMBOL_GPL(pcibios_fixup_new_pci_devices); |
| 111 | 113 | ||
| @@ -114,7 +116,6 @@ pcibios_pci_config_bridge(struct pci_dev *dev) | |||
| 114 | { | 116 | { |
| 115 | u8 sec_busno; | 117 | u8 sec_busno; |
| 116 | struct pci_bus *child_bus; | 118 | struct pci_bus *child_bus; |
| 117 | struct pci_dev *child_dev; | ||
| 118 | 119 | ||
| 119 | /* Get busno of downstream bus */ | 120 | /* Get busno of downstream bus */ |
| 120 | pci_read_config_byte(dev, PCI_SECONDARY_BUS, &sec_busno); | 121 | pci_read_config_byte(dev, PCI_SECONDARY_BUS, &sec_busno); |
| @@ -129,10 +130,6 @@ pcibios_pci_config_bridge(struct pci_dev *dev) | |||
| 129 | 130 | ||
| 130 | pci_scan_child_bus(child_bus); | 131 | pci_scan_child_bus(child_bus); |
| 131 | 132 | ||
| 132 | list_for_each_entry(child_dev, &child_bus->devices, bus_list) { | ||
| 133 | eeh_add_device_late(child_dev); | ||
| 134 | } | ||
| 135 | |||
| 136 | /* Fixup new pci devices without touching bus struct */ | 133 | /* Fixup new pci devices without touching bus struct */ |
| 137 | pcibios_fixup_new_pci_devices(child_bus, 0); | 134 | pcibios_fixup_new_pci_devices(child_bus, 0); |
| 138 | 135 | ||
| @@ -160,18 +157,25 @@ pcibios_add_pci_devices(struct pci_bus * bus) | |||
| 160 | 157 | ||
| 161 | eeh_add_device_tree_early(dn); | 158 | eeh_add_device_tree_early(dn); |
| 162 | 159 | ||
| 163 | /* pci_scan_slot should find all children */ | 160 | if (_machine == PLATFORM_PSERIES_LPAR) { |
| 164 | slotno = PCI_SLOT(PCI_DN(dn->child)->devfn); | 161 | /* use ofdt-based probe */ |
| 165 | num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0)); | 162 | of_scan_bus(dn, bus); |
| 166 | if (num) { | 163 | if (!list_empty(&bus->devices)) { |
| 167 | pcibios_fixup_new_pci_devices(bus, 1); | 164 | pcibios_fixup_new_pci_devices(bus, 0); |
| 168 | pci_bus_add_devices(bus); | 165 | pci_bus_add_devices(bus); |
| 169 | } | 166 | } |
| 167 | } else { | ||
| 168 | /* use legacy probe */ | ||
| 169 | slotno = PCI_SLOT(PCI_DN(dn->child)->devfn); | ||
| 170 | num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0)); | ||
| 171 | if (num) { | ||
| 172 | pcibios_fixup_new_pci_devices(bus, 1); | ||
| 173 | pci_bus_add_devices(bus); | ||
| 174 | } | ||
| 170 | 175 | ||
| 171 | list_for_each_entry(dev, &bus->devices, bus_list) { | 176 | list_for_each_entry(dev, &bus->devices, bus_list) |
| 172 | eeh_add_device_late (dev); | 177 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) |
| 173 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) | 178 | pcibios_pci_config_bridge(dev); |
| 174 | pcibios_pci_config_bridge(dev); | ||
| 175 | } | 179 | } |
| 176 | } | 180 | } |
| 177 | EXPORT_SYMBOL_GPL(pcibios_add_pci_devices); | 181 | EXPORT_SYMBOL_GPL(pcibios_add_pci_devices); |
diff --git a/include/asm-powerpc/eeh.h b/include/asm-powerpc/eeh.h index b263fb2fa6e4..7dfb408fe2ca 100644 --- a/include/asm-powerpc/eeh.h +++ b/include/asm-powerpc/eeh.h | |||
| @@ -27,6 +27,7 @@ | |||
| 27 | #include <linux/string.h> | 27 | #include <linux/string.h> |
| 28 | 28 | ||
| 29 | struct pci_dev; | 29 | struct pci_dev; |
| 30 | struct pci_bus; | ||
| 30 | struct device_node; | 31 | struct device_node; |
| 31 | 32 | ||
| 32 | #ifdef CONFIG_EEH | 33 | #ifdef CONFIG_EEH |
| @@ -61,7 +62,7 @@ void __init pci_addr_cache_build(void); | |||
| 61 | */ | 62 | */ |
| 62 | void eeh_add_device_early(struct device_node *); | 63 | void eeh_add_device_early(struct device_node *); |
| 63 | void eeh_add_device_tree_early(struct device_node *); | 64 | void eeh_add_device_tree_early(struct device_node *); |
| 64 | void eeh_add_device_late(struct pci_dev *); | 65 | void eeh_add_device_tree_late(struct pci_bus *); |
| 65 | 66 | ||
| 66 | /** | 67 | /** |
| 67 | * eeh_remove_device - undo EEH setup for the indicated pci device | 68 | * eeh_remove_device - undo EEH setup for the indicated pci device |
| @@ -116,12 +117,12 @@ static inline void pci_addr_cache_build(void) { } | |||
| 116 | 117 | ||
| 117 | static inline void eeh_add_device_early(struct device_node *dn) { } | 118 | static inline void eeh_add_device_early(struct device_node *dn) { } |
| 118 | 119 | ||
| 119 | static inline void eeh_add_device_late(struct pci_dev *dev) { } | ||
| 120 | |||
| 121 | static inline void eeh_remove_device(struct pci_dev *dev) { } | 120 | static inline void eeh_remove_device(struct pci_dev *dev) { } |
| 122 | 121 | ||
| 123 | static inline void eeh_add_device_tree_early(struct device_node *dn) { } | 122 | static inline void eeh_add_device_tree_early(struct device_node *dn) { } |
| 124 | 123 | ||
| 124 | static inline void eeh_add_device_tree_late(struct pci_bus *bus) { } | ||
| 125 | |||
| 125 | static inline void eeh_remove_bus_device(struct pci_dev *dev) { } | 126 | static inline void eeh_remove_bus_device(struct pci_dev *dev) { } |
| 126 | #define EEH_POSSIBLE_ERROR(val, type) (0) | 127 | #define EEH_POSSIBLE_ERROR(val, type) (0) |
| 127 | #define EEH_IO_ERROR_VALUE(size) (-1UL) | 128 | #define EEH_IO_ERROR_VALUE(size) (-1UL) |
