aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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
-rw-r--r--include/asm-powerpc/pci-bridge.h8
-rw-r--r--include/asm-powerpc/ppc-pci.h3
5 files changed, 14 insertions, 18 deletions
diff --git a/arch/powerpc/kernel/rtas_pci.c b/arch/powerpc/kernel/rtas_pci.c
index 45b8109951fe..5579f6559912 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)
72 return 0; 72 return 0;
73} 73}
74 74
75static int rtas_read_config(struct pci_dn *pdn, int where, int size, u32 *val) 75int rtas_read_config(struct pci_dn *pdn, int where, int size, u32 *val)
76{ 76{
77 int returnval = -1; 77 int returnval = -1;
78 unsigned long buid, addr; 78 unsigned long buid, addr;
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c
index 02bc1f9d20b9..9e597cb7e659 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);
106static DEFINE_PER_CPU(unsigned long, ignored_failures); 106static DEFINE_PER_CPU(unsigned long, ignored_failures);
107static DEFINE_PER_CPU(unsigned long, slot_resets); 107static DEFINE_PER_CPU(unsigned long, slot_resets);
108 108
109#define IS_BRIDGE(class_code) (((class_code)<<16) == PCI_BASE_CLASS_BRIDGE)
110
109/* --------------------------------------------------------------- */ 111/* --------------------------------------------------------------- */
110/* Below lies the EEH event infrastructure */ 112/* Below lies the EEH event infrastructure */
111 113
@@ -620,7 +622,7 @@ void eeh_restore_bars(struct pci_dn *pdn)
620 if (!pdn) 622 if (!pdn)
621 return; 623 return;
622 624
623 if ((pdn->eeh_mode & EEH_MODE_SUPPORTED) && (!pdn->eeh_is_bridge)) 625 if ((pdn->eeh_mode & EEH_MODE_SUPPORTED) && !IS_BRIDGE(pdn->class_code))
624 __restore_bars (pdn); 626 __restore_bars (pdn);
625 627
626 dn = pdn->node->child; 628 dn = pdn->node->child;
@@ -638,18 +640,15 @@ void eeh_restore_bars(struct pci_dn *pdn)
638 * PCI devices are added individuallly; but, for the restore, 640 * PCI devices are added individuallly; but, for the restore,
639 * an entire slot is reset at a time. 641 * an entire slot is reset at a time.
640 */ 642 */
641void eeh_save_bars(struct pci_dev * pdev, struct pci_dn *pdn) 643static void eeh_save_bars(struct pci_dn *pdn)
642{ 644{
643 int i; 645 int i;
644 646
645 if (!pdev || !pdn ) 647 if (!pdn )
646 return; 648 return;
647 649
648 for (i = 0; i < 16; i++) 650 for (i = 0; i < 16; i++)
649 pci_read_config_dword(pdev, i * 4, &pdn->config_space[i]); 651 rtas_read_config(pdn, i * 4, 4, &pdn->config_space[i]);
650
651 if (pdev->hdr_type == PCI_HEADER_TYPE_BRIDGE)
652 pdn->eeh_is_bridge = 1;
653} 652}
654 653
655void 654void
@@ -699,6 +698,7 @@ static void *early_enable_eeh(struct device_node *dn, void *data)
699 int enable; 698 int enable;
700 struct pci_dn *pdn = PCI_DN(dn); 699 struct pci_dn *pdn = PCI_DN(dn);
701 700
701 pdn->class_code = *class_code;
702 pdn->eeh_mode = 0; 702 pdn->eeh_mode = 0;
703 pdn->eeh_check_count = 0; 703 pdn->eeh_check_count = 0;
704 pdn->eeh_freeze_count = 0; 704 pdn->eeh_freeze_count = 0;
@@ -781,6 +781,7 @@ static void *early_enable_eeh(struct device_node *dn, void *data)
781 dn->full_name); 781 dn->full_name);
782 } 782 }
783 783
784 eeh_save_bars(pdn);
784 return NULL; 785 return NULL;
785} 786}
786 787
@@ -915,7 +916,6 @@ void eeh_add_device_late(struct pci_dev *dev)
915 pdn->pcidev = dev; 916 pdn->pcidev = dev;
916 917
917 pci_addr_cache_insert_device (dev); 918 pci_addr_cache_insert_device (dev);
918 eeh_save_bars(dev, pdn);
919} 919}
920EXPORT_SYMBOL_GPL(eeh_add_device_late); 920EXPORT_SYMBOL_GPL(eeh_add_device_late);
921 921
diff --git a/arch/powerpc/platforms/pseries/eeh_cache.c b/arch/powerpc/platforms/pseries/eeh_cache.c
index ff6c938f424b..71b2187581a3 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)
304 304
305 pci_addr_cache_insert_device(dev); 305 pci_addr_cache_insert_device(dev);
306 306
307 /* Save the BAR's; firmware doesn't restore these after EEH reset */
308 dn = pci_device_to_OF_node(dev); 307 dn = pci_device_to_OF_node(dev);
309 eeh_save_bars(dev, PCI_DN(dn));
310
311 pci_dev_get (dev); /* matching put is in eeh_remove_device() */ 308 pci_dev_get (dev); /* matching put is in eeh_remove_device() */
312 PCI_DN(dn)->pcidev = dev; 309 PCI_DN(dn)->pcidev = dev;
313 } 310 }
diff --git a/include/asm-powerpc/pci-bridge.h b/include/asm-powerpc/pci-bridge.h
index a81bc363f350..b0d816fe2e27 100644
--- a/include/asm-powerpc/pci-bridge.h
+++ b/include/asm-powerpc/pci-bridge.h
@@ -61,9 +61,10 @@ struct pci_controller;
61struct iommu_table; 61struct iommu_table;
62 62
63struct pci_dn { 63struct pci_dn {
64 int busno; /* for pci devices */ 64 int busno; /* pci bus number */
65 int bussubno; /* for pci devices */ 65 int bussubno; /* pci subordinate bus number */
66 int devfn; /* for pci devices */ 66 int devfn; /* pci device and function number */
67 int class_code; /* pci device class */
67 68
68#ifdef CONFIG_PPC_PSERIES 69#ifdef CONFIG_PPC_PSERIES
69 int eeh_mode; /* See eeh.h for possible EEH_MODEs */ 70 int eeh_mode; /* See eeh.h for possible EEH_MODEs */
@@ -71,7 +72,6 @@ struct pci_dn {
71 int eeh_pe_config_addr; /* new-style partition endpoint address */ 72 int eeh_pe_config_addr; /* new-style partition endpoint address */
72 int eeh_check_count; /* # times driver ignored error */ 73 int eeh_check_count; /* # times driver ignored error */
73 int eeh_freeze_count; /* # times this device froze up. */ 74 int eeh_freeze_count; /* # times this device froze up. */
74 int eeh_is_bridge; /* device is pci-to-pci bridge */
75#endif 75#endif
76 int pci_ext_config_space; /* for pci devices */ 76 int pci_ext_config_space; /* for pci devices */
77 struct pci_controller *phb; /* for pci devices */ 77 struct pci_controller *phb; /* for pci devices */
diff --git a/include/asm-powerpc/ppc-pci.h b/include/asm-powerpc/ppc-pci.h
index 1a2db61694f2..f80482c7231f 100644
--- a/include/asm-powerpc/ppc-pci.h
+++ b/include/asm-powerpc/ppc-pci.h
@@ -58,8 +58,6 @@ void pci_addr_cache_remove_device(struct pci_dev *dev);
58void pci_addr_cache_build(void); 58void pci_addr_cache_build(void);
59struct pci_dev *pci_get_device_by_addr(unsigned long addr); 59struct pci_dev *pci_get_device_by_addr(unsigned long addr);
60 60
61void eeh_save_bars(struct pci_dev * pdev, struct pci_dn *pdn);
62
63/** 61/**
64 * eeh_slot_error_detail -- record and EEH error condition to the log 62 * eeh_slot_error_detail -- record and EEH error condition to the log
65 * @severity: 1 if temporary, 2 if permanent failure. 63 * @severity: 1 if temporary, 2 if permanent failure.
@@ -103,6 +101,7 @@ void eeh_restore_bars(struct pci_dn *);
103void rtas_configure_bridge(struct pci_dn *); 101void rtas_configure_bridge(struct pci_dn *);
104 102
105int rtas_write_config(struct pci_dn *, int where, int size, u32 val); 103int rtas_write_config(struct pci_dn *, int where, int size, u32 val);
104int rtas_read_config(struct pci_dn *, int where, int size, u32 *val);
106 105
107/** 106/**
108 * mark and clear slots: find "partition endpoint" PE and set or 107 * mark and clear slots: find "partition endpoint" PE and set or