Skip to content

Commit

Permalink
EDAC: Replace EDAC_DIMM_PTR() macro with edac_get_dimm() function
Browse files Browse the repository at this point in the history
The EDAC_DIMM_PTR() macro takes 3 arguments from struct mem_ctl_info.
Clean up this interface to only pass the mci struct and replace this
macro with a new function edac_get_dimm().

Also introduce an edac_get_dimm_by_index() function for later use.
This allows it to get a DIMM pointer only by a given index. This can
be useful if the DIMM's position within the layers of the memory
controller or the exact size of the layers are unknown.

Small style changes made for some hunks after applying the semantic
patch.

Semantic patch used:

@@ expression mci, a, b,c; @@

-EDAC_DIMM_PTR(mci->layers, mci->dimms, mci->n_layers, a, b, c)
+edac_get_dimm(mci, a, b, c)

 [ bp: Touchups. ]

Signed-off-by: Robert Richter <rrichter@marvell.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Reviewed-by: Mauro Carvalho Chehab <mchehab@kernel.org>
Cc: "linux-edac@vger.kernel.org" <linux-edac@vger.kernel.org>
Cc: James Morse <james.morse@arm.com>
Cc: Jason Baron <jbaron@akamai.com>
Cc: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Cc: Tero Kristo <t-kristo@ti.com>
Cc: Tony Luck <tony.luck@intel.com>
Link: https://lkml.kernel.org/r/20191106093239.25517-2-rrichter@marvell.com
  • Loading branch information
Robert Richter authored and Borislav Petkov committed Nov 9, 2019
1 parent 7fdfee9 commit bc9ad9e
Show file tree
Hide file tree
Showing 14 changed files with 74 additions and 63 deletions.
7 changes: 2 additions & 5 deletions drivers/edac/ghes_edac.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,7 @@ static void ghes_edac_dmidecode(const struct dmi_header *dh, void *arg)

if (dh->type == DMI_ENTRY_MEM_DEVICE) {
struct memdev_dmi_entry *entry = (struct memdev_dmi_entry *)dh;
struct dimm_info *dimm = EDAC_DIMM_PTR(mci->layers, mci->dimms,
mci->n_layers,
dimm_fill->count, 0, 0);
struct dimm_info *dimm = edac_get_dimm(mci, dimm_fill->count, 0, 0);
u16 rdr_mask = BIT(7) | BIT(13);

if (entry->size == 0xffff) {
Expand Down Expand Up @@ -544,8 +542,7 @@ int ghes_edac_register(struct ghes *ghes, struct device *dev)
dimm_fill.mci = mci;
dmi_walk(ghes_edac_dmidecode, &dimm_fill);
} else {
struct dimm_info *dimm = EDAC_DIMM_PTR(mci->layers, mci->dimms,
mci->n_layers, 0, 0, 0);
struct dimm_info *dimm = edac_get_dimm(mci, 0, 0, 0);

dimm->nr_pages = 1;
dimm->grain = 128;
Expand Down
3 changes: 1 addition & 2 deletions drivers/edac/i10nm_base.c
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,7 @@ static int i10nm_get_dimm_config(struct mem_ctl_info *mci)

ndimms = 0;
for (j = 0; j < I10NM_NUM_DIMMS; j++) {
dimm = EDAC_DIMM_PTR(mci->layers, mci->dimms,
mci->n_layers, i, j, 0);
dimm = edac_get_dimm(mci, i, j, 0);
mtr = I10NM_GET_DIMMMTR(imc, i, j);
mcddrtcfg = I10NM_GET_MCDDRTCFG(imc, i, j);
edac_dbg(1, "dimmmtr 0x%x mcddrtcfg 0x%x (mc%d ch%d dimm%d)\n",
Expand Down
3 changes: 1 addition & 2 deletions drivers/edac/i3200_edac.c
Original file line number Diff line number Diff line change
Expand Up @@ -392,8 +392,7 @@ static int i3200_probe1(struct pci_dev *pdev, int dev_idx)
unsigned long nr_pages;

for (j = 0; j < nr_channels; j++) {
struct dimm_info *dimm = EDAC_DIMM_PTR(mci->layers, mci->dimms,
mci->n_layers, i, j, 0);
struct dimm_info *dimm = edac_get_dimm(mci, i, j, 0);

nr_pages = drb_to_nr_pages(drbs, stacked, j, i);
if (nr_pages == 0)
Expand Down
5 changes: 2 additions & 3 deletions drivers/edac/i5000_edac.c
Original file line number Diff line number Diff line change
Expand Up @@ -1275,9 +1275,8 @@ static int i5000_init_csrows(struct mem_ctl_info *mci)
if (!MTR_DIMMS_PRESENT(mtr))
continue;

dimm = EDAC_DIMM_PTR(mci->layers, mci->dimms, mci->n_layers,
channel / MAX_BRANCHES,
channel % MAX_BRANCHES, slot);
dimm = edac_get_dimm(mci, channel / MAX_BRANCHES,
channel % MAX_BRANCHES, slot);

csrow_megs = pvt->dimm_info[slot][channel].megabytes;
dimm->grain = 8;
Expand Down
3 changes: 1 addition & 2 deletions drivers/edac/i5100_edac.c
Original file line number Diff line number Diff line change
Expand Up @@ -858,8 +858,7 @@ static void i5100_init_csrows(struct mem_ctl_info *mci)
if (!npages)
continue;

dimm = EDAC_DIMM_PTR(mci->layers, mci->dimms, mci->n_layers,
chan, rank, 0);
dimm = edac_get_dimm(mci, chan, rank, 0);

dimm->nr_pages = npages;
dimm->grain = 32;
Expand Down
3 changes: 1 addition & 2 deletions drivers/edac/i5400_edac.c
Original file line number Diff line number Diff line change
Expand Up @@ -1187,8 +1187,7 @@ static int i5400_init_dimms(struct mem_ctl_info *mci)
if (!MTR_DIMMS_PRESENT(mtr))
continue;

dimm = EDAC_DIMM_PTR(mci->layers, mci->dimms, mci->n_layers,
channel / 2, channel % 2, slot);
dimm = edac_get_dimm(mci, channel / 2, channel % 2, slot);

size_mb = pvt->dimm_info[slot][channel].megabytes;

Expand Down
3 changes: 1 addition & 2 deletions drivers/edac/i7300_edac.c
Original file line number Diff line number Diff line change
Expand Up @@ -794,8 +794,7 @@ static int i7300_init_csrows(struct mem_ctl_info *mci)
for (ch = 0; ch < max_channel; ch++) {
int channel = to_channel(ch, branch);

dimm = EDAC_DIMM_PTR(mci->layers, mci->dimms,
mci->n_layers, branch, ch, slot);
dimm = edac_get_dimm(mci, branch, ch, slot);

dinfo = &pvt->dimm_info[slot][channel];

Expand Down
3 changes: 1 addition & 2 deletions drivers/edac/i7core_edac.c
Original file line number Diff line number Diff line change
Expand Up @@ -585,8 +585,7 @@ static int get_dimm_config(struct mem_ctl_info *mci)
if (!DIMM_PRESENT(dimm_dod[j]))
continue;

dimm = EDAC_DIMM_PTR(mci->layers, mci->dimms, mci->n_layers,
i, j, 0);
dimm = edac_get_dimm(mci, i, j, 0);
banks = numbank(MC_DOD_NUMBANK(dimm_dod[j]));
ranks = numrank(MC_DOD_NUMRANK(dimm_dod[j]));
rows = numrow(MC_DOD_NUMROW(dimm_dod[j]));
Expand Down
7 changes: 2 additions & 5 deletions drivers/edac/ie31200_edac.c
Original file line number Diff line number Diff line change
Expand Up @@ -490,9 +490,7 @@ static int ie31200_probe1(struct pci_dev *pdev, int dev_idx)

if (dimm_info[j][i].dual_rank) {
nr_pages = nr_pages / 2;
dimm = EDAC_DIMM_PTR(mci->layers, mci->dimms,
mci->n_layers, (i * 2) + 1,
j, 0);
dimm = edac_get_dimm(mci, (i * 2) + 1, j, 0);
dimm->nr_pages = nr_pages;
edac_dbg(0, "set nr pages: 0x%lx\n", nr_pages);
dimm->grain = 8; /* just a guess */
Expand All @@ -503,8 +501,7 @@ static int ie31200_probe1(struct pci_dev *pdev, int dev_idx)
dimm->dtype = DEV_UNKNOWN;
dimm->edac_mode = EDAC_UNKNOWN;
}
dimm = EDAC_DIMM_PTR(mci->layers, mci->dimms,
mci->n_layers, i * 2, j, 0);
dimm = edac_get_dimm(mci, i * 2, j, 0);
dimm->nr_pages = nr_pages;
edac_dbg(0, "set nr pages: 0x%lx\n", nr_pages);
dimm->grain = 8; /* same guess */
Expand Down
4 changes: 2 additions & 2 deletions drivers/edac/pnd2_edac.c
Original file line number Diff line number Diff line change
Expand Up @@ -1231,7 +1231,7 @@ static void apl_get_dimm_config(struct mem_ctl_info *mci)
if (!(chan_mask & BIT(i)))
continue;

dimm = EDAC_DIMM_PTR(mci->layers, mci->dimms, mci->n_layers, i, 0, 0);
dimm = edac_get_dimm(mci, i, 0, 0);
if (!dimm) {
edac_dbg(0, "No allocated DIMM for channel %d\n", i);
continue;
Expand Down Expand Up @@ -1311,7 +1311,7 @@ static void dnv_get_dimm_config(struct mem_ctl_info *mci)
if (!ranks_of_dimm[j])
continue;

dimm = EDAC_DIMM_PTR(mci->layers, mci->dimms, mci->n_layers, i, j, 0);
dimm = edac_get_dimm(mci, i, j, 0);
if (!dimm) {
edac_dbg(0, "No allocated DIMM for channel %d DIMM %d\n", i, j);
continue;
Expand Down
2 changes: 1 addition & 1 deletion drivers/edac/sb_edac.c
Original file line number Diff line number Diff line change
Expand Up @@ -1621,7 +1621,7 @@ static int __populate_dimms(struct mem_ctl_info *mci,
}

for (j = 0; j < max_dimms_per_channel; j++) {
dimm = EDAC_DIMM_PTR(mci->layers, mci->dimms, mci->n_layers, i, j, 0);
dimm = edac_get_dimm(mci, i, j, 0);
if (pvt->info.type == KNIGHTS_LANDING) {
pci_read_config_dword(pvt->knl.pci_channel[i],
knl_mtr_reg, &mtr);
Expand Down
3 changes: 1 addition & 2 deletions drivers/edac/skx_base.c
Original file line number Diff line number Diff line change
Expand Up @@ -189,8 +189,7 @@ static int skx_get_dimm_config(struct mem_ctl_info *mci)
pci_read_config_dword(imc->chan[i].cdev, 0x8C, &amap);
pci_read_config_dword(imc->chan[i].cdev, 0x400, &mcddrtcfg);
for (j = 0; j < SKX_NUM_DIMMS; j++) {
dimm = EDAC_DIMM_PTR(mci->layers, mci->dimms,
mci->n_layers, i, j, 0);
dimm = edac_get_dimm(mci, i, j, 0);
pci_read_config_dword(imc->chan[i].cdev,
0x80 + 4 * j, &mtr);
if (IS_DIMM_PRESENT(mtr)) {
Expand Down
2 changes: 1 addition & 1 deletion drivers/edac/ti_edac.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ static void ti_edac_setup_dimm(struct mem_ctl_info *mci, u32 type)
u32 val;
u32 memsize;

dimm = EDAC_DIMM_PTR(mci->layers, mci->dimms, mci->n_layers, 0, 0, 0);
dimm = edac_get_dimm(mci, 0, 0, 0);

val = ti_edac_readl(edac, EMIF_SDRAM_CONFIG);

Expand Down
89 changes: 57 additions & 32 deletions include/linux/edac.h
Original file line number Diff line number Diff line change
Expand Up @@ -403,37 +403,6 @@ struct edac_mc_layer {
__i; \
})

/**
* EDAC_DIMM_PTR - Macro responsible to get a pointer inside a pointer array
* for the element given by [layer0,layer1,layer2] position
*
* @layers: a struct edac_mc_layer array, describing how many elements
* were allocated for each layer
* @var: name of the var where we want to get the pointer
* (like mci->dimms)
* @nlayers: Number of layers at the @layers array
* @layer0: layer0 position
* @layer1: layer1 position. Unused if n_layers < 2
* @layer2: layer2 position. Unused if n_layers < 3
*
* For 1 layer, this macro returns "var[layer0]";
*
* For 2 layers, this macro is similar to allocate a bi-dimensional array
* and to return "var[layer0][layer1]";
*
* For 3 layers, this macro is similar to allocate a tri-dimensional array
* and to return "var[layer0][layer1][layer2]";
*/
#define EDAC_DIMM_PTR(layers, var, nlayers, layer0, layer1, layer2) ({ \
typeof(*var) __p; \
int ___i = EDAC_DIMM_OFF(layers, nlayers, layer0, layer1, layer2); \
if (___i < 0) \
__p = NULL; \
else \
__p = (var)[___i]; \
__p; \
})

struct dimm_info {
struct device dev;

Expand Down Expand Up @@ -669,4 +638,60 @@ struct mem_ctl_info {
bool fake_inject_ue;
u16 fake_inject_count;
};
#endif

/**
* edac_get_dimm_by_index - Get DIMM info at @index from a memory
* controller
*
* @mci: MC descriptor struct mem_ctl_info
* @index: index in the memory controller's DIMM array
*
* Returns a struct dimm_info * or NULL on failure.
*/
static inline struct dimm_info *
edac_get_dimm_by_index(struct mem_ctl_info *mci, int index)
{
if (index < 0 || index >= mci->tot_dimms)
return NULL;

return mci->dimms[index];
}

/**
* edac_get_dimm - Get DIMM info from a memory controller given by
* [layer0,layer1,layer2] position
*
* @mci: MC descriptor struct mem_ctl_info
* @layer0: layer0 position
* @layer1: layer1 position. Unused if n_layers < 2
* @layer2: layer2 position. Unused if n_layers < 3
*
* For 1 layer, this function returns "dimms[layer0]";
*
* For 2 layers, this function is similar to allocating a two-dimensional
* array and returning "dimms[layer0][layer1]";
*
* For 3 layers, this function is similar to allocating a tri-dimensional
* array and returning "dimms[layer0][layer1][layer2]";
*/
static inline struct dimm_info *edac_get_dimm(struct mem_ctl_info *mci,
int layer0, int layer1, int layer2)
{
int index;

if (layer0 < 0
|| (mci->n_layers > 1 && layer1 < 0)
|| (mci->n_layers > 2 && layer2 < 0))
return NULL;

index = layer0;

if (mci->n_layers > 1)
index = index * mci->layers[1].size + layer1;

if (mci->n_layers > 2)
index = index * mci->layers[2].size + layer2;

return edac_get_dimm_by_index(mci, index);
}
#endif /* _LINUX_EDAC_H_ */

0 comments on commit bc9ad9e

Please sign in to comment.