EDAC: Sanitize MODULE_AUTHOR strings
[linux-block.git] / drivers / edac / mpc85xx_edac.c
CommitLineData
a9a753d5 1/*
775c503f 2 * Freescale MPC85xx Memory Controller kernel module
a9a753d5 3 *
c92132f5
CL
4 * Parts Copyrighted (c) 2013 by Freescale Semiconductor, Inc.
5 *
a9a753d5
DJ
6 * Author: Dave Jiang <djiang@mvista.com>
7 *
8 * 2006-2007 (c) MontaVista Software, Inc. This file is licensed under
9 * the terms of the GNU General Public License version 2. This program
10 * is licensed "as is" without any warranty of any kind, whether express
11 * or implied.
12 *
13 */
14#include <linux/module.h>
15#include <linux/init.h>
a9a753d5
DJ
16#include <linux/interrupt.h>
17#include <linux/ctype.h>
18#include <linux/io.h>
19#include <linux/mod_devicetable.h>
20#include <linux/edac.h>
60be7551 21#include <linux/smp.h>
5a0e3ad6 22#include <linux/gfp.h>
666db563 23#include <linux/fsl/edac.h>
a9a753d5
DJ
24
25#include <linux/of_platform.h>
26#include <linux/of_device.h>
4177ab22
ME
27#include <linux/of_address.h>
28#include <linux/of_irq.h>
a9a753d5 29#include "edac_module.h"
a9a753d5 30#include "mpc85xx_edac.h"
ea2eb9a8 31#include "fsl_ddr_edac.h"
a9a753d5
DJ
32
33static int edac_dev_idx;
0616fb00 34#ifdef CONFIG_PCI
a9a753d5 35static int edac_pci_idx;
0616fb00 36#endif
a9a753d5
DJ
37
38/*
39 * PCI Err defines
40 */
41#ifdef CONFIG_PCI
42static u32 orig_pci_err_cap_dr;
43static u32 orig_pci_err_en;
44#endif
45
46static u32 orig_l2_err_disable;
a9a753d5 47
a9a753d5
DJ
48/**************************** PCI Err device ***************************/
49#ifdef CONFIG_PCI
50
51static void mpc85xx_pci_check(struct edac_pci_ctl_info *pci)
52{
53 struct mpc85xx_pci_pdata *pdata = pci->pvt_info;
54 u32 err_detect;
55
56 err_detect = in_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_DR);
57
58 /* master aborts can happen during PCI config cycles */
59 if (!(err_detect & ~(PCI_EDE_MULTI_ERR | PCI_EDE_MST_ABRT))) {
60 out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_DR, err_detect);
61 return;
62 }
63
88857ebe
YS
64 pr_err("PCI error(s) detected\n");
65 pr_err("PCI/X ERR_DR register: %#08x\n", err_detect);
a9a753d5 66
88857ebe 67 pr_err("PCI/X ERR_ATTRIB register: %#08x\n",
a9a753d5 68 in_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_ATTRIB));
88857ebe 69 pr_err("PCI/X ERR_ADDR register: %#08x\n",
a9a753d5 70 in_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_ADDR));
88857ebe 71 pr_err("PCI/X ERR_EXT_ADDR register: %#08x\n",
a9a753d5 72 in_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_EXT_ADDR));
88857ebe 73 pr_err("PCI/X ERR_DL register: %#08x\n",
a9a753d5 74 in_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_DL));
88857ebe 75 pr_err("PCI/X ERR_DH register: %#08x\n",
a9a753d5
DJ
76 in_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_DH));
77
78 /* clear error bits */
79 out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_DR, err_detect);
80
81 if (err_detect & PCI_EDE_PERR_MASK)
82 edac_pci_handle_pe(pci, pci->ctl_name);
83
84 if ((err_detect & ~PCI_EDE_MULTI_ERR) & ~PCI_EDE_PERR_MASK)
85 edac_pci_handle_npe(pci, pci->ctl_name);
86}
87
c92132f5
CL
88static void mpc85xx_pcie_check(struct edac_pci_ctl_info *pci)
89{
90 struct mpc85xx_pci_pdata *pdata = pci->pvt_info;
6fa06b0d 91 u32 err_detect, err_cap_stat;
c92132f5
CL
92
93 err_detect = in_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_DR);
6fa06b0d 94 err_cap_stat = in_be32(pdata->pci_vbase + MPC85XX_PCI_GAS_TIMR);
c92132f5
CL
95
96 pr_err("PCIe error(s) detected\n");
97 pr_err("PCIe ERR_DR register: 0x%08x\n", err_detect);
6fa06b0d 98 pr_err("PCIe ERR_CAP_STAT register: 0x%08x\n", err_cap_stat);
c92132f5
CL
99 pr_err("PCIe ERR_CAP_R0 register: 0x%08x\n",
100 in_be32(pdata->pci_vbase + MPC85XX_PCIE_ERR_CAP_R0));
101 pr_err("PCIe ERR_CAP_R1 register: 0x%08x\n",
102 in_be32(pdata->pci_vbase + MPC85XX_PCIE_ERR_CAP_R1));
103 pr_err("PCIe ERR_CAP_R2 register: 0x%08x\n",
104 in_be32(pdata->pci_vbase + MPC85XX_PCIE_ERR_CAP_R2));
105 pr_err("PCIe ERR_CAP_R3 register: 0x%08x\n",
106 in_be32(pdata->pci_vbase + MPC85XX_PCIE_ERR_CAP_R3));
107
108 /* clear error bits */
109 out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_DR, err_detect);
6fa06b0d
TH
110
111 /* reset error capture */
112 out_be32(pdata->pci_vbase + MPC85XX_PCI_GAS_TIMR, err_cap_stat | 0x1);
c92132f5
CL
113}
114
115static int mpc85xx_pcie_find_capability(struct device_node *np)
116{
117 struct pci_controller *hose;
118
119 if (!np)
120 return -EINVAL;
121
122 hose = pci_find_hose_for_OF_device(np);
123
124 return early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP);
125}
126
a9a753d5
DJ
127static irqreturn_t mpc85xx_pci_isr(int irq, void *dev_id)
128{
129 struct edac_pci_ctl_info *pci = dev_id;
130 struct mpc85xx_pci_pdata *pdata = pci->pvt_info;
131 u32 err_detect;
132
133 err_detect = in_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_DR);
134
135 if (!err_detect)
136 return IRQ_NONE;
137
c92132f5
CL
138 if (pdata->is_pcie)
139 mpc85xx_pcie_check(pci);
140 else
141 mpc85xx_pci_check(pci);
a9a753d5
DJ
142
143 return IRQ_HANDLED;
144}
145
666db563 146static int mpc85xx_pci_err_probe(struct platform_device *op)
a9a753d5
DJ
147{
148 struct edac_pci_ctl_info *pci;
149 struct mpc85xx_pci_pdata *pdata;
666db563
SW
150 struct mpc85xx_edac_pci_plat_data *plat_data;
151 struct device_node *of_node;
f87bd330 152 struct resource r;
a9a753d5
DJ
153 int res = 0;
154
f87bd330 155 if (!devres_open_group(&op->dev, mpc85xx_pci_err_probe, GFP_KERNEL))
a9a753d5
DJ
156 return -ENOMEM;
157
158 pci = edac_pci_alloc_ctl_info(sizeof(*pdata), "mpc85xx_pci_err");
159 if (!pci)
160 return -ENOMEM;
161
905e75c4
JH
162 /* make sure error reporting method is sane */
163 switch (edac_op_state) {
164 case EDAC_OPSTATE_POLL:
165 case EDAC_OPSTATE_INT:
166 break;
167 default:
168 edac_op_state = EDAC_OPSTATE_INT;
169 break;
170 }
171
a9a753d5
DJ
172 pdata = pci->pvt_info;
173 pdata->name = "mpc85xx_pci_err";
c92132f5 174
666db563
SW
175 plat_data = op->dev.platform_data;
176 if (!plat_data) {
177 dev_err(&op->dev, "no platform data");
178 res = -ENXIO;
179 goto err;
180 }
181 of_node = plat_data->of_node;
182
183 if (mpc85xx_pcie_find_capability(of_node) > 0)
c92132f5
CL
184 pdata->is_pcie = true;
185
f87bd330
DJ
186 dev_set_drvdata(&op->dev, pci);
187 pci->dev = &op->dev;
a9a753d5
DJ
188 pci->mod_name = EDAC_MOD_STR;
189 pci->ctl_name = pdata->name;
031d5518 190 pci->dev_name = dev_name(&op->dev);
a9a753d5 191
c92132f5
CL
192 if (edac_op_state == EDAC_OPSTATE_POLL) {
193 if (pdata->is_pcie)
194 pci->edac_check = mpc85xx_pcie_check;
195 else
196 pci->edac_check = mpc85xx_pci_check;
197 }
a9a753d5
DJ
198
199 pdata->edac_idx = edac_pci_idx++;
200
666db563 201 res = of_address_to_resource(of_node, 0, &r);
f87bd330 202 if (res) {
88857ebe 203 pr_err("%s: Unable to get resource for PCI err regs\n", __func__);
a9a753d5
DJ
204 goto err;
205 }
206
f87bd330
DJ
207 /* we only need the error registers */
208 r.start += 0xe00;
209
66ed3f75
HS
210 if (!devm_request_mem_region(&op->dev, r.start, resource_size(&r),
211 pdata->name)) {
88857ebe 212 pr_err("%s: Error while requesting mem region\n", __func__);
a9a753d5
DJ
213 res = -EBUSY;
214 goto err;
215 }
216
66ed3f75 217 pdata->pci_vbase = devm_ioremap(&op->dev, r.start, resource_size(&r));
a9a753d5 218 if (!pdata->pci_vbase) {
88857ebe 219 pr_err("%s: Unable to setup PCI err regs\n", __func__);
a9a753d5
DJ
220 res = -ENOMEM;
221 goto err;
222 }
223
c92132f5
CL
224 if (pdata->is_pcie) {
225 orig_pci_err_cap_dr =
226 in_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_ADDR);
227 out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_ADDR, ~0);
228 orig_pci_err_en =
229 in_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_EN);
230 out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_EN, 0);
231 } else {
232 orig_pci_err_cap_dr =
233 in_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_CAP_DR);
234
235 /* PCI master abort is expected during config cycles */
236 out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_CAP_DR, 0x40);
237
238 orig_pci_err_en =
239 in_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_EN);
240
241 /* disable master abort reporting */
242 out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_EN, ~0x40);
243 }
a9a753d5
DJ
244
245 /* clear error bits */
246 out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_DR, ~0);
247
6fa06b0d
TH
248 /* reset error capture */
249 out_be32(pdata->pci_vbase + MPC85XX_PCI_GAS_TIMR, 0x1);
250
a9a753d5 251 if (edac_pci_add_device(pci, pdata->edac_idx) > 0) {
956b9ba1 252 edac_dbg(3, "failed edac_pci_add_device()\n");
a9a753d5
DJ
253 goto err;
254 }
255
256 if (edac_op_state == EDAC_OPSTATE_INT) {
666db563 257 pdata->irq = irq_of_parse_and_map(of_node, 0);
f87bd330 258 res = devm_request_irq(&op->dev, pdata->irq,
c92132f5 259 mpc85xx_pci_isr,
e245e3b2 260 IRQF_SHARED,
a9a753d5
DJ
261 "[EDAC] PCI err", pci);
262 if (res < 0) {
88857ebe
YS
263 pr_err("%s: Unable to request irq %d for MPC85xx PCI err\n",
264 __func__, pdata->irq);
f87bd330 265 irq_dispose_mapping(pdata->irq);
a9a753d5
DJ
266 res = -ENODEV;
267 goto err2;
268 }
269
88857ebe 270 pr_info(EDAC_MOD_STR " acquired irq %d for PCI Err\n",
a9a753d5
DJ
271 pdata->irq);
272 }
273
c92132f5
CL
274 if (pdata->is_pcie) {
275 /*
276 * Enable all PCIe error interrupt & error detect except invalid
277 * PEX_CONFIG_ADDR/PEX_CONFIG_DATA access interrupt generation
278 * enable bit and invalid PEX_CONFIG_ADDR/PEX_CONFIG_DATA access
279 * detection enable bit. Because PCIe bus code to initialize and
280 * configure these PCIe devices on booting will use some invalid
281 * PEX_CONFIG_ADDR/PEX_CONFIG_DATA, edac driver prints the much
282 * notice information. So disable this detect to fix ugly print.
283 */
284 out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_EN, ~0
285 & ~PEX_ERR_ICCAIE_EN_BIT);
286 out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_ADDR, 0
287 | PEX_ERR_ICCAD_DISR_BIT);
288 }
289
f87bd330 290 devres_remove_group(&op->dev, mpc85xx_pci_err_probe);
956b9ba1 291 edac_dbg(3, "success\n");
88857ebe 292 pr_info(EDAC_MOD_STR " PCI err registered\n");
a9a753d5
DJ
293
294 return 0;
295
296err2:
f87bd330 297 edac_pci_del_device(&op->dev);
a9a753d5
DJ
298err:
299 edac_pci_free_ctl_info(pci);
f87bd330 300 devres_release_group(&op->dev, mpc85xx_pci_err_probe);
a9a753d5
DJ
301 return res;
302}
303
27bda205
YJ
304static int mpc85xx_pci_err_remove(struct platform_device *op)
305{
306 struct edac_pci_ctl_info *pci = dev_get_drvdata(&op->dev);
307 struct mpc85xx_pci_pdata *pdata = pci->pvt_info;
308
309 edac_dbg(0, "\n");
310
311 out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_ADDR, orig_pci_err_cap_dr);
312 out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_EN, orig_pci_err_en);
313
314 edac_pci_del_device(&op->dev);
315 edac_pci_free_ctl_info(pci);
316
317 return 0;
318}
319
666db563
SW
320static const struct platform_device_id mpc85xx_pci_err_match[] = {
321 {
322 .name = "mpc85xx-pci-edac"
323 },
324 {}
325};
326
327static struct platform_driver mpc85xx_pci_err_driver = {
328 .probe = mpc85xx_pci_err_probe,
27bda205 329 .remove = mpc85xx_pci_err_remove,
666db563
SW
330 .id_table = mpc85xx_pci_err_match,
331 .driver = {
332 .name = "mpc85xx_pci_err",
333 .suppress_bind_attrs = true,
334 },
335};
a9a753d5
DJ
336#endif /* CONFIG_PCI */
337
338/**************************** L2 Err device ***************************/
339
340/************************ L2 SYSFS parts ***********************************/
341
342static ssize_t mpc85xx_l2_inject_data_hi_show(struct edac_device_ctl_info
343 *edac_dev, char *data)
344{
345 struct mpc85xx_l2_pdata *pdata = edac_dev->pvt_info;
346 return sprintf(data, "0x%08x",
347 in_be32(pdata->l2_vbase + MPC85XX_L2_ERRINJHI));
348}
349
350static ssize_t mpc85xx_l2_inject_data_lo_show(struct edac_device_ctl_info
351 *edac_dev, char *data)
352{
353 struct mpc85xx_l2_pdata *pdata = edac_dev->pvt_info;
354 return sprintf(data, "0x%08x",
355 in_be32(pdata->l2_vbase + MPC85XX_L2_ERRINJLO));
356}
357
358static ssize_t mpc85xx_l2_inject_ctrl_show(struct edac_device_ctl_info
359 *edac_dev, char *data)
360{
361 struct mpc85xx_l2_pdata *pdata = edac_dev->pvt_info;
362 return sprintf(data, "0x%08x",
363 in_be32(pdata->l2_vbase + MPC85XX_L2_ERRINJCTL));
364}
365
366static ssize_t mpc85xx_l2_inject_data_hi_store(struct edac_device_ctl_info
367 *edac_dev, const char *data,
368 size_t count)
369{
370 struct mpc85xx_l2_pdata *pdata = edac_dev->pvt_info;
371 if (isdigit(*data)) {
372 out_be32(pdata->l2_vbase + MPC85XX_L2_ERRINJHI,
373 simple_strtoul(data, NULL, 0));
374 return count;
375 }
376 return 0;
377}
378
379static ssize_t mpc85xx_l2_inject_data_lo_store(struct edac_device_ctl_info
380 *edac_dev, const char *data,
381 size_t count)
382{
383 struct mpc85xx_l2_pdata *pdata = edac_dev->pvt_info;
384 if (isdigit(*data)) {
385 out_be32(pdata->l2_vbase + MPC85XX_L2_ERRINJLO,
386 simple_strtoul(data, NULL, 0));
387 return count;
388 }
389 return 0;
390}
391
392static ssize_t mpc85xx_l2_inject_ctrl_store(struct edac_device_ctl_info
393 *edac_dev, const char *data,
394 size_t count)
395{
396 struct mpc85xx_l2_pdata *pdata = edac_dev->pvt_info;
397 if (isdigit(*data)) {
398 out_be32(pdata->l2_vbase + MPC85XX_L2_ERRINJCTL,
399 simple_strtoul(data, NULL, 0));
400 return count;
401 }
402 return 0;
403}
404
405static struct edac_dev_sysfs_attribute mpc85xx_l2_sysfs_attributes[] = {
406 {
407 .attr = {
408 .name = "inject_data_hi",
409 .mode = (S_IRUGO | S_IWUSR)
410 },
411 .show = mpc85xx_l2_inject_data_hi_show,
412 .store = mpc85xx_l2_inject_data_hi_store},
413 {
414 .attr = {
415 .name = "inject_data_lo",
416 .mode = (S_IRUGO | S_IWUSR)
417 },
418 .show = mpc85xx_l2_inject_data_lo_show,
419 .store = mpc85xx_l2_inject_data_lo_store},
420 {
421 .attr = {
422 .name = "inject_ctrl",
423 .mode = (S_IRUGO | S_IWUSR)
424 },
425 .show = mpc85xx_l2_inject_ctrl_show,
426 .store = mpc85xx_l2_inject_ctrl_store},
427
428 /* End of list */
429 {
430 .attr = {.name = NULL}
431 }
432};
433
434static void mpc85xx_set_l2_sysfs_attributes(struct edac_device_ctl_info
435 *edac_dev)
436{
437 edac_dev->sysfs_attributes = mpc85xx_l2_sysfs_attributes;
438}
439
440/***************************** L2 ops ***********************************/
441
442static void mpc85xx_l2_check(struct edac_device_ctl_info *edac_dev)
443{
444 struct mpc85xx_l2_pdata *pdata = edac_dev->pvt_info;
445 u32 err_detect;
446
447 err_detect = in_be32(pdata->l2_vbase + MPC85XX_L2_ERRDET);
448
449 if (!(err_detect & L2_EDE_MASK))
450 return;
451
88857ebe
YS
452 pr_err("ECC Error in CPU L2 cache\n");
453 pr_err("L2 Error Detect Register: 0x%08x\n", err_detect);
454 pr_err("L2 Error Capture Data High Register: 0x%08x\n",
a9a753d5 455 in_be32(pdata->l2_vbase + MPC85XX_L2_CAPTDATAHI));
88857ebe 456 pr_err("L2 Error Capture Data Lo Register: 0x%08x\n",
a9a753d5 457 in_be32(pdata->l2_vbase + MPC85XX_L2_CAPTDATALO));
88857ebe 458 pr_err("L2 Error Syndrome Register: 0x%08x\n",
a9a753d5 459 in_be32(pdata->l2_vbase + MPC85XX_L2_CAPTECC));
88857ebe 460 pr_err("L2 Error Attributes Capture Register: 0x%08x\n",
a9a753d5 461 in_be32(pdata->l2_vbase + MPC85XX_L2_ERRATTR));
88857ebe 462 pr_err("L2 Error Address Capture Register: 0x%08x\n",
a9a753d5
DJ
463 in_be32(pdata->l2_vbase + MPC85XX_L2_ERRADDR));
464
465 /* clear error detect register */
466 out_be32(pdata->l2_vbase + MPC85XX_L2_ERRDET, err_detect);
467
468 if (err_detect & L2_EDE_CE_MASK)
469 edac_device_handle_ce(edac_dev, 0, 0, edac_dev->ctl_name);
470
471 if (err_detect & L2_EDE_UE_MASK)
472 edac_device_handle_ue(edac_dev, 0, 0, edac_dev->ctl_name);
473}
474
475static irqreturn_t mpc85xx_l2_isr(int irq, void *dev_id)
476{
477 struct edac_device_ctl_info *edac_dev = dev_id;
478 struct mpc85xx_l2_pdata *pdata = edac_dev->pvt_info;
479 u32 err_detect;
480
481 err_detect = in_be32(pdata->l2_vbase + MPC85XX_L2_ERRDET);
482
483 if (!(err_detect & L2_EDE_MASK))
484 return IRQ_NONE;
485
486 mpc85xx_l2_check(edac_dev);
487
488 return IRQ_HANDLED;
489}
490
9b3c6e85 491static int mpc85xx_l2_err_probe(struct platform_device *op)
a9a753d5
DJ
492{
493 struct edac_device_ctl_info *edac_dev;
494 struct mpc85xx_l2_pdata *pdata;
495 struct resource r;
496 int res;
497
498 if (!devres_open_group(&op->dev, mpc85xx_l2_err_probe, GFP_KERNEL))
499 return -ENOMEM;
500
501 edac_dev = edac_device_alloc_ctl_info(sizeof(*pdata),
502 "cpu", 1, "L", 1, 2, NULL, 0,
503 edac_dev_idx);
504 if (!edac_dev) {
505 devres_release_group(&op->dev, mpc85xx_l2_err_probe);
506 return -ENOMEM;
507 }
508
509 pdata = edac_dev->pvt_info;
510 pdata->name = "mpc85xx_l2_err";
a9a753d5
DJ
511 edac_dev->dev = &op->dev;
512 dev_set_drvdata(edac_dev->dev, edac_dev);
513 edac_dev->ctl_name = pdata->name;
514 edac_dev->dev_name = pdata->name;
515
a26f95fe 516 res = of_address_to_resource(op->dev.of_node, 0, &r);
a9a753d5 517 if (res) {
88857ebe 518 pr_err("%s: Unable to get resource for L2 err regs\n", __func__);
a9a753d5
DJ
519 goto err;
520 }
521
522 /* we only need the error registers */
523 r.start += 0xe00;
524
28f65c11
JP
525 if (!devm_request_mem_region(&op->dev, r.start, resource_size(&r),
526 pdata->name)) {
88857ebe 527 pr_err("%s: Error while requesting mem region\n", __func__);
a9a753d5
DJ
528 res = -EBUSY;
529 goto err;
530 }
531
28f65c11 532 pdata->l2_vbase = devm_ioremap(&op->dev, r.start, resource_size(&r));
a9a753d5 533 if (!pdata->l2_vbase) {
88857ebe 534 pr_err("%s: Unable to setup L2 err regs\n", __func__);
a9a753d5
DJ
535 res = -ENOMEM;
536 goto err;
537 }
538
539 out_be32(pdata->l2_vbase + MPC85XX_L2_ERRDET, ~0);
540
541 orig_l2_err_disable = in_be32(pdata->l2_vbase + MPC85XX_L2_ERRDIS);
542
543 /* clear the err_dis */
544 out_be32(pdata->l2_vbase + MPC85XX_L2_ERRDIS, 0);
545
546 edac_dev->mod_name = EDAC_MOD_STR;
547
548 if (edac_op_state == EDAC_OPSTATE_POLL)
549 edac_dev->edac_check = mpc85xx_l2_check;
550
551 mpc85xx_set_l2_sysfs_attributes(edac_dev);
552
553 pdata->edac_idx = edac_dev_idx++;
554
555 if (edac_device_add_device(edac_dev) > 0) {
956b9ba1 556 edac_dbg(3, "failed edac_device_add_device()\n");
a9a753d5
DJ
557 goto err;
558 }
559
560 if (edac_op_state == EDAC_OPSTATE_INT) {
a26f95fe 561 pdata->irq = irq_of_parse_and_map(op->dev.of_node, 0);
a9a753d5 562 res = devm_request_irq(&op->dev, pdata->irq,
a18c3f16 563 mpc85xx_l2_isr, IRQF_SHARED,
a9a753d5
DJ
564 "[EDAC] L2 err", edac_dev);
565 if (res < 0) {
88857ebe
YS
566 pr_err("%s: Unable to request irq %d for MPC85xx L2 err\n",
567 __func__, pdata->irq);
a9a753d5
DJ
568 irq_dispose_mapping(pdata->irq);
569 res = -ENODEV;
570 goto err2;
571 }
572
88857ebe 573 pr_info(EDAC_MOD_STR " acquired irq %d for L2 Err\n", pdata->irq);
a9a753d5
DJ
574
575 edac_dev->op_state = OP_RUNNING_INTERRUPT;
576
577 out_be32(pdata->l2_vbase + MPC85XX_L2_ERRINTEN, L2_EIE_MASK);
578 }
579
580 devres_remove_group(&op->dev, mpc85xx_l2_err_probe);
581
956b9ba1 582 edac_dbg(3, "success\n");
88857ebe 583 pr_info(EDAC_MOD_STR " L2 err registered\n");
a9a753d5
DJ
584
585 return 0;
586
587err2:
588 edac_device_del_device(&op->dev);
589err:
590 devres_release_group(&op->dev, mpc85xx_l2_err_probe);
591 edac_device_free_ctl_info(edac_dev);
592 return res;
593}
594
2dc11581 595static int mpc85xx_l2_err_remove(struct platform_device *op)
a9a753d5
DJ
596{
597 struct edac_device_ctl_info *edac_dev = dev_get_drvdata(&op->dev);
598 struct mpc85xx_l2_pdata *pdata = edac_dev->pvt_info;
599
956b9ba1 600 edac_dbg(0, "\n");
a9a753d5
DJ
601
602 if (edac_op_state == EDAC_OPSTATE_INT) {
603 out_be32(pdata->l2_vbase + MPC85XX_L2_ERRINTEN, 0);
604 irq_dispose_mapping(pdata->irq);
605 }
606
607 out_be32(pdata->l2_vbase + MPC85XX_L2_ERRDIS, orig_l2_err_disable);
608 edac_device_del_device(&op->dev);
609 edac_device_free_ctl_info(edac_dev);
610 return 0;
611}
612
1afaa055 613static const struct of_device_id mpc85xx_l2_err_of_match[] = {
29d6cf26
KG
614 { .compatible = "fsl,mpc8536-l2-cache-controller", },
615 { .compatible = "fsl,mpc8540-l2-cache-controller", },
616 { .compatible = "fsl,mpc8541-l2-cache-controller", },
617 { .compatible = "fsl,mpc8544-l2-cache-controller", },
618 { .compatible = "fsl,mpc8548-l2-cache-controller", },
619 { .compatible = "fsl,mpc8555-l2-cache-controller", },
620 { .compatible = "fsl,mpc8560-l2-cache-controller", },
621 { .compatible = "fsl,mpc8568-l2-cache-controller", },
cd1542c8 622 { .compatible = "fsl,mpc8569-l2-cache-controller", },
29d6cf26 623 { .compatible = "fsl,mpc8572-l2-cache-controller", },
cd1542c8
AV
624 { .compatible = "fsl,p1020-l2-cache-controller", },
625 { .compatible = "fsl,p1021-l2-cache-controller", },
a014554e 626 { .compatible = "fsl,p2020-l2-cache-controller", },
321d17c1 627 { .compatible = "fsl,t2080-l2-cache-controller", },
a9a753d5
DJ
628 {},
629};
952e1c66 630MODULE_DEVICE_TABLE(of, mpc85xx_l2_err_of_match);
a9a753d5 631
00006124 632static struct platform_driver mpc85xx_l2_err_driver = {
a9a753d5
DJ
633 .probe = mpc85xx_l2_err_probe,
634 .remove = mpc85xx_l2_err_remove,
635 .driver = {
4018294b 636 .name = "mpc85xx_l2_err",
4018294b
GL
637 .of_match_table = mpc85xx_l2_err_of_match,
638 },
a9a753d5
DJ
639};
640
1afaa055 641static const struct of_device_id mpc85xx_mc_err_of_match[] = {
29d6cf26
KG
642 { .compatible = "fsl,mpc8536-memory-controller", },
643 { .compatible = "fsl,mpc8540-memory-controller", },
644 { .compatible = "fsl,mpc8541-memory-controller", },
645 { .compatible = "fsl,mpc8544-memory-controller", },
646 { .compatible = "fsl,mpc8548-memory-controller", },
647 { .compatible = "fsl,mpc8555-memory-controller", },
648 { .compatible = "fsl,mpc8560-memory-controller", },
649 { .compatible = "fsl,mpc8568-memory-controller", },
5528e229 650 { .compatible = "fsl,mpc8569-memory-controller", },
29d6cf26 651 { .compatible = "fsl,mpc8572-memory-controller", },
b4846251 652 { .compatible = "fsl,mpc8349-memory-controller", },
cd1542c8
AV
653 { .compatible = "fsl,p1020-memory-controller", },
654 { .compatible = "fsl,p1021-memory-controller", },
a014554e 655 { .compatible = "fsl,p2020-memory-controller", },
86f9a433 656 { .compatible = "fsl,qoriq-memory-controller", },
a9a753d5
DJ
657 {},
658};
952e1c66 659MODULE_DEVICE_TABLE(of, mpc85xx_mc_err_of_match);
a9a753d5 660
00006124 661static struct platform_driver mpc85xx_mc_err_driver = {
d43a9fb2
YS
662 .probe = fsl_mc_err_probe,
663 .remove = fsl_mc_err_remove,
a9a753d5 664 .driver = {
4018294b 665 .name = "mpc85xx_mc_err",
4018294b
GL
666 .of_match_table = mpc85xx_mc_err_of_match,
667 },
a9a753d5
DJ
668};
669
d54051f1
TR
670static struct platform_driver * const drivers[] = {
671 &mpc85xx_mc_err_driver,
672 &mpc85xx_l2_err_driver,
666db563
SW
673#ifdef CONFIG_PCI
674 &mpc85xx_pci_err_driver,
675#endif
d54051f1
TR
676};
677
a9a753d5
DJ
678static int __init mpc85xx_mc_init(void)
679{
680 int res = 0;
f2b59ac6 681 u32 __maybe_unused pvr = 0;
a9a753d5 682
88857ebe 683 pr_info("Freescale(R) MPC85xx EDAC driver, (C) 2006 Montavista Software\n");
a9a753d5
DJ
684
685 /* make sure error reporting method is sane */
686 switch (edac_op_state) {
687 case EDAC_OPSTATE_POLL:
688 case EDAC_OPSTATE_INT:
689 break;
690 default:
691 edac_op_state = EDAC_OPSTATE_INT;
692 break;
693 }
694
d54051f1 695 res = platform_register_drivers(drivers, ARRAY_SIZE(drivers));
a9a753d5 696 if (res)
88857ebe 697 pr_warn(EDAC_MOD_STR "drivers fail to register\n");
a9a753d5 698
a9a753d5
DJ
699 return 0;
700}
701
702module_init(mpc85xx_mc_init);
703
704static void __exit mpc85xx_mc_exit(void)
705{
d54051f1 706 platform_unregister_drivers(drivers, ARRAY_SIZE(drivers));
a9a753d5
DJ
707}
708
709module_exit(mpc85xx_mc_exit);
710
711MODULE_LICENSE("GPL");
712MODULE_AUTHOR("Montavista Software, Inc.");
713module_param(edac_op_state, int, 0444);
371b27f2 714MODULE_PARM_DESC(edac_op_state, "EDAC Error Reporting state: 0=Poll, 2=Interrupt");