in i10nm_base.c [539:640]
static int __init i10nm_init(void)
{
u8 mc = 0, src_id = 0, node_id = 0;
const struct x86_cpu_id *id;
struct res_config *cfg;
const char *owner;
struct skx_dev *d;
int rc, i, off[3] = {0xd0, 0xc8, 0xcc};
u64 tolm, tohm;
edac_dbg(2, "\n");
owner = edac_get_owner();
if (owner && strncmp(owner, EDAC_MOD_STR, sizeof(EDAC_MOD_STR)))
return -EBUSY;
if (cpu_feature_enabled(X86_FEATURE_HYPERVISOR))
return -ENODEV;
id = x86_match_cpu(i10nm_cpuids);
if (!id)
return -ENODEV;
cfg = (struct res_config *)id->driver_data;
res_cfg = cfg;
rc = skx_get_hi_lo(0x09a2, off, &tolm, &tohm);
if (rc)
return rc;
rc = skx_get_all_bus_mappings(cfg, &i10nm_edac_list);
if (rc < 0)
goto fail;
if (rc == 0) {
i10nm_printk(KERN_ERR, "No memory controllers found\n");
return -ENODEV;
}
skx_set_mem_cfg(i10nm_check_2lm(cfg));
rc = i10nm_get_ddr_munits();
if (i10nm_get_hbm_munits() && rc)
goto fail;
list_for_each_entry(d, i10nm_edac_list, list) {
rc = skx_get_src_id(d, 0xf8, &src_id);
if (rc < 0)
goto fail;
rc = skx_get_node_id(d, &node_id);
if (rc < 0)
goto fail;
edac_dbg(2, "src_id = %d node_id = %d\n", src_id, node_id);
for (i = 0; i < I10NM_NUM_IMC; i++) {
if (!d->imc[i].mdev)
continue;
d->imc[i].mc = mc++;
d->imc[i].lmc = i;
d->imc[i].src_id = src_id;
d->imc[i].node_id = node_id;
if (d->imc[i].hbm_mc) {
d->imc[i].chan_mmio_sz = cfg->hbm_chan_mmio_sz;
d->imc[i].num_channels = I10NM_NUM_HBM_CHANNELS;
d->imc[i].num_dimms = I10NM_NUM_HBM_DIMMS;
} else {
d->imc[i].chan_mmio_sz = cfg->ddr_chan_mmio_sz;
d->imc[i].num_channels = I10NM_NUM_DDR_CHANNELS;
d->imc[i].num_dimms = I10NM_NUM_DDR_DIMMS;
}
rc = skx_register_mci(&d->imc[i], d->imc[i].mdev,
"Intel_10nm Socket", EDAC_MOD_STR,
i10nm_get_dimm_config, cfg);
if (rc < 0)
goto fail;
}
}
rc = skx_adxl_get();
if (rc)
goto fail;
opstate_init();
mce_register_decode_chain(&i10nm_mce_dec);
setup_i10nm_debug();
if (retry_rd_err_log && res_cfg->offsets_scrub && res_cfg->offsets_demand) {
skx_set_decode(NULL, show_retry_rd_err_log);
if (retry_rd_err_log == 2)
enable_retry_rd_err_log(true);
}
i10nm_printk(KERN_INFO, "%s\n", I10NM_REVISION);
return 0;
fail:
skx_remove();
return rc;
}