diff options
| author | Gavin Shan <gwshan@linux.vnet.ibm.com> | 2015-02-15 22:45:45 -0500 |
|---|---|---|
| committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2015-03-16 19:31:19 -0400 |
| commit | 40ae5f693f6ada75e0f2680872dd0bf52bce22c4 (patch) | |
| tree | b8c938af1fc8868db46bc4219013170b7878e458 | |
| parent | 7e3e4f8d5e80d2321cb1ab58a2070fbf28883ec1 (diff) | |
powerpc/powernv: Drop PHB operation get_state()
The patch drops PHB EEH operation get_state() and merges its logic
to eeh_ops::get_state().
Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
| -rw-r--r-- | arch/powerpc/platforms/powernv/eeh-ioda.c | 170 | ||||
| -rw-r--r-- | arch/powerpc/platforms/powernv/eeh-powernv.c | 185 | ||||
| -rw-r--r-- | arch/powerpc/platforms/powernv/pci.h | 1 |
3 files changed, 170 insertions, 186 deletions
diff --git a/arch/powerpc/platforms/powernv/eeh-ioda.c b/arch/powerpc/platforms/powernv/eeh-ioda.c index 349c0830f535..dc34c36805dc 100644 --- a/arch/powerpc/platforms/powernv/eeh-ioda.c +++ b/arch/powerpc/platforms/powernv/eeh-ioda.c | |||
| @@ -46,173 +46,6 @@ static void ioda_eeh_phb_diag(struct eeh_pe *pe) | |||
| 46 | __func__, pe->phb->global_number, rc); | 46 | __func__, pe->phb->global_number, rc); |
| 47 | } | 47 | } |
| 48 | 48 | ||
| 49 | static int ioda_eeh_get_phb_state(struct eeh_pe *pe) | ||
| 50 | { | ||
| 51 | struct pnv_phb *phb = pe->phb->private_data; | ||
| 52 | u8 fstate; | ||
| 53 | __be16 pcierr; | ||
| 54 | s64 rc; | ||
| 55 | int result = 0; | ||
| 56 | |||
| 57 | rc = opal_pci_eeh_freeze_status(phb->opal_id, | ||
| 58 | pe->addr, | ||
| 59 | &fstate, | ||
| 60 | &pcierr, | ||
| 61 | NULL); | ||
| 62 | if (rc != OPAL_SUCCESS) { | ||
| 63 | pr_warn("%s: Failure %lld getting PHB#%x state\n", | ||
| 64 | __func__, rc, phb->hose->global_number); | ||
| 65 | return EEH_STATE_NOT_SUPPORT; | ||
| 66 | } | ||
| 67 | |||
| 68 | /* | ||
| 69 | * Check PHB state. If the PHB is frozen for the | ||
| 70 | * first time, to dump the PHB diag-data. | ||
| 71 | */ | ||
| 72 | if (be16_to_cpu(pcierr) != OPAL_EEH_PHB_ERROR) { | ||
| 73 | result = (EEH_STATE_MMIO_ACTIVE | | ||
| 74 | EEH_STATE_DMA_ACTIVE | | ||
| 75 | EEH_STATE_MMIO_ENABLED | | ||
| 76 | EEH_STATE_DMA_ENABLED); | ||
| 77 | } else if (!(pe->state & EEH_PE_ISOLATED)) { | ||
| 78 | eeh_pe_state_mark(pe, EEH_PE_ISOLATED); | ||
| 79 | ioda_eeh_phb_diag(pe); | ||
| 80 | |||
| 81 | if (eeh_has_flag(EEH_EARLY_DUMP_LOG)) | ||
| 82 | pnv_pci_dump_phb_diag_data(pe->phb, pe->data); | ||
| 83 | } | ||
| 84 | |||
| 85 | return result; | ||
| 86 | } | ||
| 87 | |||
| 88 | static int ioda_eeh_get_pe_state(struct eeh_pe *pe) | ||
| 89 | { | ||
| 90 | struct pnv_phb *phb = pe->phb->private_data; | ||
| 91 | u8 fstate; | ||
| 92 | __be16 pcierr; | ||
| 93 | s64 rc; | ||
| 94 | int result; | ||
| 95 | |||
| 96 | /* | ||
| 97 | * We don't clobber hardware frozen state until PE | ||
| 98 | * reset is completed. In order to keep EEH core | ||
| 99 | * moving forward, we have to return operational | ||
| 100 | * state during PE reset. | ||
| 101 | */ | ||
| 102 | if (pe->state & EEH_PE_RESET) { | ||
| 103 | result = (EEH_STATE_MMIO_ACTIVE | | ||
| 104 | EEH_STATE_DMA_ACTIVE | | ||
| 105 | EEH_STATE_MMIO_ENABLED | | ||
| 106 | EEH_STATE_DMA_ENABLED); | ||
| 107 | return result; | ||
| 108 | } | ||
| 109 | |||
| 110 | /* | ||
| 111 | * Fetch PE state from hardware. If the PHB | ||
| 112 | * supports compound PE, let it handle that. | ||
| 113 | */ | ||
| 114 | if (phb->get_pe_state) { | ||
| 115 | fstate = phb->get_pe_state(phb, pe->addr); | ||
| 116 | } else { | ||
| 117 | rc = opal_pci_eeh_freeze_status(phb->opal_id, | ||
| 118 | pe->addr, | ||
| 119 | &fstate, | ||
| 120 | &pcierr, | ||
| 121 | NULL); | ||
| 122 | if (rc != OPAL_SUCCESS) { | ||
| 123 | pr_warn("%s: Failure %lld getting PHB#%x-PE%x state\n", | ||
| 124 | __func__, rc, phb->hose->global_number, pe->addr); | ||
| 125 | return EEH_STATE_NOT_SUPPORT; | ||
| 126 | } | ||
| 127 | } | ||
| 128 | |||
| 129 | /* Figure out state */ | ||
| 130 | switch (fstate) { | ||
| 131 | case OPAL_EEH_STOPPED_NOT_FROZEN: | ||
| 132 | result = (EEH_STATE_MMIO_ACTIVE | | ||
| 133 | EEH_STATE_DMA_ACTIVE | | ||
| 134 | EEH_STATE_MMIO_ENABLED | | ||
| 135 | EEH_STATE_DMA_ENABLED); | ||
| 136 | break; | ||
| 137 | case OPAL_EEH_STOPPED_MMIO_FREEZE: | ||
| 138 | result = (EEH_STATE_DMA_ACTIVE | | ||
| 139 | EEH_STATE_DMA_ENABLED); | ||
| 140 | break; | ||
| 141 | case OPAL_EEH_STOPPED_DMA_FREEZE: | ||
| 142 | result = (EEH_STATE_MMIO_ACTIVE | | ||
| 143 | EEH_STATE_MMIO_ENABLED); | ||
| 144 | break; | ||
| 145 | case OPAL_EEH_STOPPED_MMIO_DMA_FREEZE: | ||
| 146 | result = 0; | ||
| 147 | break; | ||
| 148 | case OPAL_EEH_STOPPED_RESET: | ||
| 149 | result = EEH_STATE_RESET_ACTIVE; | ||
| 150 | break; | ||
| 151 | case OPAL_EEH_STOPPED_TEMP_UNAVAIL: | ||
| 152 | result = EEH_STATE_UNAVAILABLE; | ||
| 153 | break; | ||
| 154 | case OPAL_EEH_STOPPED_PERM_UNAVAIL: | ||
| 155 | result = EEH_STATE_NOT_SUPPORT; | ||
| 156 | break; | ||
| 157 | default: | ||
| 158 | result = EEH_STATE_NOT_SUPPORT; | ||
| 159 | pr_warn("%s: Invalid PHB#%x-PE#%x state %x\n", | ||
| 160 | __func__, phb->hose->global_number, | ||
| 161 | pe->addr, fstate); | ||
| 162 | } | ||
| 163 | |||
| 164 | /* | ||
| 165 | * If PHB supports compound PE, to freeze all | ||
| 166 | * slave PEs for consistency. | ||
| 167 | * | ||
| 168 | * If the PE is switching to frozen state for the | ||
| 169 | * first time, to dump the PHB diag-data. | ||
| 170 | */ | ||
| 171 | if (!(result & EEH_STATE_NOT_SUPPORT) && | ||
| 172 | !(result & EEH_STATE_UNAVAILABLE) && | ||
| 173 | !(result & EEH_STATE_MMIO_ACTIVE) && | ||
| 174 | !(result & EEH_STATE_DMA_ACTIVE) && | ||
| 175 | !(pe->state & EEH_PE_ISOLATED)) { | ||
| 176 | if (phb->freeze_pe) | ||
| 177 | phb->freeze_pe(phb, pe->addr); | ||
| 178 | |||
| 179 | eeh_pe_state_mark(pe, EEH_PE_ISOLATED); | ||
| 180 | ioda_eeh_phb_diag(pe); | ||
| 181 | |||
| 182 | if (eeh_has_flag(EEH_EARLY_DUMP_LOG)) | ||
| 183 | pnv_pci_dump_phb_diag_data(pe->phb, pe->data); | ||
| 184 | } | ||
| 185 | |||
| 186 | return result; | ||
| 187 | } | ||
| 188 | |||
| 189 | /** | ||
| 190 | * ioda_eeh_get_state - Retrieve the state of PE | ||
| 191 | * @pe: EEH PE | ||
| 192 | * | ||
| 193 | * The PE's state should be retrieved from the PEEV, PEST | ||
| 194 | * IODA tables. Since the OPAL has exported the function | ||
| 195 | * to do it, it'd better to use that. | ||
| 196 | */ | ||
| 197 | static int ioda_eeh_get_state(struct eeh_pe *pe) | ||
| 198 | { | ||
| 199 | struct pnv_phb *phb = pe->phb->private_data; | ||
| 200 | |||
| 201 | /* Sanity check on PE number. PHB PE should have 0 */ | ||
| 202 | if (pe->addr < 0 || | ||
| 203 | pe->addr >= phb->ioda.total_pe) { | ||
| 204 | pr_warn("%s: PHB#%x-PE#%x out of range [0, %x]\n", | ||
| 205 | __func__, phb->hose->global_number, | ||
| 206 | pe->addr, phb->ioda.total_pe); | ||
| 207 | return EEH_STATE_NOT_SUPPORT; | ||
| 208 | } | ||
| 209 | |||
| 210 | if (pe->type & EEH_PE_PHB) | ||
| 211 | return ioda_eeh_get_phb_state(pe); | ||
| 212 | |||
| 213 | return ioda_eeh_get_pe_state(pe); | ||
| 214 | } | ||
| 215 | |||
| 216 | static s64 ioda_eeh_phb_poll(struct pnv_phb *phb) | 49 | static s64 ioda_eeh_phb_poll(struct pnv_phb *phb) |
| 217 | { | 50 | { |
| 218 | s64 rc = OPAL_HARDWARE; | 51 | s64 rc = OPAL_HARDWARE; |
| @@ -759,7 +592,7 @@ static int ioda_eeh_next_error(struct eeh_pe **pe) | |||
| 759 | break; | 592 | break; |
| 760 | 593 | ||
| 761 | /* Frozen parent PE ? */ | 594 | /* Frozen parent PE ? */ |
| 762 | state = ioda_eeh_get_state(parent_pe); | 595 | state = eeh_ops->get_state(parent_pe, NULL); |
| 763 | if (state > 0 && | 596 | if (state > 0 && |
| 764 | (state & active_flags) != active_flags) | 597 | (state & active_flags) != active_flags) |
| 765 | *pe = parent_pe; | 598 | *pe = parent_pe; |
| @@ -786,7 +619,6 @@ static int ioda_eeh_next_error(struct eeh_pe **pe) | |||
| 786 | } | 619 | } |
| 787 | 620 | ||
| 788 | struct pnv_eeh_ops ioda_eeh_ops = { | 621 | struct pnv_eeh_ops ioda_eeh_ops = { |
| 789 | .get_state = ioda_eeh_get_state, | ||
| 790 | .reset = ioda_eeh_reset, | 622 | .reset = ioda_eeh_reset, |
| 791 | .next_error = ioda_eeh_next_error | 623 | .next_error = ioda_eeh_next_error |
| 792 | }; | 624 | }; |
diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c b/arch/powerpc/platforms/powernv/eeh-powernv.c index 2429a23d4802..127ef0cc7c5b 100644 --- a/arch/powerpc/platforms/powernv/eeh-powernv.c +++ b/arch/powerpc/platforms/powernv/eeh-powernv.c | |||
| @@ -478,6 +478,159 @@ static int pnv_eeh_get_pe_addr(struct eeh_pe *pe) | |||
| 478 | return pe->addr; | 478 | return pe->addr; |
| 479 | } | 479 | } |
| 480 | 480 | ||
| 481 | static void pnv_eeh_get_phb_diag(struct eeh_pe *pe) | ||
| 482 | { | ||
| 483 | struct pnv_phb *phb = pe->phb->private_data; | ||
| 484 | s64 rc; | ||
| 485 | |||
| 486 | rc = opal_pci_get_phb_diag_data2(phb->opal_id, pe->data, | ||
| 487 | PNV_PCI_DIAG_BUF_SIZE); | ||
| 488 | if (rc != OPAL_SUCCESS) | ||
| 489 | pr_warn("%s: Failure %lld getting PHB#%x diag-data\n", | ||
| 490 | __func__, rc, pe->phb->global_number); | ||
| 491 | } | ||
| 492 | |||
| 493 | static int pnv_eeh_get_phb_state(struct eeh_pe *pe) | ||
| 494 | { | ||
| 495 | struct pnv_phb *phb = pe->phb->private_data; | ||
| 496 | u8 fstate; | ||
| 497 | __be16 pcierr; | ||
| 498 | s64 rc; | ||
| 499 | int result = 0; | ||
| 500 | |||
| 501 | rc = opal_pci_eeh_freeze_status(phb->opal_id, | ||
| 502 | pe->addr, | ||
| 503 | &fstate, | ||
| 504 | &pcierr, | ||
| 505 | NULL); | ||
| 506 | if (rc != OPAL_SUCCESS) { | ||
| 507 | pr_warn("%s: Failure %lld getting PHB#%x state\n", | ||
| 508 | __func__, rc, phb->hose->global_number); | ||
| 509 | return EEH_STATE_NOT_SUPPORT; | ||
| 510 | } | ||
| 511 | |||
| 512 | /* | ||
| 513 | * Check PHB state. If the PHB is frozen for the | ||
| 514 | * first time, to dump the PHB diag-data. | ||
| 515 | */ | ||
| 516 | if (be16_to_cpu(pcierr) != OPAL_EEH_PHB_ERROR) { | ||
| 517 | result = (EEH_STATE_MMIO_ACTIVE | | ||
| 518 | EEH_STATE_DMA_ACTIVE | | ||
| 519 | EEH_STATE_MMIO_ENABLED | | ||
| 520 | EEH_STATE_DMA_ENABLED); | ||
| 521 | } else if (!(pe->state & EEH_PE_ISOLATED)) { | ||
| 522 | eeh_pe_state_mark(pe, EEH_PE_ISOLATED); | ||
| 523 | pnv_eeh_get_phb_diag(pe); | ||
| 524 | |||
| 525 | if (eeh_has_flag(EEH_EARLY_DUMP_LOG)) | ||
| 526 | pnv_pci_dump_phb_diag_data(pe->phb, pe->data); | ||
| 527 | } | ||
| 528 | |||
| 529 | return result; | ||
| 530 | } | ||
| 531 | |||
| 532 | static int pnv_eeh_get_pe_state(struct eeh_pe *pe) | ||
| 533 | { | ||
| 534 | struct pnv_phb *phb = pe->phb->private_data; | ||
| 535 | u8 fstate; | ||
| 536 | __be16 pcierr; | ||
| 537 | s64 rc; | ||
| 538 | int result; | ||
| 539 | |||
| 540 | /* | ||
| 541 | * We don't clobber hardware frozen state until PE | ||
| 542 | * reset is completed. In order to keep EEH core | ||
| 543 | * moving forward, we have to return operational | ||
| 544 | * state during PE reset. | ||
| 545 | */ | ||
| 546 | if (pe->state & EEH_PE_RESET) { | ||
| 547 | result = (EEH_STATE_MMIO_ACTIVE | | ||
| 548 | EEH_STATE_DMA_ACTIVE | | ||
| 549 | EEH_STATE_MMIO_ENABLED | | ||
| 550 | EEH_STATE_DMA_ENABLED); | ||
| 551 | return result; | ||
| 552 | } | ||
| 553 | |||
| 554 | /* | ||
| 555 | * Fetch PE state from hardware. If the PHB | ||
| 556 | * supports compound PE, let it handle that. | ||
| 557 | */ | ||
| 558 | if (phb->get_pe_state) { | ||
| 559 | fstate = phb->get_pe_state(phb, pe->addr); | ||
| 560 | } else { | ||
| 561 | rc = opal_pci_eeh_freeze_status(phb->opal_id, | ||
| 562 | pe->addr, | ||
| 563 | &fstate, | ||
| 564 | &pcierr, | ||
| 565 | NULL); | ||
| 566 | if (rc != OPAL_SUCCESS) { | ||
| 567 | pr_warn("%s: Failure %lld getting PHB#%x-PE%x state\n", | ||
| 568 | __func__, rc, phb->hose->global_number, | ||
| 569 | pe->addr); | ||
| 570 | return EEH_STATE_NOT_SUPPORT; | ||
| 571 | } | ||
| 572 | } | ||
| 573 | |||
| 574 | /* Figure out state */ | ||
| 575 | switch (fstate) { | ||
| 576 | case OPAL_EEH_STOPPED_NOT_FROZEN: | ||
| 577 | result = (EEH_STATE_MMIO_ACTIVE | | ||
| 578 | EEH_STATE_DMA_ACTIVE | | ||
| 579 | EEH_STATE_MMIO_ENABLED | | ||
| 580 | EEH_STATE_DMA_ENABLED); | ||
| 581 | break; | ||
| 582 | case OPAL_EEH_STOPPED_MMIO_FREEZE: | ||
| 583 | result = (EEH_STATE_DMA_ACTIVE | | ||
| 584 | EEH_STATE_DMA_ENABLED); | ||
| 585 | break; | ||
| 586 | case OPAL_EEH_STOPPED_DMA_FREEZE: | ||
| 587 | result = (EEH_STATE_MMIO_ACTIVE | | ||
| 588 | EEH_STATE_MMIO_ENABLED); | ||
| 589 | break; | ||
| 590 | case OPAL_EEH_STOPPED_MMIO_DMA_FREEZE: | ||
| 591 | result = 0; | ||
| 592 | break; | ||
| 593 | case OPAL_EEH_STOPPED_RESET: | ||
| 594 | result = EEH_STATE_RESET_ACTIVE; | ||
| 595 | break; | ||
| 596 | case OPAL_EEH_STOPPED_TEMP_UNAVAIL: | ||
| 597 | result = EEH_STATE_UNAVAILABLE; | ||
| 598 | break; | ||
| 599 | case OPAL_EEH_STOPPED_PERM_UNAVAIL: | ||
| 600 | result = EEH_STATE_NOT_SUPPORT; | ||
| 601 | break; | ||
| 602 | default: | ||
| 603 | result = EEH_STATE_NOT_SUPPORT; | ||
| 604 | pr_warn("%s: Invalid PHB#%x-PE#%x state %x\n", | ||
| 605 | __func__, phb->hose->global_number, | ||
| 606 | pe->addr, fstate); | ||
| 607 | } | ||
| 608 | |||
| 609 | /* | ||
| 610 | * If PHB supports compound PE, to freeze all | ||
| 611 | * slave PEs for consistency. | ||
| 612 | * | ||
| 613 | * If the PE is switching to frozen state for the | ||
| 614 | * first time, to dump the PHB diag-data. | ||
| 615 | */ | ||
| 616 | if (!(result & EEH_STATE_NOT_SUPPORT) && | ||
| 617 | !(result & EEH_STATE_UNAVAILABLE) && | ||
| 618 | !(result & EEH_STATE_MMIO_ACTIVE) && | ||
| 619 | !(result & EEH_STATE_DMA_ACTIVE) && | ||
| 620 | !(pe->state & EEH_PE_ISOLATED)) { | ||
| 621 | if (phb->freeze_pe) | ||
| 622 | phb->freeze_pe(phb, pe->addr); | ||
| 623 | |||
| 624 | eeh_pe_state_mark(pe, EEH_PE_ISOLATED); | ||
| 625 | pnv_eeh_get_phb_diag(pe); | ||
| 626 | |||
| 627 | if (eeh_has_flag(EEH_EARLY_DUMP_LOG)) | ||
| 628 | pnv_pci_dump_phb_diag_data(pe->phb, pe->data); | ||
| 629 | } | ||
| 630 | |||
| 631 | return result; | ||
| 632 | } | ||
| 633 | |||
| 481 | /** | 634 | /** |
| 482 | * pnv_eeh_get_state - Retrieve PE state | 635 | * pnv_eeh_get_state - Retrieve PE state |
| 483 | * @pe: EEH PE | 636 | * @pe: EEH PE |
| @@ -490,24 +643,24 @@ static int pnv_eeh_get_pe_addr(struct eeh_pe *pe) | |||
| 490 | */ | 643 | */ |
| 491 | static int pnv_eeh_get_state(struct eeh_pe *pe, int *delay) | 644 | static int pnv_eeh_get_state(struct eeh_pe *pe, int *delay) |
| 492 | { | 645 | { |
| 493 | struct pci_controller *hose = pe->phb; | 646 | int ret; |
| 494 | struct pnv_phb *phb = hose->private_data; | ||
| 495 | int ret = EEH_STATE_NOT_SUPPORT; | ||
| 496 | 647 | ||
| 497 | if (phb->eeh_ops && phb->eeh_ops->get_state) { | 648 | if (pe->type & EEH_PE_PHB) |
| 498 | ret = phb->eeh_ops->get_state(pe); | 649 | ret = pnv_eeh_get_phb_state(pe); |
| 650 | else | ||
| 651 | ret = pnv_eeh_get_pe_state(pe); | ||
| 499 | 652 | ||
| 500 | /* | 653 | if (!delay) |
| 501 | * If the PE state is temporarily unavailable, | 654 | return ret; |
| 502 | * to inform the EEH core delay for default | 655 | |
| 503 | * period (1 second) | 656 | /* |
| 504 | */ | 657 | * If the PE state is temporarily unavailable, |
| 505 | if (delay) { | 658 | * to inform the EEH core delay for default |
| 506 | *delay = 0; | 659 | * period (1 second) |
| 507 | if (ret & EEH_STATE_UNAVAILABLE) | 660 | */ |
| 508 | *delay = 1000; | 661 | *delay = 0; |
| 509 | } | 662 | if (ret & EEH_STATE_UNAVAILABLE) |
| 510 | } | 663 | *delay = 1000; |
| 511 | 664 | ||
| 512 | return ret; | 665 | return ret; |
| 513 | } | 666 | } |
diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h index 8043dee64a51..773a026bfee2 100644 --- a/arch/powerpc/platforms/powernv/pci.h +++ b/arch/powerpc/platforms/powernv/pci.h | |||
| @@ -78,7 +78,6 @@ struct pnv_ioda_pe { | |||
| 78 | /* IOC dependent EEH operations */ | 78 | /* IOC dependent EEH operations */ |
| 79 | #ifdef CONFIG_EEH | 79 | #ifdef CONFIG_EEH |
| 80 | struct pnv_eeh_ops { | 80 | struct pnv_eeh_ops { |
| 81 | int (*get_state)(struct eeh_pe *pe); | ||
| 82 | int (*reset)(struct eeh_pe *pe, int option); | 81 | int (*reset)(struct eeh_pe *pe, int option); |
| 83 | int (*next_error)(struct eeh_pe **pe); | 82 | int (*next_error)(struct eeh_pe **pe); |
| 84 | }; | 83 | }; |
