linux/drivers/edac/mpc85xx_edac.c
<<
>>
Prefs
   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 "edac_core.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 const struct platform_device_id mpc85xx_pci_err_match[] = {
 304        {
 305                .name = "mpc85xx-pci-edac"
 306        },
 307        {}
 308};
 309
 310static struct platform_driver mpc85xx_pci_err_driver = {
 311        .probe = mpc85xx_pci_err_probe,
 312        .id_table = mpc85xx_pci_err_match,
 313        .driver = {
 314                .name = "mpc85xx_pci_err",
 315                .suppress_bind_attrs = true,
 316        },
 317};
 318#endif                          /* CONFIG_PCI */
 319
 320/**************************** L2 Err device ***************************/
 321
 322/************************ L2 SYSFS parts ***********************************/
 323
 324static ssize_t mpc85xx_l2_inject_data_hi_show(struct edac_device_ctl_info
 325                                              *edac_dev, char *data)
 326{
 327        struct mpc85xx_l2_pdata *pdata = edac_dev->pvt_info;
 328        return sprintf(data, "0x%08x",
 329                       in_be32(pdata->l2_vbase + MPC85XX_L2_ERRINJHI));
 330}
 331
 332static ssize_t mpc85xx_l2_inject_data_lo_show(struct edac_device_ctl_info
 333                                              *edac_dev, char *data)
 334{
 335        struct mpc85xx_l2_pdata *pdata = edac_dev->pvt_info;
 336        return sprintf(data, "0x%08x",
 337                       in_be32(pdata->l2_vbase + MPC85XX_L2_ERRINJLO));
 338}
 339
 340static ssize_t mpc85xx_l2_inject_ctrl_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_ERRINJCTL));
 346}
 347
 348static ssize_t mpc85xx_l2_inject_data_hi_store(struct edac_device_ctl_info
 349                                               *edac_dev, const char *data,
 350                                               size_t count)
 351{
 352        struct mpc85xx_l2_pdata *pdata = edac_dev->pvt_info;
 353        if (isdigit(*data)) {
 354                out_be32(pdata->l2_vbase + MPC85XX_L2_ERRINJHI,
 355                         simple_strtoul(data, NULL, 0));
 356                return count;
 357        }
 358        return 0;
 359}
 360
 361static ssize_t mpc85xx_l2_inject_data_lo_store(struct edac_device_ctl_info
 362                                               *edac_dev, const char *data,
 363                                               size_t count)
 364{
 365        struct mpc85xx_l2_pdata *pdata = edac_dev->pvt_info;
 366        if (isdigit(*data)) {
 367                out_be32(pdata->l2_vbase + MPC85XX_L2_ERRINJLO,
 368                         simple_strtoul(data, NULL, 0));
 369                return count;
 370        }
 371        return 0;
 372}
 373
 374static ssize_t mpc85xx_l2_inject_ctrl_store(struct edac_device_ctl_info
 375                                            *edac_dev, const char *data,
 376                                            size_t count)
 377{
 378        struct mpc85xx_l2_pdata *pdata = edac_dev->pvt_info;
 379        if (isdigit(*data)) {
 380                out_be32(pdata->l2_vbase + MPC85XX_L2_ERRINJCTL,
 381                         simple_strtoul(data, NULL, 0));
 382                return count;
 383        }
 384        return 0;
 385}
 386
 387static struct edac_dev_sysfs_attribute mpc85xx_l2_sysfs_attributes[] = {
 388        {
 389         .attr = {
 390                  .name = "inject_data_hi",
 391                  .mode = (S_IRUGO | S_IWUSR)
 392                  },
 393         .show = mpc85xx_l2_inject_data_hi_show,
 394         .store = mpc85xx_l2_inject_data_hi_store},
 395        {
 396         .attr = {
 397                  .name = "inject_data_lo",
 398                  .mode = (S_IRUGO | S_IWUSR)
 399                  },
 400         .show = mpc85xx_l2_inject_data_lo_show,
 401         .store = mpc85xx_l2_inject_data_lo_store},
 402        {
 403         .attr = {
 404                  .name = "inject_ctrl",
 405                  .mode = (S_IRUGO | S_IWUSR)
 406                  },
 407         .show = mpc85xx_l2_inject_ctrl_show,
 408         .store = mpc85xx_l2_inject_ctrl_store},
 409
 410        /* End of list */
 411        {
 412         .attr = {.name = NULL}
 413         }
 414};
 415
 416static void mpc85xx_set_l2_sysfs_attributes(struct edac_device_ctl_info
 417                                            *edac_dev)
 418{
 419        edac_dev->sysfs_attributes = mpc85xx_l2_sysfs_attributes;
 420}
 421
 422/***************************** L2 ops ***********************************/
 423
 424static void mpc85xx_l2_check(struct edac_device_ctl_info *edac_dev)
 425{
 426        struct mpc85xx_l2_pdata *pdata = edac_dev->pvt_info;
 427        u32 err_detect;
 428
 429        err_detect = in_be32(pdata->l2_vbase + MPC85XX_L2_ERRDET);
 430
 431        if (!(err_detect & L2_EDE_MASK))
 432                return;
 433
 434        pr_err("ECC Error in CPU L2 cache\n");
 435        pr_err("L2 Error Detect Register: 0x%08x\n", err_detect);
 436        pr_err("L2 Error Capture Data High Register: 0x%08x\n",
 437               in_be32(pdata->l2_vbase + MPC85XX_L2_CAPTDATAHI));
 438        pr_err("L2 Error Capture Data Lo Register: 0x%08x\n",
 439               in_be32(pdata->l2_vbase + MPC85XX_L2_CAPTDATALO));
 440        pr_err("L2 Error Syndrome Register: 0x%08x\n",
 441               in_be32(pdata->l2_vbase + MPC85XX_L2_CAPTECC));
 442        pr_err("L2 Error Attributes Capture Register: 0x%08x\n",
 443               in_be32(pdata->l2_vbase + MPC85XX_L2_ERRATTR));
 444        pr_err("L2 Error Address Capture Register: 0x%08x\n",
 445               in_be32(pdata->l2_vbase + MPC85XX_L2_ERRADDR));
 446
 447        /* clear error detect register */
 448        out_be32(pdata->l2_vbase + MPC85XX_L2_ERRDET, err_detect);
 449
 450        if (err_detect & L2_EDE_CE_MASK)
 451                edac_device_handle_ce(edac_dev, 0, 0, edac_dev->ctl_name);
 452
 453        if (err_detect & L2_EDE_UE_MASK)
 454                edac_device_handle_ue(edac_dev, 0, 0, edac_dev->ctl_name);
 455}
 456
 457static irqreturn_t mpc85xx_l2_isr(int irq, void *dev_id)
 458{
 459        struct edac_device_ctl_info *edac_dev = dev_id;
 460        struct mpc85xx_l2_pdata *pdata = edac_dev->pvt_info;
 461        u32 err_detect;
 462
 463        err_detect = in_be32(pdata->l2_vbase + MPC85XX_L2_ERRDET);
 464
 465        if (!(err_detect & L2_EDE_MASK))
 466                return IRQ_NONE;
 467
 468        mpc85xx_l2_check(edac_dev);
 469
 470        return IRQ_HANDLED;
 471}
 472
 473static int mpc85xx_l2_err_probe(struct platform_device *op)
 474{
 475        struct edac_device_ctl_info *edac_dev;
 476        struct mpc85xx_l2_pdata *pdata;
 477        struct resource r;
 478        int res;
 479
 480        if (!devres_open_group(&op->dev, mpc85xx_l2_err_probe, GFP_KERNEL))
 481                return -ENOMEM;
 482
 483        edac_dev = edac_device_alloc_ctl_info(sizeof(*pdata),
 484                                              "cpu", 1, "L", 1, 2, NULL, 0,
 485                                              edac_dev_idx);
 486        if (!edac_dev) {
 487                devres_release_group(&op->dev, mpc85xx_l2_err_probe);
 488                return -ENOMEM;
 489        }
 490
 491        pdata = edac_dev->pvt_info;
 492        pdata->name = "mpc85xx_l2_err";
 493        edac_dev->dev = &op->dev;
 494        dev_set_drvdata(edac_dev->dev, edac_dev);
 495        edac_dev->ctl_name = pdata->name;
 496        edac_dev->dev_name = pdata->name;
 497
 498        res = of_address_to_resource(op->dev.of_node, 0, &r);
 499        if (res) {
 500                pr_err("%s: Unable to get resource for L2 err regs\n", __func__);
 501                goto err;
 502        }
 503
 504        /* we only need the error registers */
 505        r.start += 0xe00;
 506
 507        if (!devm_request_mem_region(&op->dev, r.start, resource_size(&r),
 508                                     pdata->name)) {
 509                pr_err("%s: Error while requesting mem region\n", __func__);
 510                res = -EBUSY;
 511                goto err;
 512        }
 513
 514        pdata->l2_vbase = devm_ioremap(&op->dev, r.start, resource_size(&r));
 515        if (!pdata->l2_vbase) {
 516                pr_err("%s: Unable to setup L2 err regs\n", __func__);
 517                res = -ENOMEM;
 518                goto err;
 519        }
 520
 521        out_be32(pdata->l2_vbase + MPC85XX_L2_ERRDET, ~0);
 522
 523        orig_l2_err_disable = in_be32(pdata->l2_vbase + MPC85XX_L2_ERRDIS);
 524
 525        /* clear the err_dis */
 526        out_be32(pdata->l2_vbase + MPC85XX_L2_ERRDIS, 0);
 527
 528        edac_dev->mod_name = EDAC_MOD_STR;
 529
 530        if (edac_op_state == EDAC_OPSTATE_POLL)
 531                edac_dev->edac_check = mpc85xx_l2_check;
 532
 533        mpc85xx_set_l2_sysfs_attributes(edac_dev);
 534
 535        pdata->edac_idx = edac_dev_idx++;
 536
 537        if (edac_device_add_device(edac_dev) > 0) {
 538                edac_dbg(3, "failed edac_device_add_device()\n");
 539                goto err;
 540        }
 541
 542        if (edac_op_state == EDAC_OPSTATE_INT) {
 543                pdata->irq = irq_of_parse_and_map(op->dev.of_node, 0);
 544                res = devm_request_irq(&op->dev, pdata->irq,
 545                                       mpc85xx_l2_isr, IRQF_SHARED,
 546                                       "[EDAC] L2 err", edac_dev);
 547                if (res < 0) {
 548                        pr_err("%s: Unable to request irq %d for MPC85xx L2 err\n",
 549                                __func__, pdata->irq);
 550                        irq_dispose_mapping(pdata->irq);
 551                        res = -ENODEV;
 552                        goto err2;
 553                }
 554
 555                pr_info(EDAC_MOD_STR " acquired irq %d for L2 Err\n", pdata->irq);
 556
 557                edac_dev->op_state = OP_RUNNING_INTERRUPT;
 558
 559                out_be32(pdata->l2_vbase + MPC85XX_L2_ERRINTEN, L2_EIE_MASK);
 560        }
 561
 562        devres_remove_group(&op->dev, mpc85xx_l2_err_probe);
 563
 564        edac_dbg(3, "success\n");
 565        pr_info(EDAC_MOD_STR " L2 err registered\n");
 566
 567        return 0;
 568
 569err2:
 570        edac_device_del_device(&op->dev);
 571err:
 572        devres_release_group(&op->dev, mpc85xx_l2_err_probe);
 573        edac_device_free_ctl_info(edac_dev);
 574        return res;
 575}
 576
 577static int mpc85xx_l2_err_remove(struct platform_device *op)
 578{
 579        struct edac_device_ctl_info *edac_dev = dev_get_drvdata(&op->dev);
 580        struct mpc85xx_l2_pdata *pdata = edac_dev->pvt_info;
 581
 582        edac_dbg(0, "\n");
 583
 584        if (edac_op_state == EDAC_OPSTATE_INT) {
 585                out_be32(pdata->l2_vbase + MPC85XX_L2_ERRINTEN, 0);
 586                irq_dispose_mapping(pdata->irq);
 587        }
 588
 589        out_be32(pdata->l2_vbase + MPC85XX_L2_ERRDIS, orig_l2_err_disable);
 590        edac_device_del_device(&op->dev);
 591        edac_device_free_ctl_info(edac_dev);
 592        return 0;
 593}
 594
 595static const struct of_device_id mpc85xx_l2_err_of_match[] = {
 596/* deprecate the fsl,85.. forms in the future, 2.6.30? */
 597        { .compatible = "fsl,8540-l2-cache-controller", },
 598        { .compatible = "fsl,8541-l2-cache-controller", },
 599        { .compatible = "fsl,8544-l2-cache-controller", },
 600        { .compatible = "fsl,8548-l2-cache-controller", },
 601        { .compatible = "fsl,8555-l2-cache-controller", },
 602        { .compatible = "fsl,8568-l2-cache-controller", },
 603        { .compatible = "fsl,mpc8536-l2-cache-controller", },
 604        { .compatible = "fsl,mpc8540-l2-cache-controller", },
 605        { .compatible = "fsl,mpc8541-l2-cache-controller", },
 606        { .compatible = "fsl,mpc8544-l2-cache-controller", },
 607        { .compatible = "fsl,mpc8548-l2-cache-controller", },
 608        { .compatible = "fsl,mpc8555-l2-cache-controller", },
 609        { .compatible = "fsl,mpc8560-l2-cache-controller", },
 610        { .compatible = "fsl,mpc8568-l2-cache-controller", },
 611        { .compatible = "fsl,mpc8569-l2-cache-controller", },
 612        { .compatible = "fsl,mpc8572-l2-cache-controller", },
 613        { .compatible = "fsl,p1020-l2-cache-controller", },
 614        { .compatible = "fsl,p1021-l2-cache-controller", },
 615        { .compatible = "fsl,p2020-l2-cache-controller", },
 616        {},
 617};
 618MODULE_DEVICE_TABLE(of, mpc85xx_l2_err_of_match);
 619
 620static struct platform_driver mpc85xx_l2_err_driver = {
 621        .probe = mpc85xx_l2_err_probe,
 622        .remove = mpc85xx_l2_err_remove,
 623        .driver = {
 624                .name = "mpc85xx_l2_err",
 625                .of_match_table = mpc85xx_l2_err_of_match,
 626        },
 627};
 628
 629static const struct of_device_id mpc85xx_mc_err_of_match[] = {
 630/* deprecate the fsl,85.. forms in the future, 2.6.30? */
 631        { .compatible = "fsl,8540-memory-controller", },
 632        { .compatible = "fsl,8541-memory-controller", },
 633        { .compatible = "fsl,8544-memory-controller", },
 634        { .compatible = "fsl,8548-memory-controller", },
 635        { .compatible = "fsl,8555-memory-controller", },
 636        { .compatible = "fsl,8568-memory-controller", },
 637        { .compatible = "fsl,mpc8536-memory-controller", },
 638        { .compatible = "fsl,mpc8540-memory-controller", },
 639        { .compatible = "fsl,mpc8541-memory-controller", },
 640        { .compatible = "fsl,mpc8544-memory-controller", },
 641        { .compatible = "fsl,mpc8548-memory-controller", },
 642        { .compatible = "fsl,mpc8555-memory-controller", },
 643        { .compatible = "fsl,mpc8560-memory-controller", },
 644        { .compatible = "fsl,mpc8568-memory-controller", },
 645        { .compatible = "fsl,mpc8569-memory-controller", },
 646        { .compatible = "fsl,mpc8572-memory-controller", },
 647        { .compatible = "fsl,mpc8349-memory-controller", },
 648        { .compatible = "fsl,p1020-memory-controller", },
 649        { .compatible = "fsl,p1021-memory-controller", },
 650        { .compatible = "fsl,p2020-memory-controller", },
 651        { .compatible = "fsl,qoriq-memory-controller", },
 652        {},
 653};
 654MODULE_DEVICE_TABLE(of, mpc85xx_mc_err_of_match);
 655
 656static struct platform_driver mpc85xx_mc_err_driver = {
 657        .probe = fsl_mc_err_probe,
 658        .remove = fsl_mc_err_remove,
 659        .driver = {
 660                .name = "mpc85xx_mc_err",
 661                .of_match_table = mpc85xx_mc_err_of_match,
 662        },
 663};
 664
 665static struct platform_driver * const drivers[] = {
 666        &mpc85xx_mc_err_driver,
 667        &mpc85xx_l2_err_driver,
 668#ifdef CONFIG_PCI
 669        &mpc85xx_pci_err_driver,
 670#endif
 671};
 672
 673static int __init mpc85xx_mc_init(void)
 674{
 675        int res = 0;
 676        u32 __maybe_unused pvr = 0;
 677
 678        pr_info("Freescale(R) MPC85xx EDAC driver, (C) 2006 Montavista Software\n");
 679
 680        /* make sure error reporting method is sane */
 681        switch (edac_op_state) {
 682        case EDAC_OPSTATE_POLL:
 683        case EDAC_OPSTATE_INT:
 684                break;
 685        default:
 686                edac_op_state = EDAC_OPSTATE_INT;
 687                break;
 688        }
 689
 690        res = platform_register_drivers(drivers, ARRAY_SIZE(drivers));
 691        if (res)
 692                pr_warn(EDAC_MOD_STR "drivers fail to register\n");
 693
 694        return 0;
 695}
 696
 697module_init(mpc85xx_mc_init);
 698
 699static void __exit mpc85xx_mc_exit(void)
 700{
 701        platform_unregister_drivers(drivers, ARRAY_SIZE(drivers));
 702}
 703
 704module_exit(mpc85xx_mc_exit);
 705
 706MODULE_LICENSE("GPL");
 707MODULE_AUTHOR("Montavista Software, Inc.");
 708module_param(edac_op_state, int, 0444);
 709MODULE_PARM_DESC(edac_op_state,
 710                 "EDAC Error Reporting state: 0=Poll, 2=Interrupt");
 711