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) |