Linux Audio

Check our new training course

Linux debugging, profiling, tracing and performance analysis training

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