linux/drivers/edac/synopsys_edac.c
<<
>>
Prefs
   1/*
   2 * Synopsys DDR ECC Driver
   3 * This driver is based on ppc4xx_edac.c drivers
   4 *
   5 * Copyright (C) 2012 - 2014 Xilinx, Inc.
   6 *
   7 * This program is free software: you can redistribute it and/or modify
   8 * it under the terms of the GNU General Public License as published by
   9 * the Free Software Foundation, either version 2 of the License, or
  10 * (at your option) any later version.
  11 *
  12 * This program is distributed in the hope that it will be useful,
  13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15 * GNU General Public License for more details.
  16 *
  17 * This file is subject to the terms and conditions of the GNU General Public
  18 * License.  See the file "COPYING" in the main directory of this archive
  19 * for more details
  20 */
  21
  22#include <linux/edac.h>
  23#include <linux/module.h>
  24#include <linux/platform_device.h>
  25#include <linux/interrupt.h>
  26#include <linux/of.h>
  27
  28#include "edac_core.h"
  29
  30/* Number of cs_rows needed per memory controller */
  31#define SYNPS_EDAC_NR_CSROWS    1
  32
  33/* Number of channels per memory controller */
  34#define SYNPS_EDAC_NR_CHANS     1
  35
  36/* Granularity of reported error in bytes */
  37#define SYNPS_EDAC_ERR_GRAIN    1
  38
  39#define SYNPS_EDAC_MSG_SIZE     256
  40
  41#define SYNPS_EDAC_MOD_STRING   "synps_edac"
  42#define SYNPS_EDAC_MOD_VER      "1"
  43
  44/* Synopsys DDR memory controller registers that are relevant to ECC */
  45#define CTRL_OFST               0x0
  46#define T_ZQ_OFST               0xA4
  47
  48/* ECC control register */
  49#define ECC_CTRL_OFST           0xC4
  50/* ECC log register */
  51#define CE_LOG_OFST             0xC8
  52/* ECC address register */
  53#define CE_ADDR_OFST            0xCC
  54/* ECC data[31:0] register */
  55#define CE_DATA_31_0_OFST       0xD0
  56
  57/* Uncorrectable error info registers */
  58#define UE_LOG_OFST             0xDC
  59#define UE_ADDR_OFST            0xE0
  60#define UE_DATA_31_0_OFST       0xE4
  61
  62#define STAT_OFST               0xF0
  63#define SCRUB_OFST              0xF4
  64
  65/* Control register bit field definitions */
  66#define CTRL_BW_MASK            0xC
  67#define CTRL_BW_SHIFT           2
  68
  69#define DDRCTL_WDTH_16          1
  70#define DDRCTL_WDTH_32          0
  71
  72/* ZQ register bit field definitions */
  73#define T_ZQ_DDRMODE_MASK       0x2
  74
  75/* ECC control register bit field definitions */
  76#define ECC_CTRL_CLR_CE_ERR     0x2
  77#define ECC_CTRL_CLR_UE_ERR     0x1
  78
  79/* ECC correctable/uncorrectable error log register definitions */
  80#define LOG_VALID               0x1
  81#define CE_LOG_BITPOS_MASK      0xFE
  82#define CE_LOG_BITPOS_SHIFT     1
  83
  84/* ECC correctable/uncorrectable error address register definitions */
  85#define ADDR_COL_MASK           0xFFF
  86#define ADDR_ROW_MASK           0xFFFF000
  87#define ADDR_ROW_SHIFT          12
  88#define ADDR_BANK_MASK          0x70000000
  89#define ADDR_BANK_SHIFT         28
  90
  91/* ECC statistic register definitions */
  92#define STAT_UECNT_MASK         0xFF
  93#define STAT_CECNT_MASK         0xFF00
  94#define STAT_CECNT_SHIFT        8
  95
  96/* ECC scrub register definitions */
  97#define SCRUB_MODE_MASK         0x7
  98#define SCRUB_MODE_SECDED       0x4
  99
 100/* DDR ECC Quirks */
 101#define DDR_ECC_INTR_SUPPORT    BIT(0)
 102#define DDR_ECC_DATA_POISON_SUPPORT BIT(1)
 103
 104/* ZynqMP Enhanced DDR memory controller registers that are relevant to ECC */
 105/* ECC Configuration Registers */
 106#define ECC_CFG0_OFST   0x70
 107#define ECC_CFG1_OFST   0x74
 108
 109/* ECC Status Register */
 110#define ECC_STAT_OFST   0x78
 111
 112/* ECC Clear Register */
 113#define ECC_CLR_OFST    0x7C
 114
 115/* ECC Error count Register */
 116#define ECC_ERRCNT_OFST 0x80
 117
 118/* ECC Corrected Error Address Register */
 119#define ECC_CEADDR0_OFST        0x84
 120#define ECC_CEADDR1_OFST        0x88
 121
 122/* ECC Syndrome Registers */
 123#define ECC_CSYND0_OFST 0x8C
 124#define ECC_CSYND1_OFST 0x90
 125#define ECC_CSYND2_OFST 0x94
 126
 127/* ECC Bit Mask0 Address Register */
 128#define ECC_BITMASK0_OFST       0x98
 129#define ECC_BITMASK1_OFST       0x9C
 130#define ECC_BITMASK2_OFST       0xA0
 131
 132/* ECC UnCorrected Error Address Register */
 133#define ECC_UEADDR0_OFST        0xA4
 134#define ECC_UEADDR1_OFST        0xA8
 135
 136/* ECC Syndrome Registers */
 137#define ECC_UESYND0_OFST        0xAC
 138#define ECC_UESYND1_OFST        0xB0
 139#define ECC_UESYND2_OFST        0xB4
 140
 141/* ECC Poison Address Reg */
 142#define ECC_POISON0_OFST        0xB8
 143#define ECC_POISON1_OFST        0xBC
 144
 145/* Control regsiter bitfield definitions */
 146#define ECC_CTRL_BUSWIDTH_MASK  0x3000
 147#define ECC_CTRL_BUSWIDTH_SHIFT 12
 148#define ECC_CTRL_CLR_CE_ERRCNT  BIT(2)
 149#define ECC_CTRL_CLR_UE_ERRCNT  BIT(3)
 150
 151/* DDR Control Register width definitions  */
 152#define DDRCTL_EWDTH_16         2
 153#define DDRCTL_EWDTH_32         1
 154#define DDRCTL_EWDTH_64         0
 155
 156/* ECC status regsiter definitions */
 157#define ECC_STAT_UECNT_MASK     0xF0000
 158#define ECC_STAT_UECNT_SHIFT    16
 159#define ECC_STAT_CECNT_MASK     0xF00
 160#define ECC_STAT_CECNT_SHIFT    8
 161#define ECC_STAT_BITNUM_MASK    0x7F
 162
 163/* DDR QOS Interrupt regsiter definitions */
 164#define DDR_QOS_IRQ_STAT_OFST   0x20200
 165#define DDR_QOSUE_MASK          0x4
 166#define DDR_QOSCE_MASK          0x2
 167#define ECC_CE_UE_INTR_MASK     0x6
 168#define DDR_QOS_IRQ_EN_OFST     0x20208
 169#define DDR_QOS_IRQ_DB_OFST     0x2020C
 170
 171/* ECC Corrected Error Register Mask and Shifts*/
 172#define ECC_CEADDR0_RW_MASK     0x3FFFF
 173#define ECC_CEADDR0_RNK_MASK    BIT(24)
 174#define ECC_CEADDR1_BNKGRP_MASK 0x3000000
 175#define ECC_CEADDR1_BNKNR_MASK  0x70000
 176#define ECC_CEADDR1_BLKNR_MASK  0xFFF
 177#define ECC_CEADDR1_BNKGRP_SHIFT        24
 178#define ECC_CEADDR1_BNKNR_SHIFT 16
 179
 180/* ECC Poison register shifts */
 181#define ECC_POISON0_RANK_SHIFT 24
 182#define ECC_POISON1_BANKGRP_SHIFT 28
 183#define ECC_POISON1_BANKNR_SHIFT 24
 184
 185/* DDR Memory type defines */
 186#define MEM_TYPE_DDR3 0x1
 187#define MEM_TYPE_LPDDR3 0x1
 188#define MEM_TYPE_DDR2 0x4
 189#define MEM_TYPE_DDR4 0x10
 190#define MEM_TYPE_LPDDR4 0x10
 191
 192/* DDRC Software control register */
 193#define DDRC_SWCTL 0x320
 194
 195/* DDRC ECC CE & UE poison mask */
 196#define ECC_CEPOISON_MASK 0x3
 197#define ECC_UEPOISON_MASK 0x1
 198
 199/* DDRC Device config masks */
 200#define DDRC_MSTR_DEV_CONFIG_MASK 0xC0000000
 201#define DDRC_MSTR_DEV_CONFIG_SHIFT      30
 202#define DDRC_MSTR_DEV_CONFIG_X4_MASK    0
 203#define DDRC_MSTR_DEV_CONFIG_X8_MASK    1
 204#define DDRC_MSTR_DEV_CONFIG_X16_MASK   0x10
 205#define DDRC_MSTR_DEV_CONFIG_X32_MASK   0X11
 206
 207/* DDR4 and DDR3 device Row,Column,Bank Mapping */
 208#define DDR4_COL_SHIFT          3
 209#define DDR4_BANKGRP_SHIFT      13
 210#define DDR4_BANK_SHIFT 15
 211#define DDR4_ROW_SHIFT          17
 212#define DDR4_COL_MASK           0x3FF
 213#define DDR4_BANKGRP_MASK       0x3
 214#define DDR4_BANK_MASK          0x3
 215#define DDR4_ROW_MASK           0x7FFF
 216
 217#define DDR3_COL_SHIFT  3
 218#define DDR3_BANK_SHIFT 13
 219#define DDR3_ROW_SHIFT  16
 220#define DDR3_COL_MASK   0x3FF
 221#define DDR3_BANK_MASK  0x7
 222#define DDR3_ROW_MASK   0x3FFF
 223
 224/**
 225 * struct ecc_error_info - ECC error log information
 226 * @row:        Row number
 227 * @col:        Column number
 228 * @bank:       Bank number
 229 * @bitpos:     Bit position
 230 * @data:       Data causing the error
 231 * @bankgrpnr:  Bank group number
 232 * @blknr:      Block number
 233 */
 234struct ecc_error_info {
 235        u32 row;
 236        u32 col;
 237        u32 bank;
 238        u32 bitpos;
 239        u32 data;
 240        u32 bankgrpnr;
 241        u32 blknr;
 242};
 243
 244/**
 245 * struct synps_ecc_status - ECC status information to report
 246 * @ce_cnt:     Correctable error count
 247 * @ue_cnt:     Uncorrectable error count
 248 * @ceinfo:     Correctable error log information
 249 * @ueinfo:     Uncorrectable error log information
 250 */
 251struct synps_ecc_status {
 252        u32 ce_cnt;
 253        u32 ue_cnt;
 254        struct ecc_error_info ceinfo;
 255        struct ecc_error_info ueinfo;
 256};
 257
 258/**
 259 * struct synps_edac_priv - DDR memory controller private instance data
 260 * @baseaddr:   Base address of the DDR controller
 261 * @message:    Buffer for framing the event specific info
 262 * @stat:       ECC status information
 263 * @p_data:     Pointer to platform data
 264 * @ce_cnt:     Correctable Error count
 265 * @ue_cnt:     Uncorrectable Error count
 266 * @poison_addr:Data poison address
 267 */
 268struct synps_edac_priv {
 269        void __iomem *baseaddr;
 270        char message[SYNPS_EDAC_MSG_SIZE];
 271        struct synps_ecc_status stat;
 272        const struct synps_platform_data *p_data;
 273        u32 ce_cnt;
 274        u32 ue_cnt;
 275        ulong poison_addr;
 276};
 277
 278/**
 279 * struct synps_platform_data -  synps platform data structure
 280 * @synps_edac_geterror_info:   function pointer to synps edac error info
 281 * @synps_edac_get_mtype:       function pointer to synps edac mtype
 282 * @synps_edac_get_dtype:       function pointer to synps edac dtype
 283 * @synps_edac_get_eccstate:    function pointer to synps edac eccstate
 284 * @quirks:                     to differentiate IPs
 285 */
 286struct synps_platform_data {
 287        int (*synps_edac_geterror_info)(void __iomem *base,
 288                                         struct synps_ecc_status *p);
 289        enum mem_type (*synps_edac_get_mtype)(const void __iomem *base);
 290        enum dev_type (*synps_edac_get_dtype)(const void __iomem *base);
 291        bool (*synps_edac_get_eccstate)(void __iomem *base);
 292        int quirks;
 293};
 294
 295/**
 296 * synps_edac_geterror_info - Get the current ecc error info
 297 * @base:       Pointer to the base address of the ddr memory controller
 298 * @p:          Pointer to the synopsys ecc status structure
 299 *
 300 * Determines there is any ecc error or not
 301 *
 302 * Return: 1 if there is no error otherwise returns 0
 303 */
 304static int synps_edac_geterror_info(void __iomem *base,
 305                                    struct synps_ecc_status *p)
 306{
 307        u32 regval, clearval = 0;
 308
 309        regval = readl(base + STAT_OFST);
 310        if (!regval)
 311                return 1;
 312
 313        p->ce_cnt = (regval & STAT_CECNT_MASK) >> STAT_CECNT_SHIFT;
 314        p->ue_cnt = regval & STAT_UECNT_MASK;
 315
 316        regval = readl(base + CE_LOG_OFST);
 317        if (!(p->ce_cnt && (regval & LOG_VALID)))
 318                goto ue_err;
 319
 320        p->ceinfo.bitpos = (regval & CE_LOG_BITPOS_MASK) >> CE_LOG_BITPOS_SHIFT;
 321        regval = readl(base + CE_ADDR_OFST);
 322        p->ceinfo.row = (regval & ADDR_ROW_MASK) >> ADDR_ROW_SHIFT;
 323        p->ceinfo.col = regval & ADDR_COL_MASK;
 324        p->ceinfo.bank = (regval & ADDR_BANK_MASK) >> ADDR_BANK_SHIFT;
 325        p->ceinfo.data = readl(base + CE_DATA_31_0_OFST);
 326        edac_dbg(3, "ce bit position: %d data: %d\n", p->ceinfo.bitpos,
 327                 p->ceinfo.data);
 328        clearval = ECC_CTRL_CLR_CE_ERR;
 329
 330ue_err:
 331        regval = readl(base + UE_LOG_OFST);
 332        if (!(p->ue_cnt && (regval & LOG_VALID)))
 333                goto out;
 334
 335        regval = readl(base + UE_ADDR_OFST);
 336        p->ueinfo.row = (regval & ADDR_ROW_MASK) >> ADDR_ROW_SHIFT;
 337        p->ueinfo.col = regval & ADDR_COL_MASK;
 338        p->ueinfo.bank = (regval & ADDR_BANK_MASK) >> ADDR_BANK_SHIFT;
 339        p->ueinfo.data = readl(base + UE_DATA_31_0_OFST);
 340        clearval |= ECC_CTRL_CLR_UE_ERR;
 341
 342out:
 343        writel(clearval, base + ECC_CTRL_OFST);
 344        writel(0x0, base + ECC_CTRL_OFST);
 345
 346        return 0;
 347}
 348
 349/**
 350 * synps_enh_edac_geterror_info - Get the current ecc error info
 351 * @base:       Pointer to the base address of the ddr memory controller
 352 * @p:          Pointer to the synopsys ecc status structure
 353 *
 354 * Determines there is any ecc error or not
 355 *
 356 * Return: one if there is no error otherwise returns zero
 357 */
 358static int synps_enh_edac_geterror_info(void __iomem *base,
 359                                        struct synps_ecc_status *p)
 360{
 361        u32 regval, clearval = 0;
 362
 363        regval = readl(base + ECC_STAT_OFST);
 364        if (!regval)
 365                return 1;
 366
 367        p->ce_cnt = (regval & ECC_STAT_CECNT_MASK) >> ECC_STAT_CECNT_SHIFT;
 368        p->ue_cnt = (regval & ECC_STAT_UECNT_MASK) >> ECC_STAT_UECNT_SHIFT;
 369        p->ceinfo.bitpos = (regval & ECC_STAT_BITNUM_MASK);
 370
 371        regval = readl(base + ECC_CEADDR0_OFST);
 372        if (!(p->ce_cnt))
 373                goto ue_err;
 374
 375        p->ceinfo.row = (regval & ECC_CEADDR0_RW_MASK);
 376        regval = readl(base + ECC_CEADDR1_OFST);
 377        p->ceinfo.bank = (regval & ECC_CEADDR1_BNKNR_MASK) >>
 378                                        ECC_CEADDR1_BNKNR_SHIFT;
 379        p->ceinfo.bankgrpnr = (regval & ECC_CEADDR1_BNKGRP_MASK) >>
 380                                        ECC_CEADDR1_BNKGRP_SHIFT;
 381        p->ceinfo.blknr = (regval & ECC_CEADDR1_BLKNR_MASK);
 382        p->ceinfo.data = readl(base + ECC_CSYND0_OFST);
 383        edac_dbg(3, "ce bit position: %d data: %d\n", p->ceinfo.bitpos,
 384                 p->ceinfo.data);
 385
 386ue_err:
 387        regval = readl(base + ECC_UEADDR0_OFST);
 388        if (!(p->ue_cnt))
 389                goto out;
 390
 391        p->ueinfo.row = (regval & ECC_CEADDR0_RW_MASK);
 392        regval = readl(base + ECC_UEADDR1_OFST);
 393        p->ueinfo.bankgrpnr = (regval & ECC_CEADDR1_BNKGRP_MASK) >>
 394                                        ECC_CEADDR1_BNKGRP_SHIFT;
 395        p->ueinfo.bank = (regval & ECC_CEADDR1_BNKNR_MASK) >>
 396                                        ECC_CEADDR1_BNKNR_SHIFT;
 397        p->ueinfo.blknr = (regval & ECC_CEADDR1_BLKNR_MASK);
 398        p->ueinfo.data = readl(base + ECC_UESYND0_OFST);
 399out:
 400        clearval = ECC_CTRL_CLR_CE_ERR | ECC_CTRL_CLR_CE_ERRCNT;
 401        clearval |= ECC_CTRL_CLR_UE_ERR | ECC_CTRL_CLR_UE_ERRCNT;
 402        writel(clearval, base + ECC_CLR_OFST);
 403        writel(0x0, base + ECC_CLR_OFST);
 404
 405        return 0;
 406}
 407
 408/**
 409 * synps_edac_handle_error - Handle controller error types CE and UE
 410 * @mci:        Pointer to the edac memory controller instance
 411 * @p:          Pointer to the synopsys ecc status structure
 412 *
 413 * Handles the controller ECC correctable and un correctable error.
 414 */
 415static void synps_edac_handle_error(struct mem_ctl_info *mci,
 416                                    struct synps_ecc_status *p)
 417{
 418        struct synps_edac_priv *priv = mci->pvt_info;
 419        struct ecc_error_info *pinf;
 420
 421        if (p->ce_cnt) {
 422                pinf = &p->ceinfo;
 423                if (priv->p_data->quirks == 0)
 424                        snprintf(priv->message, SYNPS_EDAC_MSG_SIZE,
 425                                 "DDR ECC error type :%s Row %d Bank %d Col %d ",
 426                                 "CE", pinf->row, pinf->bank, pinf->col);
 427                else
 428                        snprintf(priv->message, SYNPS_EDAC_MSG_SIZE,
 429                                 "DDR ECC error type :%s Row %d Bank %d Col %d "
 430                                 "BankGroup Number %d Block Number %d",
 431                                 "CE", pinf->row, pinf->bank, pinf->col,
 432                                 pinf->bankgrpnr, pinf->blknr);
 433
 434                edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci,
 435                                     p->ce_cnt, 0, 0, 0, 0, 0, -1,
 436                                     priv->message, "");
 437        }
 438
 439        if (p->ue_cnt) {
 440                pinf = &p->ueinfo;
 441                if (priv->p_data->quirks == 0)
 442                        snprintf(priv->message, SYNPS_EDAC_MSG_SIZE,
 443                                 "DDR ECC error type :%s Row %d Bank %d Col %d ",
 444                                "UE", pinf->row, pinf->bank, pinf->col);
 445                else
 446                        snprintf(priv->message, SYNPS_EDAC_MSG_SIZE,
 447                                 "DDR ECC error type :%s Row %d Bank %d Col %d "
 448                                 "BankGroup Number %d Block Number %d",
 449                                 "UE", pinf->row, pinf->bank, pinf->col,
 450                                 pinf->bankgrpnr, pinf->blknr);
 451                edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci,
 452                                     p->ue_cnt, 0, 0, 0, 0, 0, -1,
 453                                     priv->message, "");
 454        }
 455
 456        memset(p, 0, sizeof(*p));
 457}
 458
 459/**
 460 * synps_edac_intr_handler - synps edac isr
 461 * @irq:        irq number
 462 * @dev_id:     device id poniter
 463 *
 464 * This is the Isr routine called by edac core interrupt thread.
 465 * Used to check and post ECC errors.
 466 *
 467 * Return: IRQ_NONE, if interrupt not set or IRQ_HANDLED otherwise
 468 */
 469static irqreturn_t synps_edac_intr_handler(int irq, void *dev_id)
 470{
 471        struct mem_ctl_info *mci = dev_id;
 472        struct synps_edac_priv *priv = mci->pvt_info;
 473        int status, regval;
 474
 475        regval = readl(priv->baseaddr + DDR_QOS_IRQ_STAT_OFST) &
 476                        (DDR_QOSCE_MASK | DDR_QOSUE_MASK);
 477        if (!(regval & ECC_CE_UE_INTR_MASK))
 478                return IRQ_NONE;
 479        status = priv->p_data->synps_edac_geterror_info(priv->baseaddr,
 480                                &priv->stat);
 481        if (status)
 482                return IRQ_NONE;
 483
 484        priv->ce_cnt += priv->stat.ce_cnt;
 485        priv->ue_cnt += priv->stat.ue_cnt;
 486        synps_edac_handle_error(mci, &priv->stat);
 487
 488        edac_dbg(3, "Total error count ce %d ue %d\n",
 489                 priv->ce_cnt, priv->ue_cnt);
 490        writel(regval, priv->baseaddr + DDR_QOS_IRQ_STAT_OFST);
 491        return IRQ_HANDLED;
 492}
 493
 494/**
 495 * synps_edac_check - Check controller for ECC errors
 496 * @mci:        Pointer to the edac memory controller instance
 497 *
 498 * Used to check and post ECC errors. Called by the polling thread
 499 */
 500static void synps_edac_check(struct mem_ctl_info *mci)
 501{
 502        struct synps_edac_priv *priv = mci->pvt_info;
 503        int status;
 504
 505        status = priv->p_data->synps_edac_geterror_info(priv->baseaddr,
 506                                                        &priv->stat);
 507        if (status)
 508                return;
 509
 510        priv->ce_cnt += priv->stat.ce_cnt;
 511        priv->ue_cnt += priv->stat.ue_cnt;
 512        synps_edac_handle_error(mci, &priv->stat);
 513
 514        edac_dbg(3, "Total error count ce %d ue %d\n",
 515                 priv->ce_cnt, priv->ue_cnt);
 516}
 517
 518/**
 519 * synps_edac_get_dtype - Return the controller memory width
 520 * @base:       Pointer to the ddr memory controller base address
 521 *
 522 * Get the EDAC device type width appropriate for the current controller
 523 * configuration.
 524 *
 525 * Return: a device type width enumeration.
 526 */
 527static enum dev_type synps_edac_get_dtype(const void __iomem *base)
 528{
 529        enum dev_type dt;
 530        u32 width;
 531
 532        width = readl(base + CTRL_OFST);
 533        width = (width & CTRL_BW_MASK) >> CTRL_BW_SHIFT;
 534
 535        switch (width) {
 536        case DDRCTL_WDTH_16:
 537                dt = DEV_X2;
 538                break;
 539        case DDRCTL_WDTH_32:
 540                dt = DEV_X4;
 541                break;
 542        default:
 543                dt = DEV_UNKNOWN;
 544        }
 545
 546        return dt;
 547}
 548
 549/**
 550 * synps_enh_edac_get_dtype - Return the controller memory width
 551 * @base:       Pointer to the ddr memory controller base address
 552 *
 553 * Get the EDAC device type width appropriate for the current controller
 554 * configuration.
 555 *
 556 * Return: a device type width enumeration.
 557 */
 558static enum dev_type synps_enh_edac_get_dtype(const void __iomem *base)
 559{
 560        enum dev_type dt;
 561        u32 width;
 562
 563        width = readl(base + CTRL_OFST);
 564        width = (width & ECC_CTRL_BUSWIDTH_MASK) >>
 565                ECC_CTRL_BUSWIDTH_SHIFT;
 566        switch (width) {
 567        case DDRCTL_EWDTH_16:
 568                dt = DEV_X2;
 569                break;
 570        case DDRCTL_EWDTH_32:
 571                dt = DEV_X4;
 572                break;
 573        case DDRCTL_EWDTH_64:
 574                dt = DEV_X8;
 575                break;
 576        default:
 577                dt = DEV_UNKNOWN;
 578        }
 579
 580        return dt;
 581}
 582
 583/**
 584 * synps_edac_get_eccstate - Return the controller ecc enable/disable status
 585 * @base:       Pointer to the ddr memory controller base address
 586 *
 587 * Get the ECC enable/disable status for the controller
 588 *
 589 * Return: a ecc status boolean i.e true/false - enabled/disabled.
 590 */
 591static bool synps_edac_get_eccstate(void __iomem *base)
 592{
 593        enum dev_type dt;
 594        u32 ecctype;
 595        bool state = false;
 596
 597        dt = synps_edac_get_dtype(base);
 598        if (dt == DEV_UNKNOWN)
 599                return state;
 600
 601        ecctype = readl(base + SCRUB_OFST) & SCRUB_MODE_MASK;
 602        if ((ecctype == SCRUB_MODE_SECDED) && (dt == DEV_X2))
 603                state = true;
 604
 605        return state;
 606}
 607
 608/**
 609 * synps_enh_edac_get_eccstate - Return the controller ecc enable/disable status
 610 * @base:       Pointer to the ddr memory controller base address
 611 *
 612 * Get the ECC enable/disable status for the controller
 613 *
 614 * Return: a ecc status boolean i.e true/false - enabled/disabled.
 615 */
 616static bool synps_enh_edac_get_eccstate(void __iomem *base)
 617{
 618        enum dev_type dt;
 619        u32 ecctype;
 620        bool state = false;
 621
 622        dt = synps_enh_edac_get_dtype(base);
 623        if (dt == DEV_UNKNOWN)
 624                return state;
 625
 626        ecctype = readl(base + ECC_CFG0_OFST) & SCRUB_MODE_MASK;
 627        if ((ecctype == SCRUB_MODE_SECDED) &&
 628            ((dt == DEV_X2) || (dt == DEV_X4) || (dt == DEV_X8)))
 629                state = true;
 630
 631        return state;
 632}
 633
 634/**
 635 * synps_edac_get_memsize - reads the size of the attached memory device
 636 *
 637 * Return: the memory size in bytes
 638 */
 639static u32 synps_edac_get_memsize(void)
 640{
 641        struct sysinfo inf;
 642
 643        si_meminfo(&inf);
 644
 645        return inf.totalram * inf.mem_unit;
 646}
 647
 648/**
 649 * synps_edac_get_mtype - Returns controller memory type
 650 * @base:       pointer to the synopsys ecc status structure
 651 *
 652 * Get the EDAC memory type appropriate for the current controller
 653 * configuration.
 654 *
 655 * Return: a memory type enumeration.
 656 */
 657static enum mem_type synps_edac_get_mtype(const void __iomem *base)
 658{
 659        enum mem_type mt;
 660        u32 memtype;
 661
 662        memtype = readl(base + T_ZQ_OFST);
 663
 664        if (memtype & T_ZQ_DDRMODE_MASK)
 665                mt = MEM_DDR3;
 666        else
 667                mt = MEM_DDR2;
 668
 669        return mt;
 670}
 671
 672/**
 673 * synps_enh_edac_get_mtype - Returns controller memory type
 674 * @base:       pointer to the synopsys ecc status structure
 675 *
 676 * Get the EDAC memory type appropriate for the current controller
 677 * configuration.
 678 *
 679 * Return: a memory type enumeration.
 680 */
 681static enum mem_type synps_enh_edac_get_mtype(const void __iomem *base)
 682{
 683        enum mem_type mt;
 684        u32 memtype;
 685
 686        memtype = readl(base + CTRL_OFST);
 687
 688        mt = MEM_UNKNOWN;
 689        if ((memtype & MEM_TYPE_DDR3) || (memtype & MEM_TYPE_LPDDR3))
 690                mt = MEM_DDR3;
 691        else if (memtype & MEM_TYPE_DDR2)
 692                mt = MEM_RDDR2;
 693        else if ((memtype & MEM_TYPE_LPDDR4) || (memtype & MEM_TYPE_DDR4))
 694                mt = MEM_DDR4;
 695
 696        return mt;
 697}
 698
 699/**
 700 * synps_edac_init_csrows - Initialize the cs row data
 701 * @mci:        Pointer to the edac memory controller instance
 702 *
 703 * Initializes the chip select rows associated with the EDAC memory
 704 * controller instance
 705 *
 706 * Return: Unconditionally 0.
 707 */
 708static int synps_edac_init_csrows(struct mem_ctl_info *mci)
 709{
 710        struct csrow_info *csi;
 711        struct dimm_info *dimm;
 712        struct synps_edac_priv *priv = mci->pvt_info;
 713        u32 size;
 714        int row, j;
 715
 716        for (row = 0; row < mci->nr_csrows; row++) {
 717                csi = mci->csrows[row];
 718                size = synps_edac_get_memsize();
 719
 720                for (j = 0; j < csi->nr_channels; j++) {
 721                        dimm            = csi->channels[j]->dimm;
 722                        dimm->edac_mode = EDAC_FLAG_SECDED;
 723                        dimm->mtype     = priv->p_data->synps_edac_get_mtype(
 724                                                priv->baseaddr);
 725                        dimm->nr_pages  = (size >> PAGE_SHIFT) / csi->nr_channels;
 726                        dimm->grain     = SYNPS_EDAC_ERR_GRAIN;
 727                        dimm->dtype     = priv->p_data->synps_edac_get_dtype(
 728                                                priv->baseaddr);
 729                }
 730        }
 731
 732        return 0;
 733}
 734
 735/**
 736 * synps_edac_mc_init - Initialize driver instance
 737 * @mci:        Pointer to the edac memory controller instance
 738 * @pdev:       Pointer to the platform_device struct
 739 *
 740 * Performs initialization of the EDAC memory controller instance and
 741 * related driver-private data associated with the memory controller the
 742 * instance is bound to.
 743 *
 744 * Return: Always zero.
 745 */
 746static int synps_edac_mc_init(struct mem_ctl_info *mci,
 747                                 struct platform_device *pdev)
 748{
 749        int status;
 750        struct synps_edac_priv *priv;
 751
 752        mci->pdev = &pdev->dev;
 753        priv = mci->pvt_info;
 754        platform_set_drvdata(pdev, mci);
 755
 756        /* Initialize controller capabilities and configuration */
 757        mci->mtype_cap = MEM_FLAG_DDR3 | MEM_FLAG_DDR2;
 758        mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_SECDED;
 759        mci->scrub_cap = SCRUB_HW_SRC;
 760        mci->scrub_mode = SCRUB_NONE;
 761
 762        mci->edac_cap = EDAC_FLAG_SECDED;
 763        mci->ctl_name = "synps_ddr_controller";
 764        mci->dev_name = SYNPS_EDAC_MOD_STRING;
 765        mci->mod_name = SYNPS_EDAC_MOD_VER;
 766        mci->mod_ver = "1";
 767        if (priv->p_data->quirks & DDR_ECC_INTR_SUPPORT) {
 768                edac_op_state = EDAC_OPSTATE_INT;
 769        } else {
 770                edac_op_state = EDAC_OPSTATE_POLL;
 771                mci->edac_check = synps_edac_check;
 772        }
 773        mci->ctl_page_to_phys = NULL;
 774
 775        status = synps_edac_init_csrows(mci);
 776
 777        return status;
 778}
 779
 780static const struct synps_platform_data zynq_edac_def = {
 781        .synps_edac_geterror_info       = synps_edac_geterror_info,
 782        .synps_edac_get_mtype           = synps_edac_get_mtype,
 783        .synps_edac_get_dtype           = synps_edac_get_dtype,
 784        .synps_edac_get_eccstate        = synps_edac_get_eccstate,
 785        .quirks                         = 0,
 786};
 787
 788static const struct synps_platform_data zynqmp_enh_edac_def = {
 789        .synps_edac_geterror_info       = synps_enh_edac_geterror_info,
 790        .synps_edac_get_mtype           = synps_enh_edac_get_mtype,
 791        .synps_edac_get_dtype           = synps_enh_edac_get_dtype,
 792        .synps_edac_get_eccstate        = synps_enh_edac_get_eccstate,
 793        .quirks                         = (DDR_ECC_INTR_SUPPORT |
 794                                           DDR_ECC_DATA_POISON_SUPPORT),
 795};
 796
 797static const struct of_device_id synps_edac_match[] = {
 798        { .compatible = "xlnx,zynq-ddrc-a05", .data = (void *)&zynq_edac_def },
 799        { .compatible = "xlnx,zynqmp-ddrc-2.40a",
 800                                .data = (void *)&zynqmp_enh_edac_def},
 801        { /* end of table */ }
 802};
 803
 804MODULE_DEVICE_TABLE(of, synps_edac_match);
 805
 806#define to_mci(k) container_of(k, struct mem_ctl_info, dev)
 807
 808/**
 809 * ddr4_poison_setup - update poison registers
 810 * @dttype:             Device structure variable
 811 * @device_config:      Device configuration
 812 * @priv:               Pointer to synps_edac_priv struct
 813 *
 814 * Update poison registers as per ddr4 mapping
 815 * Return: none.
 816 */
 817static void ddr4_poison_setup(enum dev_type dttype, int device_config,
 818                                struct synps_edac_priv *priv)
 819{
 820        int col, row, bank, bankgrp, regval, shift_val = 0, col_shift;
 821
 822        /* Check the Configuration of the device */
 823        if (device_config & DDRC_MSTR_DEV_CONFIG_X8_MASK) {
 824                /* For Full Dq bus */
 825                if (dttype == DEV_X8)
 826                        shift_val = 0;
 827                /* For Half Dq bus */
 828                else if (dttype == DEV_X4)
 829                        shift_val = 1;
 830                col_shift = 0;
 831        } else if (device_config & DDRC_MSTR_DEV_CONFIG_X16_MASK) {
 832                if (dttype == DEV_X8)
 833                        shift_val = 1;
 834                else if (dttype == DEV_X4)
 835                        shift_val = 2;
 836                col_shift = 1;
 837        }
 838
 839        col = (priv->poison_addr >> (DDR4_COL_SHIFT -
 840                                (shift_val - col_shift))) &
 841                                DDR4_COL_MASK;
 842        row = priv->poison_addr >> (DDR4_ROW_SHIFT - shift_val);
 843        row &= DDR4_ROW_MASK;
 844        bank = priv->poison_addr >> (DDR4_BANK_SHIFT - shift_val);
 845        bank &= DDR4_BANK_MASK;
 846        bankgrp = (priv->poison_addr >> (DDR4_BANKGRP_SHIFT -
 847                                (shift_val - col_shift))) &
 848                                DDR4_BANKGRP_MASK;
 849
 850        writel(col, priv->baseaddr + ECC_POISON0_OFST);
 851        regval = (bankgrp << ECC_POISON1_BANKGRP_SHIFT) |
 852                 (bank << ECC_POISON1_BANKNR_SHIFT) | row;
 853        writel(regval, priv->baseaddr + ECC_POISON1_OFST);
 854}
 855
 856/**
 857 * ddr3_poison_setup - update poison registers
 858 * @dttype:             Device structure variable
 859 * @device_config:      Device configuration
 860 * @priv:               Pointer to synps_edac_priv struct
 861 *
 862 * Update poison registers as per ddr3 mapping
 863 * Return: none.
 864 */
 865static void ddr3_poison_setup(enum dev_type dttype, int device_config,
 866                                struct synps_edac_priv *priv)
 867{
 868        int col, row, bank, bankgrp, regval, shift_val = 0;
 869
 870        if (dttype == DEV_X8)
 871                /* For Full Dq bus */
 872                shift_val = 0;
 873        else if (dttype == DEV_X4)
 874                /* For Half Dq bus */
 875                shift_val = 1;
 876
 877        col = (priv->poison_addr >> (DDR3_COL_SHIFT - shift_val)) &
 878                DDR3_COL_MASK;
 879        row = priv->poison_addr >> (DDR3_ROW_SHIFT - shift_val);
 880        row &= DDR3_ROW_MASK;
 881        bank = priv->poison_addr >> (DDR3_BANK_SHIFT - shift_val);
 882        bank &= DDR3_BANK_MASK;
 883        bankgrp = 0;
 884        writel(col, priv->baseaddr + ECC_POISON0_OFST);
 885        regval = (bankgrp << ECC_POISON1_BANKGRP_SHIFT) |
 886                         (bank << ECC_POISON1_BANKNR_SHIFT) | row;
 887        writel(regval, priv->baseaddr + ECC_POISON1_OFST);
 888}
 889
 890/**
 891 * synps_edac_mc_inject_data_error_show - Get Poison0 & 1 register contents
 892 * @dev:        Pointer to the device struct
 893 * @mattr:      Pointer to device attributes
 894 * @data:       Pointer to user data
 895 *
 896 * Get the Poison0 and Poison1 register contents
 897 * Return: Number of bytes copied.
 898 */
 899static ssize_t synps_edac_mc_inject_data_error_show(struct device *dev,
 900                                              struct device_attribute *mattr,
 901                                              char *data)
 902{
 903        struct mem_ctl_info *mci = to_mci(dev);
 904        struct synps_edac_priv *priv = mci->pvt_info;
 905
 906        return sprintf(data, "Poison0 Addr: 0x%08x\n\rPoison1 Addr: 0x%08x\n\r"
 907                        "Error injection Address: 0x%lx\n\r",
 908                        readl(priv->baseaddr + ECC_POISON0_OFST),
 909                        readl(priv->baseaddr + ECC_POISON1_OFST),
 910                        priv->poison_addr);
 911}
 912
 913/**
 914 * synps_edac_mc_inject_data_error_store - Configure Poison0 Poison1 registers
 915 * @dev:        Pointer to the device struct
 916 * @mattr:      Pointer to device attributes
 917 * @data:       Pointer to user data
 918 * @count:      read the size bytes from buffer
 919 *
 920 * Configures the Poison0 and Poison1 register contents as per user given
 921 * address
 922 * Return: Number of bytes copied.
 923 */
 924static ssize_t synps_edac_mc_inject_data_error_store(struct device *dev,
 925                                               struct device_attribute *mattr,
 926                                               const char *data, size_t count)
 927{
 928        struct mem_ctl_info *mci = to_mci(dev);
 929        struct synps_edac_priv *priv = mci->pvt_info;
 930        int device_config;
 931        enum mem_type mttype;
 932        enum dev_type dttype;
 933
 934        mttype = priv->p_data->synps_edac_get_mtype(
 935                                                priv->baseaddr);
 936        dttype = priv->p_data->synps_edac_get_dtype(
 937                                                priv->baseaddr);
 938        if (kstrtoul(data, 0, &priv->poison_addr))
 939                return -EINVAL;
 940
 941        device_config = readl(priv->baseaddr + CTRL_OFST);
 942        device_config = (device_config & DDRC_MSTR_DEV_CONFIG_MASK) >>
 943                                        DDRC_MSTR_DEV_CONFIG_SHIFT;
 944        if (mttype == MEM_DDR4)
 945                ddr4_poison_setup(dttype, device_config, priv);
 946        else if (mttype == MEM_DDR3)
 947                ddr3_poison_setup(dttype, device_config, priv);
 948
 949        return count;
 950}
 951
 952/**
 953 * synps_edac_mc_inject_data_poison_show - Shows type of Data poison
 954 * @dev:        Pointer to the device struct
 955 * @mattr:      Pointer to device attributes
 956 * @data:       Pointer to user data
 957 *
 958 * Shows the type of Error injection enabled, either UE or CE
 959 * Return: Number of bytes copied.
 960 */
 961static ssize_t synps_edac_mc_inject_data_poison_show(struct device *dev,
 962                                              struct device_attribute *mattr,
 963                                              char *data)
 964{
 965        struct mem_ctl_info *mci = to_mci(dev);
 966        struct synps_edac_priv *priv = mci->pvt_info;
 967
 968        return sprintf(data, "Data Poisoning: %s\n\r",
 969                        ((readl(priv->baseaddr + ECC_CFG1_OFST)) & 0x3) ?
 970                        ("Correctable Error"):("UnCorrectable Error"));
 971}
 972
 973/**
 974 * synps_edac_mc_inject_data_poison_store - Enbles Data poison CE/UE
 975 * @dev:        Pointer to the device struct
 976 * @mattr:      Pointer to device attributes
 977 * @data:       Pointer to user data
 978 * @count:      read the size bytes from buffer
 979 *
 980 * Enables the CE or UE Data poison
 981 * Return: Number of bytes copied.
 982 */
 983static ssize_t synps_edac_mc_inject_data_poison_store(struct device *dev,
 984                                               struct device_attribute *mattr,
 985                                               const char *data, size_t count)
 986{
 987        struct mem_ctl_info *mci = to_mci(dev);
 988        struct synps_edac_priv *priv = mci->pvt_info;
 989
 990        writel(0, priv->baseaddr + DDRC_SWCTL);
 991        if (strncmp(data, "CE", 2) == 0)
 992                writel(ECC_CEPOISON_MASK, priv->baseaddr + ECC_CFG1_OFST);
 993        else
 994                writel(ECC_UEPOISON_MASK, priv->baseaddr + ECC_CFG1_OFST);
 995        writel(1, priv->baseaddr + DDRC_SWCTL);
 996
 997        return count;
 998}
 999
1000static DEVICE_ATTR(inject_data_error, S_IRUGO | S_IWUSR,
1001            synps_edac_mc_inject_data_error_show,
1002            synps_edac_mc_inject_data_error_store);
1003static DEVICE_ATTR(inject_data_poison, S_IRUGO | S_IWUSR,
1004            synps_edac_mc_inject_data_poison_show,
1005            synps_edac_mc_inject_data_poison_store);
1006
1007/**
1008 * synps_edac_create_sysfs_attributes - Create sysfs entries
1009 * @mci:        Pointer to the edac memory controller instance
1010 *
1011 * Create sysfs attributes for injecting ECC errors using data poison.
1012 *
1013 * Return: 0 if sysfs creation was successful, else return negative error code.
1014 */
1015static int synps_edac_create_sysfs_attributes(struct mem_ctl_info *mci)
1016{
1017        int rc;
1018
1019        rc = device_create_file(&mci->dev, &dev_attr_inject_data_error);
1020        if (rc < 0)
1021                return rc;
1022        rc = device_create_file(&mci->dev, &dev_attr_inject_data_poison);
1023        if (rc < 0)
1024                return rc;
1025        return 0;
1026}
1027
1028/**
1029 * synps_edac_remove_sysfs_attributes - Removes sysfs entries
1030 * @mci:        Pointer to the edac memory controller instance
1031 *
1032 * Removes sysfs attributes.
1033 *
1034 * Return: none.
1035 */
1036static void synps_edac_remove_sysfs_attributes(struct mem_ctl_info *mci)
1037{
1038        device_remove_file(&mci->dev, &dev_attr_inject_data_error);
1039        device_remove_file(&mci->dev, &dev_attr_inject_data_poison);
1040}
1041
1042/**
1043 * synps_edac_mc_probe - Check controller and bind driver
1044 * @pdev:       Pointer to the platform_device struct
1045 *
1046 * Probes a specific controller instance for binding with the driver.
1047 *
1048 * Return: 0 if the controller instance was successfully bound to the
1049 * driver; otherwise, < 0 on error.
1050 */
1051static int synps_edac_mc_probe(struct platform_device *pdev)
1052{
1053        struct mem_ctl_info *mci;
1054        struct edac_mc_layer layers[2];
1055        struct synps_edac_priv *priv;
1056        int rc, irq, status;
1057        struct resource *res;
1058        void __iomem *baseaddr;
1059        const struct of_device_id *match;
1060        const struct synps_platform_data *p_data;
1061
1062        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1063        baseaddr = devm_ioremap_resource(&pdev->dev, res);
1064        if (IS_ERR(baseaddr))
1065                return PTR_ERR(baseaddr);
1066
1067        match = of_match_node(synps_edac_match, pdev->dev.of_node);
1068        if (!match && !match->data) {
1069                dev_err(&pdev->dev, "of_match_node() failed\n");
1070                return -EINVAL;
1071        }
1072
1073        p_data = (struct synps_platform_data *)match->data;
1074        if (!(p_data->synps_edac_get_eccstate(baseaddr))) {
1075                edac_printk(KERN_INFO, EDAC_MC, "ECC not enabled\n");
1076                return -ENXIO;
1077        }
1078
1079        layers[0].type = EDAC_MC_LAYER_CHIP_SELECT;
1080        layers[0].size = SYNPS_EDAC_NR_CSROWS;
1081        layers[0].is_virt_csrow = true;
1082        layers[1].type = EDAC_MC_LAYER_CHANNEL;
1083        layers[1].size = SYNPS_EDAC_NR_CHANS;
1084        layers[1].is_virt_csrow = false;
1085
1086        mci = edac_mc_alloc(0, ARRAY_SIZE(layers), layers,
1087                            sizeof(struct synps_edac_priv));
1088        if (!mci) {
1089                edac_printk(KERN_ERR, EDAC_MC,
1090                            "Failed memory allocation for mc instance\n");
1091                return -ENOMEM;
1092        }
1093
1094        priv = mci->pvt_info;
1095        priv->baseaddr = baseaddr;
1096        priv->p_data = match->data;
1097
1098        rc = synps_edac_mc_init(mci, pdev);
1099        if (rc) {
1100                edac_printk(KERN_ERR, EDAC_MC,
1101                            "Failed to initialize instance\n");
1102                goto free_edac_mc;
1103        }
1104
1105        if (priv->p_data->quirks & DDR_ECC_INTR_SUPPORT) {
1106                irq = platform_get_irq(pdev, 0);
1107                if (irq < 0) {
1108                        edac_printk(KERN_ERR, EDAC_MC,
1109                                        "No irq %d in DT\n", irq);
1110                        return -ENODEV;
1111                }
1112
1113                status = devm_request_irq(&pdev->dev, irq,
1114                        synps_edac_intr_handler,
1115                        0, dev_name(&pdev->dev), mci);
1116                if (status < 0) {
1117                        edac_printk(KERN_ERR, EDAC_MC, "Failed to request Irq\n");
1118                        goto free_edac_mc;
1119                }
1120
1121                /* Enable UE/CE Interrupts */
1122                writel((DDR_QOSUE_MASK | DDR_QOSCE_MASK),
1123                        priv->baseaddr + DDR_QOS_IRQ_EN_OFST);
1124        }
1125
1126        rc = edac_mc_add_mc(mci);
1127        if (rc) {
1128                edac_printk(KERN_ERR, EDAC_MC,
1129                            "Failed to register with EDAC core\n");
1130                goto free_edac_mc;
1131        }
1132
1133        if (priv->p_data->quirks & DDR_ECC_DATA_POISON_SUPPORT) {
1134                if (synps_edac_create_sysfs_attributes(mci)) {
1135                        edac_printk(KERN_ERR, EDAC_MC,
1136                                        "Failed to create sysfs entries\n");
1137                        goto free_edac_mc;
1138                }
1139        }
1140        /*
1141         * Start capturing the correctable and uncorrectable errors. A write of
1142         * 0 starts the counters.
1143         */
1144        if (!(priv->p_data->quirks & DDR_ECC_INTR_SUPPORT))
1145                writel(0x0, baseaddr + ECC_CTRL_OFST);
1146        return rc;
1147
1148free_edac_mc:
1149        edac_mc_free(mci);
1150
1151        return rc;
1152}
1153
1154/**
1155 * synps_edac_mc_remove - Unbind driver from controller
1156 * @pdev:       Pointer to the platform_device struct
1157 *
1158 * Return: Unconditionally 0
1159 */
1160static int synps_edac_mc_remove(struct platform_device *pdev)
1161{
1162        struct mem_ctl_info *mci = platform_get_drvdata(pdev);
1163        struct synps_edac_priv *priv;
1164
1165        priv = mci->pvt_info;
1166        if (priv->p_data->quirks & DDR_ECC_INTR_SUPPORT)
1167                /* Disable UE/CE Interrupts */
1168                writel((DDR_QOSUE_MASK | DDR_QOSCE_MASK),
1169                        priv->baseaddr + DDR_QOS_IRQ_DB_OFST);
1170        edac_mc_del_mc(&pdev->dev);
1171        if (priv->p_data->quirks & DDR_ECC_DATA_POISON_SUPPORT)
1172                synps_edac_remove_sysfs_attributes(mci);
1173        edac_mc_free(mci);
1174
1175        return 0;
1176}
1177
1178static struct platform_driver synps_edac_mc_driver = {
1179        .driver = {
1180                   .name = "synopsys-edac",
1181                   .of_match_table = synps_edac_match,
1182                   },
1183        .probe = synps_edac_mc_probe,
1184        .remove = synps_edac_mc_remove,
1185};
1186
1187module_platform_driver(synps_edac_mc_driver);
1188
1189MODULE_AUTHOR("Xilinx Inc");
1190MODULE_DESCRIPTION("Synopsys DDR ECC driver");
1191MODULE_LICENSE("GPL v2");
1192