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) {
                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;
 
 
                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",
 
                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)
 
                        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;
 
                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;
 
                        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;
 
 
                        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];
 
 
                        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]));
 
 
                        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 */
                                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 */
 
                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;
                        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;
 
                }
 
                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);
 
                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)) {
 
        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);
 
 
        __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;
 
        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_ */