diff options
-rw-r--r-- | drivers/edac/sb_edac.c | 54 |
1 files changed, 35 insertions, 19 deletions
diff --git a/drivers/edac/sb_edac.c b/drivers/edac/sb_edac.c index fe4ffeaa623b..1990978e7963 100644 --- a/drivers/edac/sb_edac.c +++ b/drivers/edac/sb_edac.c @@ -1594,6 +1594,23 @@ static int knl_get_dimm_capacity(struct sbridge_pvt *pvt, u64 *mc_sizes) return 0; } +static void get_source_id(struct mem_ctl_info *mci) +{ + struct sbridge_pvt *pvt = mci->pvt_info; + u32 reg; + + if (pvt->info.type == HASWELL || pvt->info.type == BROADWELL || + pvt->info.type == KNIGHTS_LANDING) + pci_read_config_dword(pvt->pci_sad1, SAD_TARGET, ®); + else + pci_read_config_dword(pvt->pci_br0, SAD_TARGET, ®); + + if (pvt->info.type == KNIGHTS_LANDING) + pvt->sbridge_dev->source_id = SOURCE_ID_KNL(reg); + else + pvt->sbridge_dev->source_id = SOURCE_ID(reg); +} + static int get_dimm_config(struct mem_ctl_info *mci) { struct sbridge_pvt *pvt = mci->pvt_info; @@ -1611,17 +1628,6 @@ static int get_dimm_config(struct mem_ctl_info *mci) pci_read_config_dword(pvt->pci_ha0, HASWELL_HASYSDEFEATURE2, ®); pvt->is_chan_hash = GET_BITFIELD(reg, 21, 21); } - if (pvt->info.type == HASWELL || pvt->info.type == BROADWELL || - pvt->info.type == KNIGHTS_LANDING) - pci_read_config_dword(pvt->pci_sad1, SAD_TARGET, ®); - else - pci_read_config_dword(pvt->pci_br0, SAD_TARGET, ®); - - if (pvt->info.type == KNIGHTS_LANDING) - pvt->sbridge_dev->source_id = SOURCE_ID_KNL(reg); - else - pvt->sbridge_dev->source_id = SOURCE_ID(reg); - pvt->sbridge_dev->node_id = pvt->info.get_node_id(pvt); edac_dbg(0, "mc#%d: Node ID: %d, source ID: %d\n", pvt->sbridge_dev->mc, @@ -3222,12 +3228,14 @@ static int sbridge_register_mci(struct sbridge_dev *sbridge_dev, enum type type) pvt->info.max_interleave = ARRAY_SIZE(ibridge_interleave_list); pvt->info.interleave_pkg = ibridge_interleave_pkg; pvt->info.get_width = ibridge_get_width; - mci->ctl_name = kasprintf(GFP_KERNEL, "Ivy Bridge Socket#%d", mci->mc_idx); /* Store pci devices at mci for faster access */ rc = ibridge_mci_bind_devs(mci, sbridge_dev); if (unlikely(rc < 0)) goto fail0; + get_source_id(mci); + mci->ctl_name = kasprintf(GFP_KERNEL, "Ivy Bridge SrcID#%d", + pvt->sbridge_dev->source_id); break; case SANDY_BRIDGE: pvt->info.rankcfgr = SB_RANK_CFG_A; @@ -3245,12 +3253,14 @@ static int sbridge_register_mci(struct sbridge_dev *sbridge_dev, enum type type) pvt->info.max_interleave = ARRAY_SIZE(sbridge_interleave_list); pvt->info.interleave_pkg = sbridge_interleave_pkg; pvt->info.get_width = sbridge_get_width; - mci->ctl_name = kasprintf(GFP_KERNEL, "Sandy Bridge Socket#%d", mci->mc_idx); /* Store pci devices at mci for faster access */ rc = sbridge_mci_bind_devs(mci, sbridge_dev); if (unlikely(rc < 0)) goto fail0; + get_source_id(mci); + mci->ctl_name = kasprintf(GFP_KERNEL, "Sandy Bridge SrcID#%d", + pvt->sbridge_dev->source_id); break; case HASWELL: /* rankcfgr isn't used */ @@ -3268,12 +3278,14 @@ static int sbridge_register_mci(struct sbridge_dev *sbridge_dev, enum type type) pvt->info.max_interleave = ARRAY_SIZE(ibridge_interleave_list); pvt->info.interleave_pkg = ibridge_interleave_pkg; pvt->info.get_width = ibridge_get_width; - mci->ctl_name = kasprintf(GFP_KERNEL, "Haswell Socket#%d", mci->mc_idx); /* Store pci devices at mci for faster access */ rc = haswell_mci_bind_devs(mci, sbridge_dev); if (unlikely(rc < 0)) goto fail0; + get_source_id(mci); + mci->ctl_name = kasprintf(GFP_KERNEL, "Haswell SrcID#%d", + pvt->sbridge_dev->source_id); break; case BROADWELL: /* rankcfgr isn't used */ @@ -3291,12 +3303,14 @@ static int sbridge_register_mci(struct sbridge_dev *sbridge_dev, enum type type) pvt->info.max_interleave = ARRAY_SIZE(ibridge_interleave_list); pvt->info.interleave_pkg = ibridge_interleave_pkg; pvt->info.get_width = broadwell_get_width; - mci->ctl_name = kasprintf(GFP_KERNEL, "Broadwell Socket#%d", mci->mc_idx); /* Store pci devices at mci for faster access */ rc = broadwell_mci_bind_devs(mci, sbridge_dev); if (unlikely(rc < 0)) goto fail0; + get_source_id(mci); + mci->ctl_name = kasprintf(GFP_KERNEL, "Broadwell SrcID#%d", + pvt->sbridge_dev->source_id); break; case KNIGHTS_LANDING: /* pvt->info.rankcfgr == ??? */ @@ -3314,12 +3328,13 @@ static int sbridge_register_mci(struct sbridge_dev *sbridge_dev, enum type type) pvt->info.max_interleave = ARRAY_SIZE(knl_interleave_list); pvt->info.interleave_pkg = ibridge_interleave_pkg; pvt->info.get_width = knl_get_width; - mci->ctl_name = kasprintf(GFP_KERNEL, - "Knights Landing Socket#%d", mci->mc_idx); rc = knl_mci_bind_devs(mci, sbridge_dev); if (unlikely(rc < 0)) goto fail0; + get_source_id(mci); + mci->ctl_name = kasprintf(GFP_KERNEL, "Knights Landing SrcID#%d", + pvt->sbridge_dev->source_id); break; } @@ -3334,13 +3349,14 @@ static int sbridge_register_mci(struct sbridge_dev *sbridge_dev, enum type type) if (unlikely(edac_mc_add_mc(mci))) { edac_dbg(0, "MC: failed edac_mc_add_mc()\n"); rc = -EINVAL; - goto fail0; + goto fail; } return 0; -fail0: +fail: kfree(mci->ctl_name); +fail0: edac_mc_free(mci); sbridge_dev->mci = NULL; return rc; |