aboutsummaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorLinas Vepstas <linas@linas.org>2005-11-03 18:55:19 -0600
committerPaul Mackerras <paulus@samba.org>2006-01-10 15:30:39 +1100
commit7684b40cb53ba00cc51271f1c42897b776c48fbc (patch)
tree19155abfd3b76d13b55dfb6fdf1a46e4a8c0a048 /arch
parentd177c207ba16b1db31283e2d1fee7ad4a863584b (diff)
[PATCH] powerpc: Save device BARs much earlier in the boot sequence
241-eeh-save-bars-earlier.patch Save the PCI device bars *before* any PCI probing is done. Signed-off-by: Linas Vepstas <linas@austin.ibm.com> Signed-off-by: Paul Mackerras <paulus@samba.org> (cherry picked from 76c902b919098860f3d4e125f847abcc4cb1782a commit)
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/kernel/rtas_pci.c2
-rw-r--r--arch/powerpc/platforms/pseries/eeh.c16
-rw-r--r--arch/powerpc/platforms/pseries/eeh_cache.c3
3 files changed, 9 insertions, 12 deletions
diff --git a/arch/powerpc/kernel/rtas_pci.c b/arch/powerpc/kernel/rtas_pci.c
index 45b8109951f..5579f655991 100644
--- a/arch/powerpc/kernel/rtas_pci.c
+++ b/arch/powerpc/kernel/rtas_pci.c
@@ -72,7 +72,7 @@ static int of_device_available(struct device_node * dn)
return 0;
}
-static int rtas_read_config(struct pci_dn *pdn, int where, int size, u32 *val)
+int rtas_read_config(struct pci_dn *pdn, int where, int size, u32 *val)
{
int returnval = -1;
unsigned long buid, addr;
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c
index 02bc1f9d20b..9e597cb7e65 100644
--- a/arch/powerpc/platforms/pseries/eeh.c
+++ b/arch/powerpc/platforms/pseries/eeh.c
@@ -106,6 +106,8 @@ static DEFINE_PER_CPU(unsigned long, false_positives);
static DEFINE_PER_CPU(unsigned long, ignored_failures);
static DEFINE_PER_CPU(unsigned long, slot_resets);
+#define IS_BRIDGE(class_code) (((class_code)<<16) == PCI_BASE_CLASS_BRIDGE)
+
/* --------------------------------------------------------------- */
/* Below lies the EEH event infrastructure */
@@ -620,7 +622,7 @@ void eeh_restore_bars(struct pci_dn *pdn)
if (!pdn)
return;
- if ((pdn->eeh_mode & EEH_MODE_SUPPORTED) && (!pdn->eeh_is_bridge))
+ if ((pdn->eeh_mode & EEH_MODE_SUPPORTED) && !IS_BRIDGE(pdn->class_code))
__restore_bars (pdn);
dn = pdn->node->child;
@@ -638,18 +640,15 @@ void eeh_restore_bars(struct pci_dn *pdn)
* PCI devices are added individuallly; but, for the restore,
* an entire slot is reset at a time.
*/
-void eeh_save_bars(struct pci_dev * pdev, struct pci_dn *pdn)
+static void eeh_save_bars(struct pci_dn *pdn)
{
int i;
- if (!pdev || !pdn )
+ if (!pdn )
return;
for (i = 0; i < 16; i++)
- pci_read_config_dword(pdev, i * 4, &pdn->config_space[i]);
-
- if (pdev->hdr_type == PCI_HEADER_TYPE_BRIDGE)
- pdn->eeh_is_bridge = 1;
+ rtas_read_config(pdn, i * 4, 4, &pdn->config_space[i]);
}
void
@@ -699,6 +698,7 @@ static void *early_enable_eeh(struct device_node *dn, void *data)
int enable;
struct pci_dn *pdn = PCI_DN(dn);
+ pdn->class_code = *class_code;
pdn->eeh_mode = 0;
pdn->eeh_check_count = 0;
pdn->eeh_freeze_count = 0;
@@ -781,6 +781,7 @@ static void *early_enable_eeh(struct device_node *dn, void *data)
dn->full_name);
}
+ eeh_save_bars(pdn);
return NULL;
}
@@ -915,7 +916,6 @@ void eeh_add_device_late(struct pci_dev *dev)
pdn->pcidev = dev;
pci_addr_cache_insert_device (dev);
- eeh_save_bars(dev, pdn);
}
EXPORT_SYMBOL_GPL(eeh_add_device_late);
diff --git a/arch/powerpc/platforms/pseries/eeh_cache.c b/arch/powerpc/platforms/pseries/eeh_cache.c
index ff6c938f424..71b2187581a 100644
--- a/arch/powerpc/platforms/pseries/eeh_cache.c
+++ b/arch/powerpc/platforms/pseries/eeh_cache.c
@@ -304,10 +304,7 @@ void __init pci_addr_cache_build(void)
pci_addr_cache_insert_device(dev);
- /* Save the BAR's; firmware doesn't restore these after EEH reset */
dn = pci_device_to_OF_node(dev);
- eeh_save_bars(dev, PCI_DN(dn));
-
pci_dev_get (dev); /* matching put is in eeh_remove_device() */
PCI_DN(dn)->pcidev = dev;
}