Merge branch 'for-4.16' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/percpu
[sfrench/cifs-2.6.git] / drivers / edac / mv64x60_edac.c
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
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
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. */
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
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
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 **********************************/
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
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
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
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 **********************************/
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
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
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
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
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
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
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
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
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
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
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
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");