aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGavin Shan <gwshan@linux.vnet.ibm.com>2015-02-15 22:45:45 -0500
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2015-03-16 19:31:19 -0400
commit40ae5f693f6ada75e0f2680872dd0bf52bce22c4 (patch)
treeb8c938af1fc8868db46bc4219013170b7878e458
parent7e3e4f8d5e80d2321cb1ab58a2070fbf28883ec1 (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.c170
-rw-r--r--arch/powerpc/platforms/powernv/eeh-powernv.c185
-rw-r--r--arch/powerpc/platforms/powernv/pci.h1
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
49static 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
88static 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 */
197static 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
216static s64 ioda_eeh_phb_poll(struct pnv_phb *phb) 49static 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
788struct pnv_eeh_ops ioda_eeh_ops = { 621struct 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
481static 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
493static 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
532static 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 */
491static int pnv_eeh_get_state(struct eeh_pe *pe, int *delay) 644static 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
80struct pnv_eeh_ops { 80struct 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};