mci = edac_mc_alloc(mc, ARRAY_SIZE(layers), layers, sizeof(struct octeon_lmc_pvt));
#include <linux/module.h>
#include <asm/octeon/octeon.h>
#include <asm/octeon/cvmx-lmcx-defs.h>
#define to_mci(k) container_of(k, struct mem_ctl_info, dev)
unsigned long error_type;
static void octeon_lmc_edac_poll(struct mem_ctl_info *mci)
union cvmx_lmcx_mem_cfg0 cfg0;
cfg0.u64 = cvmx_read_csr(CVMX_LMCX_MEM_CFG0(mci->mc_idx));
if (cfg0.s.sec_err || cfg0.s.ded_err) {
union cvmx_lmcx_fadr fadr;
fadr.u64 = cvmx_read_csr(CVMX_LMCX_FADR(mci->mc_idx));
snprintf(msg, sizeof(msg),
"DIMM %d rank %d bank %d row %d col %d",
fadr.cn30xx.fdimm, fadr.cn30xx.fbunk,
fadr.cn30xx.fbank, fadr.cn30xx.frow, fadr.cn30xx.fcol);
edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, 1, 0, 0, 0,
edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, 1, 0, 0, 0,
cvmx_write_csr(CVMX_LMCX_MEM_CFG0(mci->mc_idx), cfg0.u64);
static void octeon_lmc_edac_poll_o2(struct mem_ctl_info *mci)
struct octeon_lmc_pvt *pvt = mci->pvt_info;
union cvmx_lmcx_int int_reg;
int_reg.u64 = cvmx_read_csr(CVMX_LMCX_INT(mci->mc_idx));
if (pvt->error_type == 1)
if (pvt->error_type == 2)
if (int_reg.s.sec_err || int_reg.s.ded_err) {
union cvmx_lmcx_fadr fadr;
if (likely(!pvt->inject))
fadr.u64 = cvmx_read_csr(CVMX_LMCX_FADR(mci->mc_idx));