cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

mpc85xx_edac.c (19809B)


      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	{ .compatible = "fsl,mpc8536-l2-cache-controller", },
    613	{ .compatible = "fsl,mpc8540-l2-cache-controller", },
    614	{ .compatible = "fsl,mpc8541-l2-cache-controller", },
    615	{ .compatible = "fsl,mpc8544-l2-cache-controller", },
    616	{ .compatible = "fsl,mpc8548-l2-cache-controller", },
    617	{ .compatible = "fsl,mpc8555-l2-cache-controller", },
    618	{ .compatible = "fsl,mpc8560-l2-cache-controller", },
    619	{ .compatible = "fsl,mpc8568-l2-cache-controller", },
    620	{ .compatible = "fsl,mpc8569-l2-cache-controller", },
    621	{ .compatible = "fsl,mpc8572-l2-cache-controller", },
    622	{ .compatible = "fsl,p1020-l2-cache-controller", },
    623	{ .compatible = "fsl,p1021-l2-cache-controller", },
    624	{ .compatible = "fsl,p2020-l2-cache-controller", },
    625	{ .compatible = "fsl,t2080-l2-cache-controller", },
    626	{},
    627};
    628MODULE_DEVICE_TABLE(of, mpc85xx_l2_err_of_match);
    629
    630static struct platform_driver mpc85xx_l2_err_driver = {
    631	.probe = mpc85xx_l2_err_probe,
    632	.remove = mpc85xx_l2_err_remove,
    633	.driver = {
    634		.name = "mpc85xx_l2_err",
    635		.of_match_table = mpc85xx_l2_err_of_match,
    636	},
    637};
    638
    639static const struct of_device_id mpc85xx_mc_err_of_match[] = {
    640	{ .compatible = "fsl,mpc8536-memory-controller", },
    641	{ .compatible = "fsl,mpc8540-memory-controller", },
    642	{ .compatible = "fsl,mpc8541-memory-controller", },
    643	{ .compatible = "fsl,mpc8544-memory-controller", },
    644	{ .compatible = "fsl,mpc8548-memory-controller", },
    645	{ .compatible = "fsl,mpc8555-memory-controller", },
    646	{ .compatible = "fsl,mpc8560-memory-controller", },
    647	{ .compatible = "fsl,mpc8568-memory-controller", },
    648	{ .compatible = "fsl,mpc8569-memory-controller", },
    649	{ .compatible = "fsl,mpc8572-memory-controller", },
    650	{ .compatible = "fsl,mpc8349-memory-controller", },
    651	{ .compatible = "fsl,p1020-memory-controller", },
    652	{ .compatible = "fsl,p1021-memory-controller", },
    653	{ .compatible = "fsl,p2020-memory-controller", },
    654	{ .compatible = "fsl,qoriq-memory-controller", },
    655	{},
    656};
    657MODULE_DEVICE_TABLE(of, mpc85xx_mc_err_of_match);
    658
    659static struct platform_driver mpc85xx_mc_err_driver = {
    660	.probe = fsl_mc_err_probe,
    661	.remove = fsl_mc_err_remove,
    662	.driver = {
    663		.name = "mpc85xx_mc_err",
    664		.of_match_table = mpc85xx_mc_err_of_match,
    665	},
    666};
    667
    668static struct platform_driver * const drivers[] = {
    669	&mpc85xx_mc_err_driver,
    670	&mpc85xx_l2_err_driver,
    671#ifdef CONFIG_PCI
    672	&mpc85xx_pci_err_driver,
    673#endif
    674};
    675
    676static int __init mpc85xx_mc_init(void)
    677{
    678	int res = 0;
    679	u32 __maybe_unused pvr = 0;
    680
    681	pr_info("Freescale(R) MPC85xx EDAC driver, (C) 2006 Montavista Software\n");
    682
    683	/* make sure error reporting method is sane */
    684	switch (edac_op_state) {
    685	case EDAC_OPSTATE_POLL:
    686	case EDAC_OPSTATE_INT:
    687		break;
    688	default:
    689		edac_op_state = EDAC_OPSTATE_INT;
    690		break;
    691	}
    692
    693	res = platform_register_drivers(drivers, ARRAY_SIZE(drivers));
    694	if (res)
    695		pr_warn(EDAC_MOD_STR "drivers fail to register\n");
    696
    697	return 0;
    698}
    699
    700module_init(mpc85xx_mc_init);
    701
    702static void __exit mpc85xx_mc_exit(void)
    703{
    704	platform_unregister_drivers(drivers, ARRAY_SIZE(drivers));
    705}
    706
    707module_exit(mpc85xx_mc_exit);
    708
    709MODULE_LICENSE("GPL");
    710MODULE_AUTHOR("Montavista Software, Inc.");
    711module_param(edac_op_state, int, 0444);
    712MODULE_PARM_DESC(edac_op_state,
    713		 "EDAC Error Reporting state: 0=Poll, 2=Interrupt");