aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGavin Shan <gwshan@linux.vnet.ibm.com>2014-11-24 17:27:00 -0500
committerMichael Ellerman <mpe@ellerman.id.au>2015-01-22 22:02:52 -0500
commit2aa5cf9e48f2f39cc255f8e29964df3ff9ca017b (patch)
treef2aaa35edbb58d7e714f76e5163e26ae7edac04f
parent6f20e7f2e930211613a66d0603fa4abaaf3ce662 (diff)
powerpc/eeh: Fix missed PE#0 on P7IOC
PE#0 should be regarded as valid for P7IOC, while it's invalid for PHB3. The patch adds flag EEH_VALID_PE_ZERO to differentiate those two cases. Without the patch, we possibly see frozen PE#0 state is cleared without EEH recovery taken on P7IOC as following kernel logs indicate: [root@ltcfbl8eb ~]# dmesg : pci 0000:00 : [PE# 000] Secondary bus 0 associated with PE#0 pci 0000:01 : [PE# 001] Secondary bus 1 associated with PE#1 pci 0001:00 : [PE# 000] Secondary bus 0 associated with PE#0 pci 0001:01 : [PE# 001] Secondary bus 1 associated with PE#1 pci 0002:00 : [PE# 000] Secondary bus 0 associated with PE#0 pci 0002:01 : [PE# 001] Secondary bus 1 associated with PE#1 pci 0003:00 : [PE# 000] Secondary bus 0 associated with PE#0 pci 0003:01 : [PE# 001] Secondary bus 1 associated with PE#1 pci 0003:20 : [PE# 002] Secondary bus 32..63 associated with PE#2 : EEH: Clear non-existing PHB#3-PE#0 EEH: PHB location: U78AE.001.WZS00M9-P1-002 Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
-rw-r--r--arch/powerpc/include/asm/eeh.h5
-rw-r--r--arch/powerpc/kernel/eeh_pe.c14
-rw-r--r--arch/powerpc/platforms/powernv/eeh-powernv.c11
3 files changed, 25 insertions, 5 deletions
diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h
index 0652ebe117af..9c11d1ed6a36 100644
--- a/arch/powerpc/include/asm/eeh.h
+++ b/arch/powerpc/include/asm/eeh.h
@@ -38,8 +38,9 @@ struct device_node;
38#define EEH_FORCE_DISABLED 0x02 /* EEH disabled */ 38#define EEH_FORCE_DISABLED 0x02 /* EEH disabled */
39#define EEH_PROBE_MODE_DEV 0x04 /* From PCI device */ 39#define EEH_PROBE_MODE_DEV 0x04 /* From PCI device */
40#define EEH_PROBE_MODE_DEVTREE 0x08 /* From device tree */ 40#define EEH_PROBE_MODE_DEVTREE 0x08 /* From device tree */
41#define EEH_ENABLE_IO_FOR_LOG 0x10 /* Enable IO for log */ 41#define EEH_VALID_PE_ZERO 0x10 /* PE#0 is valid */
42#define EEH_EARLY_DUMP_LOG 0x20 /* Dump log immediately */ 42#define EEH_ENABLE_IO_FOR_LOG 0x20 /* Enable IO for log */
43#define EEH_EARLY_DUMP_LOG 0x40 /* Dump log immediately */
43 44
44/* 45/*
45 * Delay for PE reset, all in ms 46 * Delay for PE reset, all in ms
diff --git a/arch/powerpc/kernel/eeh_pe.c b/arch/powerpc/kernel/eeh_pe.c
index 5a63e2b0f65b..fa950fbc2d97 100644
--- a/arch/powerpc/kernel/eeh_pe.c
+++ b/arch/powerpc/kernel/eeh_pe.c
@@ -239,10 +239,18 @@ static void *__eeh_pe_get(void *data, void *flag)
239 if (pe->type & EEH_PE_PHB) 239 if (pe->type & EEH_PE_PHB)
240 return NULL; 240 return NULL;
241 241
242 /* We prefer PE address */ 242 /*
243 if (edev->pe_config_addr && 243 * We prefer PE address. For most cases, we should
244 (edev->pe_config_addr == pe->addr)) 244 * have non-zero PE address
245 */
246 if (eeh_has_flag(EEH_VALID_PE_ZERO)) {
247 if (edev->pe_config_addr == pe->addr)
248 return pe;
249 } else {
250 if (edev->pe_config_addr &&
251 (edev->pe_config_addr == pe->addr))
245 return pe; 252 return pe;
253 }
246 254
247 /* Try BDF address */ 255 /* Try BDF address */
248 if (edev->config_addr && 256 if (edev->config_addr &&
diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c b/arch/powerpc/platforms/powernv/eeh-powernv.c
index 1d19e7917d7f..e261869adc86 100644
--- a/arch/powerpc/platforms/powernv/eeh-powernv.c
+++ b/arch/powerpc/platforms/powernv/eeh-powernv.c
@@ -68,6 +68,17 @@ static int powernv_eeh_init(void)
68 68
69 if (phb->model == PNV_PHB_MODEL_P7IOC) 69 if (phb->model == PNV_PHB_MODEL_P7IOC)
70 eeh_add_flag(EEH_ENABLE_IO_FOR_LOG); 70 eeh_add_flag(EEH_ENABLE_IO_FOR_LOG);
71
72 /*
73 * PE#0 should be regarded as valid by EEH core
74 * if it's not the reserved one. Currently, we
75 * have the reserved PE#0 and PE#127 for PHB3
76 * and P7IOC separately. So we should regard
77 * PE#0 as valid for P7IOC.
78 */
79 if (phb->ioda.reserved_pe != 0)
80 eeh_add_flag(EEH_VALID_PE_ZERO);
81
71 break; 82 break;
72 } 83 }
73 84