aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms
diff options
context:
space:
mode:
authorGavin Shan <shangw@linux.vnet.ibm.com>2013-06-20 01:21:08 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2013-06-20 03:06:27 -0400
commiteb0059836baa14c58ebad030684846213aaece89 (patch)
tree1797c9a63f962a2c3b943881bce6329f61cedf3b /arch/powerpc/platforms
parent73370c662b4e453185201b44b775a49e95870009 (diff)
powerpc/eeh: I/O chip EEH enable option
The patch adds the backend to enable or disable EEH functionality for the specified PE. The backend is also used to enable MMIO or DMA path for the problematic PE. It's notable that all PEs on PowerNV platform support EEH functionality by default, and we disallow to disable EEH for the specific PE. Signed-off-by: Gavin Shan <shangw@linux.vnet.ibm.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/platforms')
-rw-r--r--arch/powerpc/platforms/powernv/eeh-ioda.c65
1 files changed, 64 insertions, 1 deletions
diff --git a/arch/powerpc/platforms/powernv/eeh-ioda.c b/arch/powerpc/platforms/powernv/eeh-ioda.c
index 7b272416b9cc..744eb9e39be2 100644
--- a/arch/powerpc/platforms/powernv/eeh-ioda.c
+++ b/arch/powerpc/platforms/powernv/eeh-ioda.c
@@ -53,9 +53,72 @@ static int ioda_eeh_post_init(struct pci_controller *hose)
53 return 0; 53 return 0;
54} 54}
55 55
56/**
57 * ioda_eeh_set_option - Set EEH operation or I/O setting
58 * @pe: EEH PE
59 * @option: options
60 *
61 * Enable or disable EEH option for the indicated PE. The
62 * function also can be used to enable I/O or DMA for the
63 * PE.
64 */
65static int ioda_eeh_set_option(struct eeh_pe *pe, int option)
66{
67 s64 ret;
68 u32 pe_no;
69 struct pci_controller *hose = pe->phb;
70 struct pnv_phb *phb = hose->private_data;
71
72 /* Check on PE number */
73 if (pe->addr < 0 || pe->addr >= phb->ioda.total_pe) {
74 pr_err("%s: PE address %x out of range [0, %x] "
75 "on PHB#%x\n",
76 __func__, pe->addr, phb->ioda.total_pe,
77 hose->global_number);
78 return -EINVAL;
79 }
80
81 pe_no = pe->addr;
82 switch (option) {
83 case EEH_OPT_DISABLE:
84 ret = -EEXIST;
85 break;
86 case EEH_OPT_ENABLE:
87 ret = 0;
88 break;
89 case EEH_OPT_THAW_MMIO:
90 ret = opal_pci_eeh_freeze_clear(phb->opal_id, pe_no,
91 OPAL_EEH_ACTION_CLEAR_FREEZE_MMIO);
92 if (ret) {
93 pr_warning("%s: Failed to enable MMIO for "
94 "PHB#%x-PE#%x, err=%lld\n",
95 __func__, hose->global_number, pe_no, ret);
96 return -EIO;
97 }
98
99 break;
100 case EEH_OPT_THAW_DMA:
101 ret = opal_pci_eeh_freeze_clear(phb->opal_id, pe_no,
102 OPAL_EEH_ACTION_CLEAR_FREEZE_DMA);
103 if (ret) {
104 pr_warning("%s: Failed to enable DMA for "
105 "PHB#%x-PE#%x, err=%lld\n",
106 __func__, hose->global_number, pe_no, ret);
107 return -EIO;
108 }
109
110 break;
111 default:
112 pr_warning("%s: Invalid option %d\n", __func__, option);
113 return -EINVAL;
114 }
115
116 return ret;
117}
118
56struct pnv_eeh_ops ioda_eeh_ops = { 119struct pnv_eeh_ops ioda_eeh_ops = {
57 .post_init = ioda_eeh_post_init, 120 .post_init = ioda_eeh_post_init,
58 .set_option = NULL, 121 .set_option = ioda_eeh_set_option,
59 .get_state = NULL, 122 .get_state = NULL,
60 .reset = NULL, 123 .reset = NULL,
61 .get_log = NULL, 124 .get_log = NULL,