diff options
author | Gavin Shan <gwshan@linux.vnet.ibm.com> | 2014-11-24 17:27:00 -0500 |
---|---|---|
committer | Michael Ellerman <mpe@ellerman.id.au> | 2015-01-22 22:02:52 -0500 |
commit | 2aa5cf9e48f2f39cc255f8e29964df3ff9ca017b (patch) | |
tree | f2aaa35edbb58d7e714f76e5163e26ae7edac04f | |
parent | 6f20e7f2e930211613a66d0603fa4abaaf3ce662 (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.h | 5 | ||||
-rw-r--r-- | arch/powerpc/kernel/eeh_pe.c | 14 | ||||
-rw-r--r-- | arch/powerpc/platforms/powernv/eeh-powernv.c | 11 |
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 | ||