summaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/pseries/eeh.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-01-31 13:37:27 +1100
committerLinus Torvalds <torvalds@linux-foundation.org>2008-01-31 13:37:27 +1100
commit8af03e782cae1e0a0f530ddd22301cdd12cf9dc0 (patch)
treec4af13a38bd3cc1a811a37f2358491f171052070 /arch/powerpc/platforms/pseries/eeh.c
parent6232665040f9a23fafd9d94d4ae8d5a2dc850f65 (diff)
parent99e139126ab2e84be67969650f92eb37c12ab5cd (diff)
downloadop-kernel-dev-8af03e782cae1e0a0f530ddd22301cdd12cf9dc0.zip
op-kernel-dev-8af03e782cae1e0a0f530ddd22301cdd12cf9dc0.tar.gz
Merge branch 'for-2.6.25' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc
* 'for-2.6.25' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc: (454 commits) [POWERPC] Cell IOMMU fixed mapping support [POWERPC] Split out the ioid fetching/checking logic [POWERPC] Add support to cell_iommu_setup_page_tables() for multiple windows [POWERPC] Split out the IOMMU logic from cell_dma_dev_setup() [POWERPC] Split cell_iommu_setup_hardware() into two parts [POWERPC] Split out the logic that allocates struct iommus [POWERPC] Allocate the hash table under 1G on cell [POWERPC] Add set_dma_ops() to match get_dma_ops() [POWERPC] 83xx: Clean up / convert mpc83xx board DTS files to v1 format. [POWERPC] 85xx: Only invalidate TLB0 and TLB1 [POWERPC] 83xx: Fix typo in mpc837x compatible entries [POWERPC] 85xx: convert sbc85* boards to use machine_device_initcall [POWERPC] 83xx: rework platform Kconfig [POWERPC] 85xx: rework platform Kconfig [POWERPC] 86xx: Remove unused IRQ defines [POWERPC] QE: Explicitly set address-cells and size cells for muram [POWERPC] Convert StorCenter DTS file to /dts-v1/ format. [POWERPC] 86xx: Convert all 86xx DTS files to /dts-v1/ format. [PPC] Remove 85xx from arch/ppc [PPC] Remove 83xx from arch/ppc ...
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 fb3d636..9eb539e 100644
--- a/arch/powerpc/platforms/pseries/eeh.c
+++ b/arch/powerpc/platforms/pseries/eeh.c
@@ -29,6 +29,8 @@
#include <linux/rbtree.h>
#include <linux/seq_file.h>
#include <linux/spinlock.h>
+#include <linux/of.h>
+
#include <asm/atomic.h>
#include <asm/eeh.h>
#include <asm/eeh_event.h>
@@ -169,7 +171,6 @@ static void rtas_slot_error_detail(struct pci_dn *pdn, int severity,
*/
static size_t gather_pci_data(struct pci_dn *pdn, char * buf, size_t len)
{
- struct device_node *dn;
struct pci_dev *dev = pdn->pcidev;
u32 cfg;
int cap, i;
@@ -243,12 +244,12 @@ static size_t gather_pci_data(struct pci_dn *pdn, char * buf, size_t len)
/* Gather status on devices under the bridge */
if (dev->class >> 16 == PCI_BASE_CLASS_BRIDGE) {
- dn = pdn->node->child;
- while (dn) {
+ struct device_node *dn;
+
+ for_each_child_of_node(pdn->node, dn) {
pdn = PCI_DN(dn);
if (pdn)
n += gather_pci_data(pdn, buf+n, len-n);
- dn = dn->sibling;
}
}
@@ -372,7 +373,7 @@ struct device_node * find_device_pe(struct device_node *dn)
return dn;
}
-/** Mark all devices that are peers of this device as failed.
+/** Mark all devices that are children of this device as failed.
* Mark the device driver too, so that it can see the failure
* immediately; this is critical, since some drivers poll
* status registers in interrupts ... If a driver is polling,
@@ -380,9 +381,11 @@ struct device_node * find_device_pe(struct device_node *dn)
* an interrupt context, which is bad.
*/
-static void __eeh_mark_slot (struct device_node *dn, int mode_flag)
+static void __eeh_mark_slot(struct device_node *parent, int mode_flag)
{
- while (dn) {
+ struct device_node *dn;
+
+ for_each_child_of_node(parent, dn) {
if (PCI_DN(dn)) {
/* Mark the pci device driver too */
struct pci_dev *dev = PCI_DN(dn)->pcidev;
@@ -392,10 +395,8 @@ static void __eeh_mark_slot (struct device_node *dn, int mode_flag)
if (dev && dev->driver)
dev->error_state = pci_channel_io_frozen;
- if (dn->child)
- __eeh_mark_slot (dn->child, mode_flag);
+ __eeh_mark_slot(dn, mode_flag);
}
- dn = dn->sibling;
}
}
@@ -415,19 +416,19 @@ void eeh_mark_slot (struct device_node *dn, int mode_flag)
if (dev)
dev->error_state = pci_channel_io_frozen;
- __eeh_mark_slot (dn->child, mode_flag);
+ __eeh_mark_slot(dn, mode_flag);
}
-static void __eeh_clear_slot (struct device_node *dn, int mode_flag)
+static void __eeh_clear_slot(struct device_node *parent, int mode_flag)
{
- while (dn) {
+ struct device_node *dn;
+
+ for_each_child_of_node(parent, dn) {
if (PCI_DN(dn)) {
PCI_DN(dn)->eeh_mode &= ~mode_flag;
PCI_DN(dn)->eeh_check_count = 0;
- if (dn->child)
- __eeh_clear_slot (dn->child, mode_flag);
+ __eeh_clear_slot(dn, mode_flag);
}
- dn = dn->sibling;
}
}
@@ -444,7 +445,7 @@ void eeh_clear_slot (struct device_node *dn, int mode_flag)
PCI_DN(dn)->eeh_mode &= ~mode_flag;
PCI_DN(dn)->eeh_check_count = 0;
- __eeh_clear_slot (dn->child, mode_flag);
+ __eeh_clear_slot(dn, mode_flag);
spin_unlock_irqrestore(&confirm_error_lock, flags);
}
@@ -480,6 +481,7 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
no_dn++;
return 0;
}
+ dn = find_device_pe(dn);
pdn = PCI_DN(dn);
/* 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)
/* Note that config-io to empty slots may fail;
* they are empty when they don't have children. */
- if ((rets[0] == 5) && (dn->child == NULL)) {
+ if ((rets[0] == 5) && (rets[2] == 0) && (dn->child == NULL)) {
false_positives++;
pdn->eeh_false_positives ++;
rc = 0;
@@ -848,11 +850,8 @@ void eeh_restore_bars(struct pci_dn *pdn)
if ((pdn->eeh_mode & EEH_MODE_SUPPORTED) && !IS_BRIDGE(pdn->class_code))
__restore_bars (pdn);
- dn = pdn->node->child;
- while (dn) {
+ for_each_child_of_node(pdn->node, dn)
eeh_restore_bars (PCI_DN(dn));
- dn = dn->sibling;
- }
}
/**
@@ -1130,7 +1129,8 @@ static void eeh_add_device_early(struct device_node *dn)
void eeh_add_device_tree_early(struct device_node *dn)
{
struct device_node *sib;
- for (sib = dn->child; sib; sib = sib->sibling)
+
+ for_each_child_of_node(dn, sib)
eeh_add_device_tree_early(sib);
eeh_add_device_early(dn);
}
OpenPOWER on IntegriCloud