#include <asm/cacheflush.h>
#include <linux/genalloc.h>
#include <linux/interrupt.h>
#include <linux/irqchip/chained_irq.h>
#include <linux/kernel.h>
#include <linux/mfd/syscon.h>
#include <linux/notifier.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/uaccess.h>
#define EDAC_MOD_STR "altera_edac"
#define EDAC_DEVICE "Altera"
#ifdef CONFIG_EDAC_ALTERA_SDRAM
static const struct altr_sdram_prv_data c5_data = {
.ecc_ctrl_offset = CV_CTLCFG_OFST,
.ecc_ctl_en_mask = CV_CTLCFG_ECC_AUTO_EN,
.ecc_stat_offset = CV_DRAMSTS_OFST,
.ecc_stat_ce_mask = CV_DRAMSTS_SBEERR,
.ecc_stat_ue_mask = CV_DRAMSTS_DBEERR,
.ecc_saddr_offset = CV_ERRADDR_OFST,
.ecc_daddr_offset = CV_ERRADDR_OFST,
.ecc_cecnt_offset = CV_SBECOUNT_OFST,
.ecc_uecnt_offset = CV_DBECOUNT_OFST,
.ecc_irq_en_offset = CV_DRAMINTR_OFST,
.ecc_irq_en_mask = CV_DRAMINTR_INTREN,
.ecc_irq_clr_offset = CV_DRAMINTR_OFST,
.ecc_irq_clr_mask = (CV_DRAMINTR_INTRCLR | CV_DRAMINTR_INTREN),
.ecc_cnt_rst_offset = CV_DRAMINTR_OFST,
.ecc_cnt_rst_mask = CV_DRAMINTR_INTRCLR,
.ce_ue_trgr_offset = CV_CTLCFG_OFST,
.ce_set_mask = CV_CTLCFG_GEN_SB_ERR,
.ue_set_mask = CV_CTLCFG_GEN_DB_ERR,
static const struct altr_sdram_prv_data a10_data = {
.ecc_ctrl_offset = A10_ECCCTRL1_OFST,
.ecc_ctl_en_mask = A10_ECCCTRL1_ECC_EN,
.ecc_stat_offset = A10_INTSTAT_OFST,
.ecc_stat_ce_mask = A10_INTSTAT_SBEERR,
.ecc_stat_ue_mask = A10_INTSTAT_DBEERR,
.ecc_saddr_offset = A10_SERRADDR_OFST,
.ecc_daddr_offset = A10_DERRADDR_OFST,
.ecc_irq_en_offset = A10_ERRINTEN_OFST,
.ecc_irq_en_mask = A10_ECC_IRQ_EN_MASK,
.ecc_irq_clr_offset = A10_INTSTAT_OFST,
.ecc_irq_clr_mask = (A10_INTSTAT_SBEERR | A10_INTSTAT_DBEERR),
.ecc_cnt_rst_offset = A10_ECCCTRL1_OFST,
.ecc_cnt_rst_mask = A10_ECC_CNT_RESET_MASK,
.ce_ue_trgr_offset = A10_DIAGINTTEST_OFST,
.ce_set_mask = A10_DIAGINT_TSERRA_MASK,
.ue_set_mask = A10_DIAGINT_TDERRA_MASK,
static irqreturn_t altr_sdram_mc_err_handler(int irq, void *dev_id)
struct mem_ctl_info *mci = dev_id;
struct altr_sdram_mc_data *drvdata = mci->pvt_info;
const struct altr_sdram_prv_data *priv = drvdata->data;
u32 status, err_count = 1, err_addr;
regmap_read(drvdata->mc_vbase, priv->ecc_stat_offset, &status);
if (status & priv->ecc_stat_ue_mask) {
regmap_read(drvdata->mc_vbase, priv->ecc_daddr_offset,
if (priv->ecc_uecnt_offset)
regmap_read(drvdata->mc_vbase, priv->ecc_uecnt_offset,
panic("\nEDAC: [%d Uncorrectable errors @ 0x%08X]\n",