aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorGavin Shan <gwshan@linux.vnet.ibm.com>2014-05-04 19:29:02 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2014-06-11 03:04:12 -0400
commit2c66599206938412d1781171953d565652ca3b93 (patch)
tree30ddb3eba867f719c59711b5e50fd47f90333142 /arch
parent4817fc323dad9f08f2cb1aca22e6dc7f894c95d5 (diff)
powerpc/eeh: Clear frozen state for child PE
Since commit cb523e09 ("powerpc/eeh: Avoid I/O access during PE reset"), the PE is kept as frozen state on hardware level until the PE reset is done completely. After that, we explicitly clear the frozen state of the affected PE. However, there might have frozen child PEs of the affected PE and we also need clear their frozen state as well. Otherwise, the recovery is going to fail. Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/kernel/eeh_driver.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/arch/powerpc/kernel/eeh_driver.c b/arch/powerpc/kernel/eeh_driver.c
index 7100a5b96e70..8bb40e7cdeb6 100644
--- a/arch/powerpc/kernel/eeh_driver.c
+++ b/arch/powerpc/kernel/eeh_driver.c
@@ -447,8 +447,9 @@ static void *eeh_pe_detach_dev(void *data, void *userdata)
447 * PE reset (for 3 times), we try to clear the frozen state 447 * PE reset (for 3 times), we try to clear the frozen state
448 * for 3 times as well. 448 * for 3 times as well.
449 */ 449 */
450static int eeh_clear_pe_frozen_state(struct eeh_pe *pe) 450static void *__eeh_clear_pe_frozen_state(void *data, void *flag)
451{ 451{
452 struct eeh_pe *pe = (struct eeh_pe *)data;
452 int i, rc; 453 int i, rc;
453 454
454 for (i = 0; i < 3; i++) { 455 for (i = 0; i < 3; i++) {
@@ -461,13 +462,24 @@ static int eeh_clear_pe_frozen_state(struct eeh_pe *pe)
461 } 462 }
462 463
463 /* The PE has been isolated, clear it */ 464 /* The PE has been isolated, clear it */
464 if (rc) 465 if (rc) {
465 pr_warn("%s: Can't clear frozen PHB#%x-PE#%x (%d)\n", 466 pr_warn("%s: Can't clear frozen PHB#%x-PE#%x (%d)\n",
466 __func__, pe->phb->global_number, pe->addr, rc); 467 __func__, pe->phb->global_number, pe->addr, rc);
467 else 468 return (void *)pe;
469 }
470
471 return NULL;
472}
473
474static int eeh_clear_pe_frozen_state(struct eeh_pe *pe)
475{
476 void *rc;
477
478 rc = eeh_pe_traverse(pe, __eeh_clear_pe_frozen_state, NULL);
479 if (!rc)
468 eeh_pe_state_clear(pe, EEH_PE_ISOLATED); 480 eeh_pe_state_clear(pe, EEH_PE_ISOLATED);
469 481
470 return rc; 482 return rc ? -EIO : 0;
471} 483}
472 484
473/** 485/**