aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/platforms/pseries/eeh.c13
-rw-r--r--arch/powerpc/platforms/pseries/eeh_driver.c20
2 files changed, 29 insertions, 4 deletions
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c
index b0fa76d0c78a..02bc1f9d20b9 100644
--- a/arch/powerpc/platforms/pseries/eeh.c
+++ b/arch/powerpc/platforms/pseries/eeh.c
@@ -223,6 +223,11 @@ static void __eeh_mark_slot (struct device_node *dn, int mode_flag)
223void eeh_mark_slot (struct device_node *dn, int mode_flag) 223void eeh_mark_slot (struct device_node *dn, int mode_flag)
224{ 224{
225 dn = find_device_pe (dn); 225 dn = find_device_pe (dn);
226
227 /* Back up one, since config addrs might be shared */
228 if (PCI_DN(dn) && PCI_DN(dn)->eeh_pe_config_addr)
229 dn = dn->parent;
230
226 PCI_DN(dn)->eeh_mode |= mode_flag; 231 PCI_DN(dn)->eeh_mode |= mode_flag;
227 __eeh_mark_slot (dn->child, mode_flag); 232 __eeh_mark_slot (dn->child, mode_flag);
228} 233}
@@ -244,7 +249,13 @@ void eeh_clear_slot (struct device_node *dn, int mode_flag)
244{ 249{
245 unsigned long flags; 250 unsigned long flags;
246 spin_lock_irqsave(&confirm_error_lock, flags); 251 spin_lock_irqsave(&confirm_error_lock, flags);
252
247 dn = find_device_pe (dn); 253 dn = find_device_pe (dn);
254
255 /* Back up one, since config addrs might be shared */
256 if (PCI_DN(dn) && PCI_DN(dn)->eeh_pe_config_addr)
257 dn = dn->parent;
258
248 PCI_DN(dn)->eeh_mode &= ~mode_flag; 259 PCI_DN(dn)->eeh_mode &= ~mode_flag;
249 PCI_DN(dn)->eeh_check_count = 0; 260 PCI_DN(dn)->eeh_check_count = 0;
250 __eeh_clear_slot (dn->child, mode_flag); 261 __eeh_clear_slot (dn->child, mode_flag);
@@ -609,7 +620,7 @@ void eeh_restore_bars(struct pci_dn *pdn)
609 if (!pdn) 620 if (!pdn)
610 return; 621 return;
611 622
612 if (! pdn->eeh_is_bridge) 623 if ((pdn->eeh_mode & EEH_MODE_SUPPORTED) && (!pdn->eeh_is_bridge))
613 __restore_bars (pdn); 624 __restore_bars (pdn);
614 625
615 dn = pdn->node->child; 626 dn = pdn->node->child;
diff --git a/arch/powerpc/platforms/pseries/eeh_driver.c b/arch/powerpc/platforms/pseries/eeh_driver.c
index 242b2923360d..1c97c89597fb 100644
--- a/arch/powerpc/platforms/pseries/eeh_driver.c
+++ b/arch/powerpc/platforms/pseries/eeh_driver.c
@@ -213,9 +213,23 @@ static int eeh_reset_device (struct pci_dn *pe_dn, struct pci_bus *bus)
213 if (rc) 213 if (rc)
214 return rc; 214 return rc;
215 215
216 /* Walk over all functions on this device */ 216 /* New-style config addrs might be shared across multiple devices,
217 rtas_configure_bridge(pe_dn); 217 * Walk over all functions on this device */
218 eeh_restore_bars(pe_dn); 218 if (pe_dn->eeh_pe_config_addr) {
219 struct device_node *pe = pe_dn->node;
220 pe = pe->parent->child;
221 while (pe) {
222 struct pci_dn *ppe = PCI_DN(pe);
223 if (pe_dn->eeh_pe_config_addr == ppe->eeh_pe_config_addr) {
224 rtas_configure_bridge(ppe);
225 eeh_restore_bars(ppe);
226 }
227 pe = pe->sibling;
228 }
229 } else {
230 rtas_configure_bridge(pe_dn);
231 eeh_restore_bars(pe_dn);
232 }
219 233
220 /* Give the system 5 seconds to finish running the user-space 234 /* Give the system 5 seconds to finish running the user-space
221 * hotplug shutdown scripts, e.g. ifdown for ethernet. Yes, 235 * hotplug shutdown scripts, e.g. ifdown for ethernet. Yes,