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 | }; |