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