Commit 7684b40c authored by Linas Vepstas's avatar Linas Vepstas Committed by Paul Mackerras

[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: default avatarLinas Vepstas <linas@austin.ibm.com>
Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
(cherry picked from 76c902b919098860f3d4e125f847abcc4cb1782a commit)
parent d177c207
...@@ -72,7 +72,7 @@ static int of_device_available(struct device_node * dn) ...@@ -72,7 +72,7 @@ static int of_device_available(struct device_node * dn)
return 0; 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; int returnval = -1;
unsigned long buid, addr; unsigned long buid, addr;
......
...@@ -106,6 +106,8 @@ static DEFINE_PER_CPU(unsigned long, false_positives); ...@@ -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, ignored_failures);
static DEFINE_PER_CPU(unsigned long, slot_resets); 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 */ /* Below lies the EEH event infrastructure */
...@@ -620,7 +622,7 @@ void eeh_restore_bars(struct pci_dn *pdn) ...@@ -620,7 +622,7 @@ void eeh_restore_bars(struct pci_dn *pdn)
if (!pdn) if (!pdn)
return; 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); __restore_bars (pdn);
dn = pdn->node->child; dn = pdn->node->child;
...@@ -638,18 +640,15 @@ void eeh_restore_bars(struct pci_dn *pdn) ...@@ -638,18 +640,15 @@ void eeh_restore_bars(struct pci_dn *pdn)
* PCI devices are added individuallly; but, for the restore, * PCI devices are added individuallly; but, for the restore,
* an entire slot is reset at a time. * 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; int i;
if (!pdev || !pdn ) if (!pdn )
return; return;
for (i = 0; i < 16; i++) for (i = 0; i < 16; i++)
pci_read_config_dword(pdev, i * 4, &pdn->config_space[i]); rtas_read_config(pdn, i * 4, 4, &pdn->config_space[i]);
if (pdev->hdr_type == PCI_HEADER_TYPE_BRIDGE)
pdn->eeh_is_bridge = 1;
} }
void void
...@@ -699,6 +698,7 @@ static void *early_enable_eeh(struct device_node *dn, void *data) ...@@ -699,6 +698,7 @@ static void *early_enable_eeh(struct device_node *dn, void *data)
int enable; int enable;
struct pci_dn *pdn = PCI_DN(dn); struct pci_dn *pdn = PCI_DN(dn);
pdn->class_code = *class_code;
pdn->eeh_mode = 0; pdn->eeh_mode = 0;
pdn->eeh_check_count = 0; pdn->eeh_check_count = 0;
pdn->eeh_freeze_count = 0; pdn->eeh_freeze_count = 0;
...@@ -781,6 +781,7 @@ static void *early_enable_eeh(struct device_node *dn, void *data) ...@@ -781,6 +781,7 @@ static void *early_enable_eeh(struct device_node *dn, void *data)
dn->full_name); dn->full_name);
} }
eeh_save_bars(pdn);
return NULL; return NULL;
} }
...@@ -915,7 +916,6 @@ void eeh_add_device_late(struct pci_dev *dev) ...@@ -915,7 +916,6 @@ void eeh_add_device_late(struct pci_dev *dev)
pdn->pcidev = dev; pdn->pcidev = dev;
pci_addr_cache_insert_device (dev); pci_addr_cache_insert_device (dev);
eeh_save_bars(dev, pdn);
} }
EXPORT_SYMBOL_GPL(eeh_add_device_late); EXPORT_SYMBOL_GPL(eeh_add_device_late);
......
...@@ -304,10 +304,7 @@ void __init pci_addr_cache_build(void) ...@@ -304,10 +304,7 @@ void __init pci_addr_cache_build(void)
pci_addr_cache_insert_device(dev); 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); 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_dev_get (dev); /* matching put is in eeh_remove_device() */
PCI_DN(dn)->pcidev = dev; PCI_DN(dn)->pcidev = dev;
} }
......
...@@ -61,9 +61,10 @@ struct pci_controller; ...@@ -61,9 +61,10 @@ struct pci_controller;
struct iommu_table; struct iommu_table;
struct pci_dn { struct pci_dn {
int busno; /* for pci devices */ int busno; /* pci bus number */
int bussubno; /* for pci devices */ int bussubno; /* pci subordinate bus number */
int devfn; /* for pci devices */ int devfn; /* pci device and function number */
int class_code; /* pci device class */
#ifdef CONFIG_PPC_PSERIES #ifdef CONFIG_PPC_PSERIES
int eeh_mode; /* See eeh.h for possible EEH_MODEs */ int eeh_mode; /* See eeh.h for possible EEH_MODEs */
...@@ -71,7 +72,6 @@ struct pci_dn { ...@@ -71,7 +72,6 @@ struct pci_dn {
int eeh_pe_config_addr; /* new-style partition endpoint address */ int eeh_pe_config_addr; /* new-style partition endpoint address */
int eeh_check_count; /* # times driver ignored error */ int eeh_check_count; /* # times driver ignored error */
int eeh_freeze_count; /* # times this device froze up. */ int eeh_freeze_count; /* # times this device froze up. */
int eeh_is_bridge; /* device is pci-to-pci bridge */
#endif #endif
int pci_ext_config_space; /* for pci devices */ int pci_ext_config_space; /* for pci devices */
struct pci_controller *phb; /* for pci devices */ struct pci_controller *phb; /* for pci devices */
......
...@@ -58,8 +58,6 @@ void pci_addr_cache_remove_device(struct pci_dev *dev); ...@@ -58,8 +58,6 @@ void pci_addr_cache_remove_device(struct pci_dev *dev);
void pci_addr_cache_build(void); void pci_addr_cache_build(void);
struct pci_dev *pci_get_device_by_addr(unsigned long addr); struct pci_dev *pci_get_device_by_addr(unsigned long addr);
void eeh_save_bars(struct pci_dev * pdev, struct pci_dn *pdn);
/** /**
* eeh_slot_error_detail -- record and EEH error condition to the log * eeh_slot_error_detail -- record and EEH error condition to the log
* @severity: 1 if temporary, 2 if permanent failure. * @severity: 1 if temporary, 2 if permanent failure.
...@@ -103,6 +101,7 @@ void eeh_restore_bars(struct pci_dn *); ...@@ -103,6 +101,7 @@ void eeh_restore_bars(struct pci_dn *);
void rtas_configure_bridge(struct pci_dn *); void rtas_configure_bridge(struct pci_dn *);
int rtas_write_config(struct pci_dn *, int where, int size, u32 val); int rtas_write_config(struct pci_dn *, int where, int size, u32 val);
int rtas_read_config(struct pci_dn *, int where, int size, u32 *val);
/** /**
* mark and clear slots: find "partition endpoint" PE and set or * mark and clear slots: find "partition endpoint" PE and set or
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment