aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/pseries/eeh.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/platforms/pseries/eeh.c')
-rw-r--r--arch/powerpc/platforms/pseries/eeh.c46
1 files changed, 23 insertions, 23 deletions
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c
index fb3d636e088b..9eb539ee5f9a 100644
--- a/arch/powerpc/platforms/pseries/eeh.c
+++ b/arch/powerpc/platforms/pseries/eeh.c
@@ -29,6 +29,8 @@
29#include <linux/rbtree.h> 29#include <linux/rbtree.h>
30#include <linux/seq_file.h> 30#include <linux/seq_file.h>
31#include <linux/spinlock.h> 31#include <linux/spinlock.h>
32#include <linux/of.h>
33
32#include <asm/atomic.h> 34#include <asm/atomic.h>
33#include <asm/eeh.h> 35#include <asm/eeh.h>
34#include <asm/eeh_event.h> 36#include <asm/eeh_event.h>
@@ -169,7 +171,6 @@ static void rtas_slot_error_detail(struct pci_dn *pdn, int severity,
169 */ 171 */
170static size_t gather_pci_data(struct pci_dn *pdn, char * buf, size_t len) 172static size_t gather_pci_data(struct pci_dn *pdn, char * buf, size_t len)
171{ 173{
172 struct device_node *dn;
173 struct pci_dev *dev = pdn->pcidev; 174 struct pci_dev *dev = pdn->pcidev;
174 u32 cfg; 175 u32 cfg;
175 int cap, i; 176 int cap, i;
@@ -243,12 +244,12 @@ static size_t gather_pci_data(struct pci_dn *pdn, char * buf, size_t len)
243 244
244 /* Gather status on devices under the bridge */ 245 /* Gather status on devices under the bridge */
245 if (dev->class >> 16 == PCI_BASE_CLASS_BRIDGE) { 246 if (dev->class >> 16 == PCI_BASE_CLASS_BRIDGE) {
246 dn = pdn->node->child; 247 struct device_node *dn;
247 while (dn) { 248
249 for_each_child_of_node(pdn->node, dn) {
248 pdn = PCI_DN(dn); 250 pdn = PCI_DN(dn);
249 if (pdn) 251 if (pdn)
250 n += gather_pci_data(pdn, buf+n, len-n); 252 n += gather_pci_data(pdn, buf+n, len-n);
251 dn = dn->sibling;
252 } 253 }
253 } 254 }
254 255
@@ -372,7 +373,7 @@ struct device_node * find_device_pe(struct device_node *dn)
372 return dn; 373 return dn;
373} 374}
374 375
375/** Mark all devices that are peers of this device as failed. 376/** Mark all devices that are children of this device as failed.
376 * Mark the device driver too, so that it can see the failure 377 * Mark the device driver too, so that it can see the failure
377 * immediately; this is critical, since some drivers poll 378 * immediately; this is critical, since some drivers poll
378 * status registers in interrupts ... If a driver is polling, 379 * status registers in interrupts ... If a driver is polling,
@@ -380,9 +381,11 @@ struct device_node * find_device_pe(struct device_node *dn)
380 * an interrupt context, which is bad. 381 * an interrupt context, which is bad.
381 */ 382 */
382 383
383static void __eeh_mark_slot (struct device_node *dn, int mode_flag) 384static void __eeh_mark_slot(struct device_node *parent, int mode_flag)
384{ 385{
385 while (dn) { 386 struct device_node *dn;
387
388 for_each_child_of_node(parent, dn) {
386 if (PCI_DN(dn)) { 389 if (PCI_DN(dn)) {
387 /* Mark the pci device driver too */ 390 /* Mark the pci device driver too */
388 struct pci_dev *dev = PCI_DN(dn)->pcidev; 391 struct pci_dev *dev = PCI_DN(dn)->pcidev;
@@ -392,10 +395,8 @@ static void __eeh_mark_slot (struct device_node *dn, int mode_flag)
392 if (dev && dev->driver) 395 if (dev && dev->driver)
393 dev->error_state = pci_channel_io_frozen; 396 dev->error_state = pci_channel_io_frozen;
394 397
395 if (dn->child) 398 __eeh_mark_slot(dn, mode_flag);
396 __eeh_mark_slot (dn->child, mode_flag);
397 } 399 }
398 dn = dn->sibling;
399 } 400 }
400} 401}
401 402
@@ -415,19 +416,19 @@ void eeh_mark_slot (struct device_node *dn, int mode_flag)
415 if (dev) 416 if (dev)
416 dev->error_state = pci_channel_io_frozen; 417 dev->error_state = pci_channel_io_frozen;
417 418
418 __eeh_mark_slot (dn->child, mode_flag); 419 __eeh_mark_slot(dn, mode_flag);
419} 420}
420 421
421static void __eeh_clear_slot (struct device_node *dn, int mode_flag) 422static void __eeh_clear_slot(struct device_node *parent, int mode_flag)
422{ 423{
423 while (dn) { 424 struct device_node *dn;
425
426 for_each_child_of_node(parent, dn) {
424 if (PCI_DN(dn)) { 427 if (PCI_DN(dn)) {
425 PCI_DN(dn)->eeh_mode &= ~mode_flag; 428 PCI_DN(dn)->eeh_mode &= ~mode_flag;
426 PCI_DN(dn)->eeh_check_count = 0; 429 PCI_DN(dn)->eeh_check_count = 0;
427 if (dn->child) 430 __eeh_clear_slot(dn, mode_flag);
428 __eeh_clear_slot (dn->child, mode_flag);
429 } 431 }
430 dn = dn->sibling;
431 } 432 }
432} 433}
433 434
@@ -444,7 +445,7 @@ void eeh_clear_slot (struct device_node *dn, int mode_flag)
444 445
445 PCI_DN(dn)->eeh_mode &= ~mode_flag; 446 PCI_DN(dn)->eeh_mode &= ~mode_flag;
446 PCI_DN(dn)->eeh_check_count = 0; 447 PCI_DN(dn)->eeh_check_count = 0;
447 __eeh_clear_slot (dn->child, mode_flag); 448 __eeh_clear_slot(dn, mode_flag);
448 spin_unlock_irqrestore(&confirm_error_lock, flags); 449 spin_unlock_irqrestore(&confirm_error_lock, flags);
449} 450}
450 451
@@ -480,6 +481,7 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
480 no_dn++; 481 no_dn++;
481 return 0; 482 return 0;
482 } 483 }
484 dn = find_device_pe(dn);
483 pdn = PCI_DN(dn); 485 pdn = PCI_DN(dn);
484 486
485 /* Access to IO BARs might get this far and still not want checking. */ 487 /* Access to IO BARs might get this far and still not want checking. */
@@ -545,7 +547,7 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
545 547
546 /* Note that config-io to empty slots may fail; 548 /* Note that config-io to empty slots may fail;
547 * they are empty when they don't have children. */ 549 * they are empty when they don't have children. */
548 if ((rets[0] == 5) && (dn->child == NULL)) { 550 if ((rets[0] == 5) && (rets[2] == 0) && (dn->child == NULL)) {
549 false_positives++; 551 false_positives++;
550 pdn->eeh_false_positives ++; 552 pdn->eeh_false_positives ++;
551 rc = 0; 553 rc = 0;
@@ -848,11 +850,8 @@ void eeh_restore_bars(struct pci_dn *pdn)
848 if ((pdn->eeh_mode & EEH_MODE_SUPPORTED) && !IS_BRIDGE(pdn->class_code)) 850 if ((pdn->eeh_mode & EEH_MODE_SUPPORTED) && !IS_BRIDGE(pdn->class_code))
849 __restore_bars (pdn); 851 __restore_bars (pdn);
850 852
851 dn = pdn->node->child; 853 for_each_child_of_node(pdn->node, dn)
852 while (dn) {
853 eeh_restore_bars (PCI_DN(dn)); 854 eeh_restore_bars (PCI_DN(dn));
854 dn = dn->sibling;
855 }
856} 855}
857 856
858/** 857/**
@@ -1130,7 +1129,8 @@ static void eeh_add_device_early(struct device_node *dn)
1130void eeh_add_device_tree_early(struct device_node *dn) 1129void eeh_add_device_tree_early(struct device_node *dn)
1131{ 1130{
1132 struct device_node *sib; 1131 struct device_node *sib;
1133 for (sib = dn->child; sib; sib = sib->sibling) 1132
1133 for_each_child_of_node(dn, sib)
1134 eeh_add_device_tree_early(sib); 1134 eeh_add_device_tree_early(sib);
1135 eeh_add_device_early(dn); 1135 eeh_add_device_early(dn);
1136} 1136}