• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Marvell MV64x60 Memory Controller kernel module for PPC platforms
3  *
4  * Author: Dave Jiang <djiang@mvista.com>
5  *
6  * 2006-2007 (c) MontaVista Software, Inc. This file is licensed under
7  * the terms of the GNU General Public License version 2. This program
8  * is licensed "as is" without any warranty of any kind, whether express
9  * or implied.
10  *
11  */
12 
13 #include <linux/module.h>
14 #include <linux/init.h>
15 #include <linux/interrupt.h>
16 #include <linux/io.h>
17 #include <linux/edac.h>
18 #include <linux/gfp.h>
19 
20 #include "edac_module.h"
21 #include "mv64x60_edac.h"
22 
23 static const char *mv64x60_ctl_name = "MV64x60";
24 static int edac_dev_idx;
25 static int edac_pci_idx;
26 static int edac_mc_idx;
27 
28 /*********************** PCI err device **********************************/
29 #ifdef CONFIG_PCI
mv64x60_pci_check(struct edac_pci_ctl_info * pci)30 static void mv64x60_pci_check(struct edac_pci_ctl_info *pci)
31 {
32 	struct mv64x60_pci_pdata *pdata = pci->pvt_info;
33 	u32 cause;
34 
35 	cause = readl(pdata->pci_vbase + MV64X60_PCI_ERROR_CAUSE);
36 	if (!cause)
37 		return;
38 
39 	printk(KERN_ERR "Error in PCI %d Interface\n", pdata->pci_hose);
40 	printk(KERN_ERR "Cause register: 0x%08x\n", cause);
41 	printk(KERN_ERR "Address Low: 0x%08x\n",
42 	       readl(pdata->pci_vbase + MV64X60_PCI_ERROR_ADDR_LO));
43 	printk(KERN_ERR "Address High: 0x%08x\n",
44 	       readl(pdata->pci_vbase + MV64X60_PCI_ERROR_ADDR_HI));
45 	printk(KERN_ERR "Attribute: 0x%08x\n",
46 	       readl(pdata->pci_vbase + MV64X60_PCI_ERROR_ATTR));
47 	printk(KERN_ERR "Command: 0x%08x\n",
48 	       readl(pdata->pci_vbase + MV64X60_PCI_ERROR_CMD));
49 	writel(~cause, pdata->pci_vbase + MV64X60_PCI_ERROR_CAUSE);
50 
51 	if (cause & MV64X60_PCI_PE_MASK)
52 		edac_pci_handle_pe(pci, pci->ctl_name);
53 
54 	if (!(cause & MV64X60_PCI_PE_MASK))
55 		edac_pci_handle_npe(pci, pci->ctl_name);
56 }
57 
mv64x60_pci_isr(int irq,void * dev_id)58 static irqreturn_t mv64x60_pci_isr(int irq, void *dev_id)
59 {
60 	struct edac_pci_ctl_info *pci = dev_id;
61 	struct mv64x60_pci_pdata *pdata = pci->pvt_info;
62 	u32 val;
63 
64 	val = readl(pdata->pci_vbase + MV64X60_PCI_ERROR_CAUSE);
65 	if (!val)
66 		return IRQ_NONE;
67 
68 	mv64x60_pci_check(pci);
69 
70 	return IRQ_HANDLED;
71 }
72 
73 /*
74  * Bit 0 of MV64x60_PCIx_ERR_MASK does not exist on the 64360 and because of
75  * errata FEr-#11 and FEr-##16 for the 64460, it should be 0 on that chip as
76  * well.  IOW, don't set bit 0.
77  */
78 
79 /* Erratum FEr PCI-#16: clear bit 0 of PCI SERRn Mask reg. */
mv64x60_pci_fixup(struct platform_device * pdev)80 static int __init mv64x60_pci_fixup(struct platform_device *pdev)
81 {
82 	struct resource *r;
83 	void __iomem *pci_serr;
84 
85 	r = platform_get_resource(pdev, IORESOURCE_MEM, 1);
86 	if (!r) {
87 		printk(KERN_ERR "%s: Unable to get resource for "
88 		       "PCI err regs\n", __func__);
89 		return -ENOENT;
90 	}
91 
92 	pci_serr = ioremap(r->start, resource_size(r));
93 	if (!pci_serr)
94 		return -ENOMEM;
95 
96 	writel(readl(pci_serr) & ~0x1, pci_serr);
97 	iounmap(pci_serr);
98 
99 	return 0;
100 }
101 
mv64x60_pci_err_probe(struct platform_device * pdev)102 static int mv64x60_pci_err_probe(struct platform_device *pdev)
103 {
104 	struct edac_pci_ctl_info *pci;
105 	struct mv64x60_pci_pdata *pdata;
106 	struct resource *r;
107 	int res = 0;
108 
109 	if (!devres_open_group(&pdev->dev, mv64x60_pci_err_probe, GFP_KERNEL))
110 		return -ENOMEM;
111 
112 	pci = edac_pci_alloc_ctl_info(sizeof(*pdata), "mv64x60_pci_err");
113 	if (!pci)
114 		return -ENOMEM;
115 
116 	pdata = pci->pvt_info;
117 
118 	pdata->pci_hose = pdev->id;
119 	pdata->name = "mv64x60_pci_err";
120 	platform_set_drvdata(pdev, pci);
121 	pci->dev = &pdev->dev;
122 	pci->dev_name = dev_name(&pdev->dev);
123 	pci->mod_name = EDAC_MOD_STR;
124 	pci->ctl_name = pdata->name;
125 
126 	if (edac_op_state == EDAC_OPSTATE_POLL)
127 		pci->edac_check = mv64x60_pci_check;
128 
129 	pdata->edac_idx = edac_pci_idx++;
130 
131 	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
132 	if (!r) {
133 		printk(KERN_ERR "%s: Unable to get resource for "
134 		       "PCI err regs\n", __func__);
135 		res = -ENOENT;
136 		goto err;
137 	}
138 
139 	if (!devm_request_mem_region(&pdev->dev,
140 				     r->start,
141 				     resource_size(r),
142 				     pdata->name)) {
143 		printk(KERN_ERR "%s: Error while requesting mem region\n",
144 		       __func__);
145 		res = -EBUSY;
146 		goto err;
147 	}
148 
149 	pdata->pci_vbase = devm_ioremap(&pdev->dev,
150 					r->start,
151 					resource_size(r));
152 	if (!pdata->pci_vbase) {
153 		printk(KERN_ERR "%s: Unable to setup PCI err regs\n", __func__);
154 		res = -ENOMEM;
155 		goto err;
156 	}
157 
158 	res = mv64x60_pci_fixup(pdev);
159 	if (res < 0) {
160 		printk(KERN_ERR "%s: PCI fixup failed\n", __func__);
161 		goto err;
162 	}
163 
164 	writel(0, pdata->pci_vbase + MV64X60_PCI_ERROR_CAUSE);
165 	writel(0, pdata->pci_vbase + MV64X60_PCI_ERROR_MASK);
166 	writel(MV64X60_PCIx_ERR_MASK_VAL,
167 		  pdata->pci_vbase + MV64X60_PCI_ERROR_MASK);
168 
169 	if (edac_pci_add_device(pci, pdata->edac_idx) > 0) {
170 		edac_dbg(3, "failed edac_pci_add_device()\n");
171 		goto err;
172 	}
173 
174 	if (edac_op_state == EDAC_OPSTATE_INT) {
175 		pdata->irq = platform_get_irq(pdev, 0);
176 		res = devm_request_irq(&pdev->dev,
177 				       pdata->irq,
178 				       mv64x60_pci_isr,
179 				       0,
180 				       "[EDAC] PCI err",
181 				       pci);
182 		if (res < 0) {
183 			printk(KERN_ERR "%s: Unable to request irq %d for "
184 			       "MV64x60 PCI ERR\n", __func__, pdata->irq);
185 			res = -ENODEV;
186 			goto err2;
187 		}
188 		printk(KERN_INFO EDAC_MOD_STR " acquired irq %d for PCI Err\n",
189 		       pdata->irq);
190 	}
191 
192 	devres_remove_group(&pdev->dev, mv64x60_pci_err_probe);
193 
194 	/* get this far and it's successful */
195 	edac_dbg(3, "success\n");
196 
197 	return 0;
198 
199 err2:
200 	edac_pci_del_device(&pdev->dev);
201 err:
202 	edac_pci_free_ctl_info(pci);
203 	devres_release_group(&pdev->dev, mv64x60_pci_err_probe);
204 	return res;
205 }
206 
mv64x60_pci_err_remove(struct platform_device * pdev)207 static int mv64x60_pci_err_remove(struct platform_device *pdev)
208 {
209 	struct edac_pci_ctl_info *pci = platform_get_drvdata(pdev);
210 
211 	edac_dbg(0, "\n");
212 
213 	edac_pci_del_device(&pdev->dev);
214 
215 	edac_pci_free_ctl_info(pci);
216 
217 	return 0;
218 }
219 
220 static struct platform_driver mv64x60_pci_err_driver = {
221 	.probe = mv64x60_pci_err_probe,
222 	.remove = mv64x60_pci_err_remove,
223 	.driver = {
224 		   .name = "mv64x60_pci_err",
225 	}
226 };
227 
228 #endif /* CONFIG_PCI */
229 
230 /*********************** SRAM err device **********************************/
mv64x60_sram_check(struct edac_device_ctl_info * edac_dev)231 static void mv64x60_sram_check(struct edac_device_ctl_info *edac_dev)
232 {
233 	struct mv64x60_sram_pdata *pdata = edac_dev->pvt_info;
234 	u32 cause;
235 
236 	cause = readl(pdata->sram_vbase + MV64X60_SRAM_ERR_CAUSE);
237 	if (!cause)
238 		return;
239 
240 	printk(KERN_ERR "Error in internal SRAM\n");
241 	printk(KERN_ERR "Cause register: 0x%08x\n", cause);
242 	printk(KERN_ERR "Address Low: 0x%08x\n",
243 	       readl(pdata->sram_vbase + MV64X60_SRAM_ERR_ADDR_LO));
244 	printk(KERN_ERR "Address High: 0x%08x\n",
245 	       readl(pdata->sram_vbase + MV64X60_SRAM_ERR_ADDR_HI));
246 	printk(KERN_ERR "Data Low: 0x%08x\n",
247 	       readl(pdata->sram_vbase + MV64X60_SRAM_ERR_DATA_LO));
248 	printk(KERN_ERR "Data High: 0x%08x\n",
249 	       readl(pdata->sram_vbase + MV64X60_SRAM_ERR_DATA_HI));
250 	printk(KERN_ERR "Parity: 0x%08x\n",
251 	       readl(pdata->sram_vbase + MV64X60_SRAM_ERR_PARITY));
252 	writel(0, pdata->sram_vbase + MV64X60_SRAM_ERR_CAUSE);
253 
254 	edac_device_handle_ue(edac_dev, 0, 0, edac_dev->ctl_name);
255 }
256 
mv64x60_sram_isr(int irq,void * dev_id)257 static irqreturn_t mv64x60_sram_isr(int irq, void *dev_id)
258 {
259 	struct edac_device_ctl_info *edac_dev = dev_id;
260 	struct mv64x60_sram_pdata *pdata = edac_dev->pvt_info;
261 	u32 cause;
262 
263 	cause = readl(pdata->sram_vbase + MV64X60_SRAM_ERR_CAUSE);
264 	if (!cause)
265 		return IRQ_NONE;
266 
267 	mv64x60_sram_check(edac_dev);
268 
269 	return IRQ_HANDLED;
270 }
271 
mv64x60_sram_err_probe(struct platform_device * pdev)272 static int mv64x60_sram_err_probe(struct platform_device *pdev)
273 {
274 	struct edac_device_ctl_info *edac_dev;
275 	struct mv64x60_sram_pdata *pdata;
276 	struct resource *r;
277 	int res = 0;
278 
279 	if (!devres_open_group(&pdev->dev, mv64x60_sram_err_probe, GFP_KERNEL))
280 		return -ENOMEM;
281 
282 	edac_dev = edac_device_alloc_ctl_info(sizeof(*pdata),
283 					      "sram", 1, NULL, 0, 0, NULL, 0,
284 					      edac_dev_idx);
285 	if (!edac_dev) {
286 		devres_release_group(&pdev->dev, mv64x60_sram_err_probe);
287 		return -ENOMEM;
288 	}
289 
290 	pdata = edac_dev->pvt_info;
291 	pdata->name = "mv64x60_sram_err";
292 	edac_dev->dev = &pdev->dev;
293 	platform_set_drvdata(pdev, edac_dev);
294 	edac_dev->dev_name = dev_name(&pdev->dev);
295 
296 	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
297 	if (!r) {
298 		printk(KERN_ERR "%s: Unable to get resource for "
299 		       "SRAM err regs\n", __func__);
300 		res = -ENOENT;
301 		goto err;
302 	}
303 
304 	if (!devm_request_mem_region(&pdev->dev,
305 				     r->start,
306 				     resource_size(r),
307 				     pdata->name)) {
308 		printk(KERN_ERR "%s: Error while request mem region\n",
309 		       __func__);
310 		res = -EBUSY;
311 		goto err;
312 	}
313 
314 	pdata->sram_vbase = devm_ioremap(&pdev->dev,
315 					 r->start,
316 					 resource_size(r));
317 	if (!pdata->sram_vbase) {
318 		printk(KERN_ERR "%s: Unable to setup SRAM err regs\n",
319 		       __func__);
320 		res = -ENOMEM;
321 		goto err;
322 	}
323 
324 	/* setup SRAM err registers */
325 	writel(0, pdata->sram_vbase + MV64X60_SRAM_ERR_CAUSE);
326 
327 	edac_dev->mod_name = EDAC_MOD_STR;
328 	edac_dev->ctl_name = pdata->name;
329 
330 	if (edac_op_state == EDAC_OPSTATE_POLL)
331 		edac_dev->edac_check = mv64x60_sram_check;
332 
333 	pdata->edac_idx = edac_dev_idx++;
334 
335 	if (edac_device_add_device(edac_dev) > 0) {
336 		edac_dbg(3, "failed edac_device_add_device()\n");
337 		goto err;
338 	}
339 
340 	if (edac_op_state == EDAC_OPSTATE_INT) {
341 		pdata->irq = platform_get_irq(pdev, 0);
342 		res = devm_request_irq(&pdev->dev,
343 				       pdata->irq,
344 				       mv64x60_sram_isr,
345 				       0,
346 				       "[EDAC] SRAM err",
347 				       edac_dev);
348 		if (res < 0) {
349 			printk(KERN_ERR
350 			       "%s: Unable to request irq %d for "
351 			       "MV64x60 SRAM ERR\n", __func__, pdata->irq);
352 			res = -ENODEV;
353 			goto err2;
354 		}
355 
356 		printk(KERN_INFO EDAC_MOD_STR " acquired irq %d for SRAM Err\n",
357 		       pdata->irq);
358 	}
359 
360 	devres_remove_group(&pdev->dev, mv64x60_sram_err_probe);
361 
362 	/* get this far and it's successful */
363 	edac_dbg(3, "success\n");
364 
365 	return 0;
366 
367 err2:
368 	edac_device_del_device(&pdev->dev);
369 err:
370 	devres_release_group(&pdev->dev, mv64x60_sram_err_probe);
371 	edac_device_free_ctl_info(edac_dev);
372 	return res;
373 }
374 
mv64x60_sram_err_remove(struct platform_device * pdev)375 static int mv64x60_sram_err_remove(struct platform_device *pdev)
376 {
377 	struct edac_device_ctl_info *edac_dev = platform_get_drvdata(pdev);
378 
379 	edac_dbg(0, "\n");
380 
381 	edac_device_del_device(&pdev->dev);
382 	edac_device_free_ctl_info(edac_dev);
383 
384 	return 0;
385 }
386 
387 static struct platform_driver mv64x60_sram_err_driver = {
388 	.probe = mv64x60_sram_err_probe,
389 	.remove = mv64x60_sram_err_remove,
390 	.driver = {
391 		   .name = "mv64x60_sram_err",
392 	}
393 };
394 
395 /*********************** CPU err device **********************************/
mv64x60_cpu_check(struct edac_device_ctl_info * edac_dev)396 static void mv64x60_cpu_check(struct edac_device_ctl_info *edac_dev)
397 {
398 	struct mv64x60_cpu_pdata *pdata = edac_dev->pvt_info;
399 	u32 cause;
400 
401 	cause = readl(pdata->cpu_vbase[1] + MV64x60_CPU_ERR_CAUSE) &
402 	    MV64x60_CPU_CAUSE_MASK;
403 	if (!cause)
404 		return;
405 
406 	printk(KERN_ERR "Error on CPU interface\n");
407 	printk(KERN_ERR "Cause register: 0x%08x\n", cause);
408 	printk(KERN_ERR "Address Low: 0x%08x\n",
409 	       readl(pdata->cpu_vbase[0] + MV64x60_CPU_ERR_ADDR_LO));
410 	printk(KERN_ERR "Address High: 0x%08x\n",
411 	       readl(pdata->cpu_vbase[0] + MV64x60_CPU_ERR_ADDR_HI));
412 	printk(KERN_ERR "Data Low: 0x%08x\n",
413 	       readl(pdata->cpu_vbase[1] + MV64x60_CPU_ERR_DATA_LO));
414 	printk(KERN_ERR "Data High: 0x%08x\n",
415 	       readl(pdata->cpu_vbase[1] + MV64x60_CPU_ERR_DATA_HI));
416 	printk(KERN_ERR "Parity: 0x%08x\n",
417 	       readl(pdata->cpu_vbase[1] + MV64x60_CPU_ERR_PARITY));
418 	writel(0, pdata->cpu_vbase[1] + MV64x60_CPU_ERR_CAUSE);
419 
420 	edac_device_handle_ue(edac_dev, 0, 0, edac_dev->ctl_name);
421 }
422 
mv64x60_cpu_isr(int irq,void * dev_id)423 static irqreturn_t mv64x60_cpu_isr(int irq, void *dev_id)
424 {
425 	struct edac_device_ctl_info *edac_dev = dev_id;
426 	struct mv64x60_cpu_pdata *pdata = edac_dev->pvt_info;
427 	u32 cause;
428 
429 	cause = readl(pdata->cpu_vbase[1] + MV64x60_CPU_ERR_CAUSE) &
430 	    MV64x60_CPU_CAUSE_MASK;
431 	if (!cause)
432 		return IRQ_NONE;
433 
434 	mv64x60_cpu_check(edac_dev);
435 
436 	return IRQ_HANDLED;
437 }
438 
mv64x60_cpu_err_probe(struct platform_device * pdev)439 static int mv64x60_cpu_err_probe(struct platform_device *pdev)
440 {
441 	struct edac_device_ctl_info *edac_dev;
442 	struct resource *r;
443 	struct mv64x60_cpu_pdata *pdata;
444 	int res = 0;
445 
446 	if (!devres_open_group(&pdev->dev, mv64x60_cpu_err_probe, GFP_KERNEL))
447 		return -ENOMEM;
448 
449 	edac_dev = edac_device_alloc_ctl_info(sizeof(*pdata),
450 					      "cpu", 1, NULL, 0, 0, NULL, 0,
451 					      edac_dev_idx);
452 	if (!edac_dev) {
453 		devres_release_group(&pdev->dev, mv64x60_cpu_err_probe);
454 		return -ENOMEM;
455 	}
456 
457 	pdata = edac_dev->pvt_info;
458 	pdata->name = "mv64x60_cpu_err";
459 	edac_dev->dev = &pdev->dev;
460 	platform_set_drvdata(pdev, edac_dev);
461 	edac_dev->dev_name = dev_name(&pdev->dev);
462 
463 	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
464 	if (!r) {
465 		printk(KERN_ERR "%s: Unable to get resource for "
466 		       "CPU err regs\n", __func__);
467 		res = -ENOENT;
468 		goto err;
469 	}
470 
471 	if (!devm_request_mem_region(&pdev->dev,
472 				     r->start,
473 				     resource_size(r),
474 				     pdata->name)) {
475 		printk(KERN_ERR "%s: Error while requesting mem region\n",
476 		       __func__);
477 		res = -EBUSY;
478 		goto err;
479 	}
480 
481 	pdata->cpu_vbase[0] = devm_ioremap(&pdev->dev,
482 					   r->start,
483 					   resource_size(r));
484 	if (!pdata->cpu_vbase[0]) {
485 		printk(KERN_ERR "%s: Unable to setup CPU err regs\n", __func__);
486 		res = -ENOMEM;
487 		goto err;
488 	}
489 
490 	r = platform_get_resource(pdev, IORESOURCE_MEM, 1);
491 	if (!r) {
492 		printk(KERN_ERR "%s: Unable to get resource for "
493 		       "CPU err regs\n", __func__);
494 		res = -ENOENT;
495 		goto err;
496 	}
497 
498 	if (!devm_request_mem_region(&pdev->dev,
499 				     r->start,
500 				     resource_size(r),
501 				     pdata->name)) {
502 		printk(KERN_ERR "%s: Error while requesting mem region\n",
503 		       __func__);
504 		res = -EBUSY;
505 		goto err;
506 	}
507 
508 	pdata->cpu_vbase[1] = devm_ioremap(&pdev->dev,
509 					   r->start,
510 					   resource_size(r));
511 	if (!pdata->cpu_vbase[1]) {
512 		printk(KERN_ERR "%s: Unable to setup CPU err regs\n", __func__);
513 		res = -ENOMEM;
514 		goto err;
515 	}
516 
517 	/* setup CPU err registers */
518 	writel(0, pdata->cpu_vbase[1] + MV64x60_CPU_ERR_CAUSE);
519 	writel(0, pdata->cpu_vbase[1] + MV64x60_CPU_ERR_MASK);
520 	writel(0x000000ff, pdata->cpu_vbase[1] + MV64x60_CPU_ERR_MASK);
521 
522 	edac_dev->mod_name = EDAC_MOD_STR;
523 	edac_dev->ctl_name = pdata->name;
524 	if (edac_op_state == EDAC_OPSTATE_POLL)
525 		edac_dev->edac_check = mv64x60_cpu_check;
526 
527 	pdata->edac_idx = edac_dev_idx++;
528 
529 	if (edac_device_add_device(edac_dev) > 0) {
530 		edac_dbg(3, "failed edac_device_add_device()\n");
531 		goto err;
532 	}
533 
534 	if (edac_op_state == EDAC_OPSTATE_INT) {
535 		pdata->irq = platform_get_irq(pdev, 0);
536 		res = devm_request_irq(&pdev->dev,
537 				       pdata->irq,
538 				       mv64x60_cpu_isr,
539 				       0,
540 				       "[EDAC] CPU err",
541 				       edac_dev);
542 		if (res < 0) {
543 			printk(KERN_ERR
544 			       "%s: Unable to request irq %d for MV64x60 "
545 			       "CPU ERR\n", __func__, pdata->irq);
546 			res = -ENODEV;
547 			goto err2;
548 		}
549 
550 		printk(KERN_INFO EDAC_MOD_STR
551 		       " acquired irq %d for CPU Err\n", pdata->irq);
552 	}
553 
554 	devres_remove_group(&pdev->dev, mv64x60_cpu_err_probe);
555 
556 	/* get this far and it's successful */
557 	edac_dbg(3, "success\n");
558 
559 	return 0;
560 
561 err2:
562 	edac_device_del_device(&pdev->dev);
563 err:
564 	devres_release_group(&pdev->dev, mv64x60_cpu_err_probe);
565 	edac_device_free_ctl_info(edac_dev);
566 	return res;
567 }
568 
mv64x60_cpu_err_remove(struct platform_device * pdev)569 static int mv64x60_cpu_err_remove(struct platform_device *pdev)
570 {
571 	struct edac_device_ctl_info *edac_dev = platform_get_drvdata(pdev);
572 
573 	edac_dbg(0, "\n");
574 
575 	edac_device_del_device(&pdev->dev);
576 	edac_device_free_ctl_info(edac_dev);
577 	return 0;
578 }
579 
580 static struct platform_driver mv64x60_cpu_err_driver = {
581 	.probe = mv64x60_cpu_err_probe,
582 	.remove = mv64x60_cpu_err_remove,
583 	.driver = {
584 		   .name = "mv64x60_cpu_err",
585 	}
586 };
587 
588 /*********************** DRAM err device **********************************/
589 
mv64x60_mc_check(struct mem_ctl_info * mci)590 static void mv64x60_mc_check(struct mem_ctl_info *mci)
591 {
592 	struct mv64x60_mc_pdata *pdata = mci->pvt_info;
593 	u32 reg;
594 	u32 err_addr;
595 	u32 sdram_ecc;
596 	u32 comp_ecc;
597 	u32 syndrome;
598 
599 	reg = readl(pdata->mc_vbase + MV64X60_SDRAM_ERR_ADDR);
600 	if (!reg)
601 		return;
602 
603 	err_addr = reg & ~0x3;
604 	sdram_ecc = readl(pdata->mc_vbase + MV64X60_SDRAM_ERR_ECC_RCVD);
605 	comp_ecc = readl(pdata->mc_vbase + MV64X60_SDRAM_ERR_ECC_CALC);
606 	syndrome = sdram_ecc ^ comp_ecc;
607 
608 	/* first bit clear in ECC Err Reg, 1 bit error, correctable by HW */
609 	if (!(reg & 0x1))
610 		edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, 1,
611 				     err_addr >> PAGE_SHIFT,
612 				     err_addr & PAGE_MASK, syndrome,
613 				     0, 0, -1,
614 				     mci->ctl_name, "");
615 	else	/* 2 bit error, UE */
616 		edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, 1,
617 				     err_addr >> PAGE_SHIFT,
618 				     err_addr & PAGE_MASK, 0,
619 				     0, 0, -1,
620 				     mci->ctl_name, "");
621 
622 	/* clear the error */
623 	writel(0, pdata->mc_vbase + MV64X60_SDRAM_ERR_ADDR);
624 }
625 
mv64x60_mc_isr(int irq,void * dev_id)626 static irqreturn_t mv64x60_mc_isr(int irq, void *dev_id)
627 {
628 	struct mem_ctl_info *mci = dev_id;
629 	struct mv64x60_mc_pdata *pdata = mci->pvt_info;
630 	u32 reg;
631 
632 	reg = readl(pdata->mc_vbase + MV64X60_SDRAM_ERR_ADDR);
633 	if (!reg)
634 		return IRQ_NONE;
635 
636 	/* writing 0's to the ECC err addr in check function clears irq */
637 	mv64x60_mc_check(mci);
638 
639 	return IRQ_HANDLED;
640 }
641 
get_total_mem(struct mv64x60_mc_pdata * pdata)642 static void get_total_mem(struct mv64x60_mc_pdata *pdata)
643 {
644 	struct device_node *np = NULL;
645 	const unsigned int *reg;
646 
647 	np = of_find_node_by_type(NULL, "memory");
648 	if (!np)
649 		return;
650 
651 	reg = of_get_property(np, "reg", NULL);
652 
653 	pdata->total_mem = reg[1];
654 }
655 
mv64x60_init_csrows(struct mem_ctl_info * mci,struct mv64x60_mc_pdata * pdata)656 static void mv64x60_init_csrows(struct mem_ctl_info *mci,
657 				struct mv64x60_mc_pdata *pdata)
658 {
659 	struct csrow_info *csrow;
660 	struct dimm_info *dimm;
661 
662 	u32 devtype;
663 	u32 ctl;
664 
665 	get_total_mem(pdata);
666 
667 	ctl = readl(pdata->mc_vbase + MV64X60_SDRAM_CONFIG);
668 
669 	csrow = mci->csrows[0];
670 	dimm = csrow->channels[0]->dimm;
671 
672 	dimm->nr_pages = pdata->total_mem >> PAGE_SHIFT;
673 	dimm->grain = 8;
674 
675 	dimm->mtype = (ctl & MV64X60_SDRAM_REGISTERED) ? MEM_RDDR : MEM_DDR;
676 
677 	devtype = (ctl >> 20) & 0x3;
678 	switch (devtype) {
679 	case 0x0:
680 		dimm->dtype = DEV_X32;
681 		break;
682 	case 0x2:		/* could be X8 too, but no way to tell */
683 		dimm->dtype = DEV_X16;
684 		break;
685 	case 0x3:
686 		dimm->dtype = DEV_X4;
687 		break;
688 	default:
689 		dimm->dtype = DEV_UNKNOWN;
690 		break;
691 	}
692 
693 	dimm->edac_mode = EDAC_SECDED;
694 }
695 
mv64x60_mc_err_probe(struct platform_device * pdev)696 static int mv64x60_mc_err_probe(struct platform_device *pdev)
697 {
698 	struct mem_ctl_info *mci;
699 	struct edac_mc_layer layers[2];
700 	struct mv64x60_mc_pdata *pdata;
701 	struct resource *r;
702 	u32 ctl;
703 	int res = 0;
704 
705 	if (!devres_open_group(&pdev->dev, mv64x60_mc_err_probe, GFP_KERNEL))
706 		return -ENOMEM;
707 
708 	layers[0].type = EDAC_MC_LAYER_CHIP_SELECT;
709 	layers[0].size = 1;
710 	layers[0].is_virt_csrow = true;
711 	layers[1].type = EDAC_MC_LAYER_CHANNEL;
712 	layers[1].size = 1;
713 	layers[1].is_virt_csrow = false;
714 	mci = edac_mc_alloc(edac_mc_idx, ARRAY_SIZE(layers), layers,
715 			    sizeof(struct mv64x60_mc_pdata));
716 	if (!mci) {
717 		printk(KERN_ERR "%s: No memory for CPU err\n", __func__);
718 		devres_release_group(&pdev->dev, mv64x60_mc_err_probe);
719 		return -ENOMEM;
720 	}
721 
722 	pdata = mci->pvt_info;
723 	mci->pdev = &pdev->dev;
724 	platform_set_drvdata(pdev, mci);
725 	pdata->name = "mv64x60_mc_err";
726 	mci->dev_name = dev_name(&pdev->dev);
727 	pdata->edac_idx = edac_mc_idx++;
728 
729 	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
730 	if (!r) {
731 		printk(KERN_ERR "%s: Unable to get resource for "
732 		       "MC err regs\n", __func__);
733 		res = -ENOENT;
734 		goto err;
735 	}
736 
737 	if (!devm_request_mem_region(&pdev->dev,
738 				     r->start,
739 				     resource_size(r),
740 				     pdata->name)) {
741 		printk(KERN_ERR "%s: Error while requesting mem region\n",
742 		       __func__);
743 		res = -EBUSY;
744 		goto err;
745 	}
746 
747 	pdata->mc_vbase = devm_ioremap(&pdev->dev,
748 				       r->start,
749 				       resource_size(r));
750 	if (!pdata->mc_vbase) {
751 		printk(KERN_ERR "%s: Unable to setup MC err regs\n", __func__);
752 		res = -ENOMEM;
753 		goto err;
754 	}
755 
756 	ctl = readl(pdata->mc_vbase + MV64X60_SDRAM_CONFIG);
757 	if (!(ctl & MV64X60_SDRAM_ECC)) {
758 		/* Non-ECC RAM? */
759 		printk(KERN_WARNING "%s: No ECC DIMMs discovered\n", __func__);
760 		res = -ENODEV;
761 		goto err;
762 	}
763 
764 	edac_dbg(3, "init mci\n");
765 	mci->mtype_cap = MEM_FLAG_RDDR | MEM_FLAG_DDR;
766 	mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_SECDED;
767 	mci->edac_cap = EDAC_FLAG_SECDED;
768 	mci->mod_name = EDAC_MOD_STR;
769 	mci->ctl_name = mv64x60_ctl_name;
770 
771 	if (edac_op_state == EDAC_OPSTATE_POLL)
772 		mci->edac_check = mv64x60_mc_check;
773 
774 	mci->ctl_page_to_phys = NULL;
775 
776 	mci->scrub_mode = SCRUB_SW_SRC;
777 
778 	mv64x60_init_csrows(mci, pdata);
779 
780 	/* setup MC registers */
781 	writel(0, pdata->mc_vbase + MV64X60_SDRAM_ERR_ADDR);
782 	ctl = readl(pdata->mc_vbase + MV64X60_SDRAM_ERR_ECC_CNTL);
783 	ctl = (ctl & 0xff00ffff) | 0x10000;
784 	writel(ctl, pdata->mc_vbase + MV64X60_SDRAM_ERR_ECC_CNTL);
785 
786 	res = edac_mc_add_mc(mci);
787 	if (res) {
788 		edac_dbg(3, "failed edac_mc_add_mc()\n");
789 		goto err;
790 	}
791 
792 	if (edac_op_state == EDAC_OPSTATE_INT) {
793 		/* acquire interrupt that reports errors */
794 		pdata->irq = platform_get_irq(pdev, 0);
795 		res = devm_request_irq(&pdev->dev,
796 				       pdata->irq,
797 				       mv64x60_mc_isr,
798 				       0,
799 				       "[EDAC] MC err",
800 				       mci);
801 		if (res < 0) {
802 			printk(KERN_ERR "%s: Unable to request irq %d for "
803 			       "MV64x60 DRAM ERR\n", __func__, pdata->irq);
804 			res = -ENODEV;
805 			goto err2;
806 		}
807 
808 		printk(KERN_INFO EDAC_MOD_STR " acquired irq %d for MC Err\n",
809 		       pdata->irq);
810 	}
811 
812 	/* get this far and it's successful */
813 	edac_dbg(3, "success\n");
814 
815 	return 0;
816 
817 err2:
818 	edac_mc_del_mc(&pdev->dev);
819 err:
820 	devres_release_group(&pdev->dev, mv64x60_mc_err_probe);
821 	edac_mc_free(mci);
822 	return res;
823 }
824 
mv64x60_mc_err_remove(struct platform_device * pdev)825 static int mv64x60_mc_err_remove(struct platform_device *pdev)
826 {
827 	struct mem_ctl_info *mci = platform_get_drvdata(pdev);
828 
829 	edac_dbg(0, "\n");
830 
831 	edac_mc_del_mc(&pdev->dev);
832 	edac_mc_free(mci);
833 	return 0;
834 }
835 
836 static struct platform_driver mv64x60_mc_err_driver = {
837 	.probe = mv64x60_mc_err_probe,
838 	.remove = mv64x60_mc_err_remove,
839 	.driver = {
840 		   .name = "mv64x60_mc_err",
841 	}
842 };
843 
844 static struct platform_driver * const drivers[] = {
845 	&mv64x60_mc_err_driver,
846 	&mv64x60_cpu_err_driver,
847 	&mv64x60_sram_err_driver,
848 #ifdef CONFIG_PCI
849 	&mv64x60_pci_err_driver,
850 #endif
851 };
852 
mv64x60_edac_init(void)853 static int __init mv64x60_edac_init(void)
854 {
855 
856 	printk(KERN_INFO "Marvell MV64x60 EDAC driver " MV64x60_REVISION "\n");
857 	printk(KERN_INFO "\t(C) 2006-2007 MontaVista Software\n");
858 
859 	/* make sure error reporting method is sane */
860 	switch (edac_op_state) {
861 	case EDAC_OPSTATE_POLL:
862 	case EDAC_OPSTATE_INT:
863 		break;
864 	default:
865 		edac_op_state = EDAC_OPSTATE_INT;
866 		break;
867 	}
868 
869 	return platform_register_drivers(drivers, ARRAY_SIZE(drivers));
870 }
871 module_init(mv64x60_edac_init);
872 
mv64x60_edac_exit(void)873 static void __exit mv64x60_edac_exit(void)
874 {
875 	platform_unregister_drivers(drivers, ARRAY_SIZE(drivers));
876 }
877 module_exit(mv64x60_edac_exit);
878 
879 MODULE_LICENSE("GPL");
880 MODULE_AUTHOR("Montavista Software, Inc.");
881 module_param(edac_op_state, int, 0444);
882 MODULE_PARM_DESC(edac_op_state,
883 		 "EDAC Error Reporting state: 0=Poll, 2=Interrupt");
884