aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/edac/cell_edac.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/edac/cell_edac.c')
-rw-r--r--drivers/edac/cell_edac.c42
1 files changed, 31 insertions, 11 deletions
diff --git a/drivers/edac/cell_edac.c b/drivers/edac/cell_edac.c
index 9a6a274e6925..69ee6aab5c71 100644
--- a/drivers/edac/cell_edac.c
+++ b/drivers/edac/cell_edac.c
@@ -48,8 +48,9 @@ static void cell_edac_count_ce(struct mem_ctl_info *mci, int chan, u64 ar)
48 syndrome = (ar & 0x000000001fe00000ul) >> 21; 48 syndrome = (ar & 0x000000001fe00000ul) >> 21;
49 49
50 /* TODO: Decoding of the error address */ 50 /* TODO: Decoding of the error address */
51 edac_mc_handle_ce(mci, csrow->first_page + pfn, offset, 51 edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci,
52 syndrome, 0, chan, ""); 52 csrow->first_page + pfn, offset, syndrome,
53 0, chan, -1, "", "", NULL);
53} 54}
54 55
55static void cell_edac_count_ue(struct mem_ctl_info *mci, int chan, u64 ar) 56static void cell_edac_count_ue(struct mem_ctl_info *mci, int chan, u64 ar)
@@ -69,7 +70,9 @@ static void cell_edac_count_ue(struct mem_ctl_info *mci, int chan, u64 ar)
69 offset = address & ~PAGE_MASK; 70 offset = address & ~PAGE_MASK;
70 71
71 /* TODO: Decoding of the error address */ 72 /* TODO: Decoding of the error address */
72 edac_mc_handle_ue(mci, csrow->first_page + pfn, offset, 0, ""); 73 edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci,
74 csrow->first_page + pfn, offset, 0,
75 0, chan, -1, "", "", NULL);
73} 76}
74 77
75static void cell_edac_check(struct mem_ctl_info *mci) 78static void cell_edac_check(struct mem_ctl_info *mci)
@@ -124,8 +127,11 @@ static void cell_edac_check(struct mem_ctl_info *mci)
124static void __devinit cell_edac_init_csrows(struct mem_ctl_info *mci) 127static void __devinit cell_edac_init_csrows(struct mem_ctl_info *mci)
125{ 128{
126 struct csrow_info *csrow = &mci->csrows[0]; 129 struct csrow_info *csrow = &mci->csrows[0];
130 struct dimm_info *dimm;
127 struct cell_edac_priv *priv = mci->pvt_info; 131 struct cell_edac_priv *priv = mci->pvt_info;
128 struct device_node *np; 132 struct device_node *np;
133 int j;
134 u32 nr_pages;
129 135
130 for (np = NULL; 136 for (np = NULL;
131 (np = of_find_node_by_name(np, "memory")) != NULL;) { 137 (np = of_find_node_by_name(np, "memory")) != NULL;) {
@@ -140,15 +146,20 @@ static void __devinit cell_edac_init_csrows(struct mem_ctl_info *mci)
140 if (of_node_to_nid(np) != priv->node) 146 if (of_node_to_nid(np) != priv->node)
141 continue; 147 continue;
142 csrow->first_page = r.start >> PAGE_SHIFT; 148 csrow->first_page = r.start >> PAGE_SHIFT;
143 csrow->nr_pages = resource_size(&r) >> PAGE_SHIFT; 149 nr_pages = resource_size(&r) >> PAGE_SHIFT;
144 csrow->last_page = csrow->first_page + csrow->nr_pages - 1; 150 csrow->last_page = csrow->first_page + nr_pages - 1;
145 csrow->mtype = MEM_XDR; 151
146 csrow->edac_mode = EDAC_SECDED; 152 for (j = 0; j < csrow->nr_channels; j++) {
153 dimm = csrow->channels[j].dimm;
154 dimm->mtype = MEM_XDR;
155 dimm->edac_mode = EDAC_SECDED;
156 dimm->nr_pages = nr_pages / csrow->nr_channels;
157 }
147 dev_dbg(mci->dev, 158 dev_dbg(mci->dev,
148 "Initialized on node %d, chanmask=0x%x," 159 "Initialized on node %d, chanmask=0x%x,"
149 " first_page=0x%lx, nr_pages=0x%x\n", 160 " first_page=0x%lx, nr_pages=0x%x\n",
150 priv->node, priv->chanmask, 161 priv->node, priv->chanmask,
151 csrow->first_page, csrow->nr_pages); 162 csrow->first_page, nr_pages);
152 break; 163 break;
153 } 164 }
154} 165}
@@ -157,9 +168,10 @@ static int __devinit cell_edac_probe(struct platform_device *pdev)
157{ 168{
158 struct cbe_mic_tm_regs __iomem *regs; 169 struct cbe_mic_tm_regs __iomem *regs;
159 struct mem_ctl_info *mci; 170 struct mem_ctl_info *mci;
171 struct edac_mc_layer layers[2];
160 struct cell_edac_priv *priv; 172 struct cell_edac_priv *priv;
161 u64 reg; 173 u64 reg;
162 int rc, chanmask; 174 int rc, chanmask, num_chans;
163 175
164 regs = cbe_get_cpu_mic_tm_regs(cbe_node_to_cpu(pdev->id)); 176 regs = cbe_get_cpu_mic_tm_regs(cbe_node_to_cpu(pdev->id));
165 if (regs == NULL) 177 if (regs == NULL)
@@ -184,8 +196,16 @@ static int __devinit cell_edac_probe(struct platform_device *pdev)
184 in_be64(&regs->mic_fir)); 196 in_be64(&regs->mic_fir));
185 197
186 /* Allocate & init EDAC MC data structure */ 198 /* Allocate & init EDAC MC data structure */
187 mci = edac_mc_alloc(sizeof(struct cell_edac_priv), 1, 199 num_chans = chanmask == 3 ? 2 : 1;
188 chanmask == 3 ? 2 : 1, pdev->id); 200
201 layers[0].type = EDAC_MC_LAYER_CHIP_SELECT;
202 layers[0].size = 1;
203 layers[0].is_virt_csrow = true;
204 layers[1].type = EDAC_MC_LAYER_CHANNEL;
205 layers[1].size = num_chans;
206 layers[1].is_virt_csrow = false;
207 mci = edac_mc_alloc(pdev->id, ARRAY_SIZE(layers), layers,
208 sizeof(struct cell_edac_priv));
189 if (mci == NULL) 209 if (mci == NULL)
190 return -ENOMEM; 210 return -ENOMEM;
191 priv = mci->pvt_info; 211 priv = mci->pvt_info;