Commit de3910eb79ac8c0f29a11224661c0ebaaf813039

Authored by Mauro Carvalho Chehab
1 parent e39f4ea9b0

edac: change the mem allocation scheme to make Documentation/kobject.txt happy

Kernel kobjects have rigid rules: each container object should be
dynamically allocated, and can't be allocated into a single kmalloc.

EDAC never obeyed this rule: it has a single malloc function that
allocates all needed data into a single kzalloc.

As this is not accepted anymore, change the allocation schema of the
EDAC *_info structs to enforce this Kernel standard.

Acked-by: Chris Metcalf <cmetcalf@tilera.com>
Cc: Aristeu Rozanski <arozansk@redhat.com>
Cc: Doug Thompson <norsk5@yahoo.com>
Cc: Greg K H <gregkh@linuxfoundation.org>
Cc: Borislav Petkov <borislav.petkov@amd.com>
Cc: Mark Gross <mark.gross@intel.com>
Cc: Tim Small <tim@buttersideup.com>
Cc: Ranganathan Desikan <ravi@jetztechnologies.com>
Cc: "Arvind R." <arvino55@gmail.com>
Cc: Olof Johansson <olof@lixom.net>
Cc: Egor Martovetsky <egor@pasemi.com>
Cc: Michal Marek <mmarek@suse.cz>
Cc: Jiri Kosina <jkosina@suse.cz>
Cc: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Hitoshi Mitake <h.mitake@gmail.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Shaohui Xie <Shaohui.Xie@freescale.com>
Cc: linuxppc-dev@lists.ozlabs.org
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

Showing 22 changed files with 242 additions and 164 deletions Side-by-side Diff

drivers/edac/amd64_edac.c
... ... @@ -2205,6 +2205,7 @@
2205 2205 static int init_csrows(struct mem_ctl_info *mci)
2206 2206 {
2207 2207 struct csrow_info *csrow;
  2208 + struct dimm_info *dimm;
2208 2209 struct amd64_pvt *pvt = mci->pvt_info;
2209 2210 u64 base, mask;
2210 2211 u32 val;
... ... @@ -2222,7 +2223,7 @@
2222 2223 !!(val & NBCFG_CHIPKILL), !!(val & NBCFG_ECC_ENABLE));
2223 2224  
2224 2225 for_each_chip_select(i, 0, pvt) {
2225   - csrow = &mci->csrows[i];
  2226 + csrow = mci->csrows[i];
2226 2227  
2227 2228 if (!csrow_enabled(i, 0, pvt) && !csrow_enabled(i, 1, pvt)) {
2228 2229 debugf1("----CSROW %d EMPTY for node %d\n", i,
... ... @@ -2257,9 +2258,10 @@
2257 2258 edac_mode = EDAC_NONE;
2258 2259  
2259 2260 for (j = 0; j < pvt->channel_count; j++) {
2260   - csrow->channels[j].dimm->mtype = mtype;
2261   - csrow->channels[j].dimm->edac_mode = edac_mode;
2262   - csrow->channels[j].dimm->nr_pages = nr_pages;
  2261 + dimm = csrow->channels[j]->dimm;
  2262 + dimm->mtype = mtype;
  2263 + dimm->edac_mode = edac_mode;
  2264 + dimm->nr_pages = nr_pages;
2263 2265 }
2264 2266 }
2265 2267  
drivers/edac/amd76x_edac.c
... ... @@ -146,7 +146,7 @@
146 146 if (handle_errors) {
147 147 row = (info->ecc_mode_status >> 4) & 0xf;
148 148 edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci,
149   - mci->csrows[row].first_page, 0, 0,
  149 + mci->csrows[row]->first_page, 0, 0,
150 150 row, 0, -1,
151 151 mci->ctl_name, "", NULL);
152 152 }
... ... @@ -161,7 +161,7 @@
161 161 if (handle_errors) {
162 162 row = info->ecc_mode_status & 0xf;
163 163 edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci,
164   - mci->csrows[row].first_page, 0, 0,
  164 + mci->csrows[row]->first_page, 0, 0,
165 165 row, 0, -1,
166 166 mci->ctl_name, "", NULL);
167 167 }
... ... @@ -194,8 +194,8 @@
194 194 int index;
195 195  
196 196 for (index = 0; index < mci->nr_csrows; index++) {
197   - csrow = &mci->csrows[index];
198   - dimm = csrow->channels[0].dimm;
  197 + csrow = mci->csrows[index];
  198 + dimm = csrow->channels[0]->dimm;
199 199  
200 200 /* find the DRAM Chip Select Base address and mask */
201 201 pci_read_config_dword(pdev,
drivers/edac/cell_edac.c
... ... @@ -33,7 +33,7 @@
33 33 static void cell_edac_count_ce(struct mem_ctl_info *mci, int chan, u64 ar)
34 34 {
35 35 struct cell_edac_priv *priv = mci->pvt_info;
36   - struct csrow_info *csrow = &mci->csrows[0];
  36 + struct csrow_info *csrow = mci->csrows[0];
37 37 unsigned long address, pfn, offset, syndrome;
38 38  
39 39 dev_dbg(mci->pdev, "ECC CE err on node %d, channel %d, ar = 0x%016llx\n",
... ... @@ -56,7 +56,7 @@
56 56 static void cell_edac_count_ue(struct mem_ctl_info *mci, int chan, u64 ar)
57 57 {
58 58 struct cell_edac_priv *priv = mci->pvt_info;
59   - struct csrow_info *csrow = &mci->csrows[0];
  59 + struct csrow_info *csrow = mci->csrows[0];
60 60 unsigned long address, pfn, offset;
61 61  
62 62 dev_dbg(mci->pdev, "ECC UE err on node %d, channel %d, ar = 0x%016llx\n",
... ... @@ -126,7 +126,7 @@
126 126  
127 127 static void __devinit cell_edac_init_csrows(struct mem_ctl_info *mci)
128 128 {
129   - struct csrow_info *csrow = &mci->csrows[0];
  129 + struct csrow_info *csrow = mci->csrows[0];
130 130 struct dimm_info *dimm;
131 131 struct cell_edac_priv *priv = mci->pvt_info;
132 132 struct device_node *np;
... ... @@ -150,7 +150,7 @@
150 150 csrow->last_page = csrow->first_page + nr_pages - 1;
151 151  
152 152 for (j = 0; j < csrow->nr_channels; j++) {
153   - dimm = csrow->channels[j].dimm;
  153 + dimm = csrow->channels[j]->dimm;
154 154 dimm->mtype = MEM_XDR;
155 155 dimm->edac_mode = EDAC_SECDED;
156 156 dimm->nr_pages = nr_pages / csrow->nr_channels;
drivers/edac/cpc925_edac.c
... ... @@ -348,7 +348,7 @@
348 348 if (bba == 0)
349 349 continue; /* not populated */
350 350  
351   - csrow = &mci->csrows[index];
  351 + csrow = mci->csrows[index];
352 352  
353 353 row_size = bba * (1UL << 28); /* 256M */
354 354 csrow->first_page = last_nr_pages;
... ... @@ -380,7 +380,7 @@
380 380 break;
381 381 }
382 382 for (j = 0; j < csrow->nr_channels; j++) {
383   - dimm = csrow->channels[j].dimm;
  383 + dimm = csrow->channels[j]->dimm;
384 384 dimm->nr_pages = nr_pages / csrow->nr_channels;
385 385 dimm->mtype = MEM_RDDR;
386 386 dimm->edac_mode = EDAC_SECDED;
... ... @@ -463,7 +463,7 @@
463 463 *csrow = rank;
464 464  
465 465 #ifdef CONFIG_EDAC_DEBUG
466   - if (mci->csrows[rank].first_page == 0) {
  466 + if (mci->csrows[rank]->first_page == 0) {
467 467 cpc925_mc_printk(mci, KERN_ERR, "ECC occurs in a "
468 468 "non-populated csrow, broken hardware?\n");
469 469 return;
... ... @@ -471,7 +471,7 @@
471 471 #endif
472 472  
473 473 /* Revert csrow number */
474   - pa = mci->csrows[rank].first_page << PAGE_SHIFT;
  474 + pa = mci->csrows[rank]->first_page << PAGE_SHIFT;
475 475  
476 476 /* Revert column address */
477 477 col += bcnt;
drivers/edac/e752x_edac.c
... ... @@ -1096,7 +1096,7 @@
1096 1096 for (last_cumul_size = index = 0; index < mci->nr_csrows; index++) {
1097 1097 /* mem_dev 0=x8, 1=x4 */
1098 1098 mem_dev = (dra >> (index * 4 + 2)) & 0x3;
1099   - csrow = &mci->csrows[remap_csrow_index(mci, index)];
  1099 + csrow = mci->csrows[remap_csrow_index(mci, index)];
1100 1100  
1101 1101 mem_dev = (mem_dev == 2);
1102 1102 pci_read_config_byte(pdev, E752X_DRB + index, &value);
... ... @@ -1127,7 +1127,7 @@
1127 1127 } else
1128 1128 edac_mode = EDAC_NONE;
1129 1129 for (i = 0; i < csrow->nr_channels; i++) {
1130   - struct dimm_info *dimm = csrow->channels[i].dimm;
  1130 + struct dimm_info *dimm = csrow->channels[i]->dimm;
1131 1131  
1132 1132 debugf3("Initializing rank at (%i,%i)\n", index, i);
1133 1133 dimm->nr_pages = nr_pages / csrow->nr_channels;
drivers/edac/e7xxx_edac.c
... ... @@ -378,7 +378,7 @@
378 378 for (index = 0; index < mci->nr_csrows; index++) {
379 379 /* mem_dev 0=x8, 1=x4 */
380 380 mem_dev = (dra >> (index * 4 + 3)) & 0x1;
381   - csrow = &mci->csrows[index];
  381 + csrow = mci->csrows[index];
382 382  
383 383 pci_read_config_byte(pdev, E7XXX_DRB + index, &value);
384 384 /* convert a 64 or 32 MiB DRB to a page size. */
... ... @@ -409,7 +409,7 @@
409 409 edac_mode = EDAC_NONE;
410 410  
411 411 for (j = 0; j < drc_chan + 1; j++) {
412   - dimm = csrow->channels[j].dimm;
  412 + dimm = csrow->channels[j]->dimm;
413 413  
414 414 dimm->nr_pages = nr_pages / (drc_chan + 1);
415 415 dimm->grain = 1 << 12; /* 4KiB - resolution of CELOG */
drivers/edac/edac_mc.c
... ... @@ -210,15 +210,15 @@
210 210 {
211 211 struct mem_ctl_info *mci;
212 212 struct edac_mc_layer *layer;
213   - struct csrow_info *csi, *csr;
214   - struct rank_info *chi, *chp, *chan;
  213 + struct csrow_info *csr;
  214 + struct rank_info *chan;
215 215 struct dimm_info *dimm;
216 216 u32 *ce_per_layer[EDAC_MAX_LAYERS], *ue_per_layer[EDAC_MAX_LAYERS];
217 217 unsigned pos[EDAC_MAX_LAYERS];
218 218 unsigned size, tot_dimms = 1, count = 1;
219 219 unsigned tot_csrows = 1, tot_channels = 1, tot_errcount = 0;
220 220 void *pvt, *p, *ptr = NULL;
221   - int i, j, row, chn, n, len;
  221 + int i, j, row, chn, n, len, off;
222 222 bool per_rank = false;
223 223  
224 224 BUG_ON(n_layers > EDAC_MAX_LAYERS || n_layers == 0);
... ... @@ -244,9 +244,6 @@
244 244 */
245 245 mci = edac_align_ptr(&ptr, sizeof(*mci), 1);
246 246 layer = edac_align_ptr(&ptr, sizeof(*layer), n_layers);
247   - csi = edac_align_ptr(&ptr, sizeof(*csi), tot_csrows);
248   - chi = edac_align_ptr(&ptr, sizeof(*chi), tot_csrows * tot_channels);
249   - dimm = edac_align_ptr(&ptr, sizeof(*dimm), tot_dimms);
250 247 for (i = 0; i < n_layers; i++) {
251 248 count *= layers[i].size;
252 249 debugf4("%s: errcount layer %d size %d\n", __func__, i, count);
... ... @@ -264,6 +261,7 @@
264 261 tot_dimms,
265 262 per_rank ? "ranks" : "dimms",
266 263 tot_csrows * tot_channels);
  264 +
267 265 mci = kzalloc(size, GFP_KERNEL);
268 266 if (mci == NULL)
269 267 return NULL;
... ... @@ -272,9 +270,6 @@
272 270 * rather than an imaginary chunk of memory located at address 0.
273 271 */
274 272 layer = (struct edac_mc_layer *)(((char *)mci) + ((unsigned long)layer));
275   - csi = (struct csrow_info *)(((char *)mci) + ((unsigned long)csi));
276   - chi = (struct rank_info *)(((char *)mci) + ((unsigned long)chi));
277   - dimm = (struct dimm_info *)(((char *)mci) + ((unsigned long)dimm));
278 273 for (i = 0; i < n_layers; i++) {
279 274 mci->ce_per_layer[i] = (u32 *)((char *)mci + ((unsigned long)ce_per_layer[i]));
280 275 mci->ue_per_layer[i] = (u32 *)((char *)mci + ((unsigned long)ue_per_layer[i]));
... ... @@ -283,8 +278,6 @@
283 278  
284 279 /* setup index and various internal pointers */
285 280 mci->mc_idx = mc_num;
286   - mci->csrows = csi;
287   - mci->dimms = dimm;
288 281 mci->tot_dimms = tot_dimms;
289 282 mci->pvt_info = pvt;
290 283 mci->n_layers = n_layers;
291 284  
292 285  
293 286  
294 287  
295 288  
296 289  
297 290  
298 291  
... ... @@ -295,39 +288,60 @@
295 288 mci->mem_is_per_rank = per_rank;
296 289  
297 290 /*
298   - * Fill the csrow struct
  291 + * Alocate and fill the csrow/channels structs
299 292 */
  293 + mci->csrows = kcalloc(sizeof(*mci->csrows), tot_csrows, GFP_KERNEL);
  294 + if (!mci->csrows)
  295 + goto error;
300 296 for (row = 0; row < tot_csrows; row++) {
301   - csr = &csi[row];
  297 + csr = kzalloc(sizeof(**mci->csrows), GFP_KERNEL);
  298 + if (!csr)
  299 + goto error;
  300 + mci->csrows[row] = csr;
302 301 csr->csrow_idx = row;
303 302 csr->mci = mci;
304 303 csr->nr_channels = tot_channels;
305   - chp = &chi[row * tot_channels];
306   - csr->channels = chp;
  304 + csr->channels = kcalloc(sizeof(*csr->channels), tot_channels,
  305 + GFP_KERNEL);
  306 + if (!csr->channels)
  307 + goto error;
307 308  
308 309 for (chn = 0; chn < tot_channels; chn++) {
309   - chan = &chp[chn];
  310 + chan = kzalloc(sizeof(**csr->channels), GFP_KERNEL);
  311 + if (!chan)
  312 + goto error;
  313 + csr->channels[chn] = chan;
310 314 chan->chan_idx = chn;
311 315 chan->csrow = csr;
312 316 }
313 317 }
314 318  
315 319 /*
316   - * Fill the dimm struct
  320 + * Allocate and fill the dimm structs
317 321 */
  322 + mci->dimms = kcalloc(sizeof(*mci->dimms), tot_dimms, GFP_KERNEL);
  323 + if (!mci->dimms)
  324 + goto error;
  325 +
318 326 memset(&pos, 0, sizeof(pos));
319 327 row = 0;
320 328 chn = 0;
321 329 debugf4("%s: initializing %d %s\n", __func__, tot_dimms,
322 330 per_rank ? "ranks" : "dimms");
323 331 for (i = 0; i < tot_dimms; i++) {
324   - chan = &csi[row].channels[chn];
325   - dimm = EDAC_DIMM_PTR(layer, mci->dimms, n_layers,
326   - pos[0], pos[1], pos[2]);
  332 + chan = mci->csrows[row]->channels[chn];
  333 + off = EDAC_DIMM_OFF(layer, n_layers, pos[0], pos[1], pos[2]);
  334 + if (off < 0 || off >= tot_dimms) {
  335 + edac_mc_printk(mci, KERN_ERR, "EDAC core bug: EDAC_DIMM_OFF is trying to do an illegal data access\n");
  336 + goto error;
  337 + }
  338 +
  339 + dimm = kzalloc(sizeof(**mci->dimms), GFP_KERNEL);
  340 + mci->dimms[off] = dimm;
327 341 dimm->mci = mci;
328 342  
329   - debugf2("%s: %d: %s%zd (%d:%d:%d): row %d, chan %d\n", __func__,
330   - i, per_rank ? "rank" : "dimm", (dimm - mci->dimms),
  343 + debugf2("%s: %d: %s%i (%d:%d:%d): row %d, chan %d\n", __func__,
  344 + i, per_rank ? "rank" : "dimm", off,
331 345 pos[0], pos[1], pos[2], row, chn);
332 346  
333 347 /*
... ... @@ -381,6 +395,28 @@
381 395 */
382 396  
383 397 return mci;
  398 +
  399 +error:
  400 + if (mci->dimms) {
  401 + for (i = 0; i < tot_dimms; i++)
  402 + kfree(mci->dimms[i]);
  403 + kfree(mci->dimms);
  404 + }
  405 + if (mci->csrows) {
  406 + for (chn = 0; chn < tot_channels; chn++) {
  407 + csr = mci->csrows[chn];
  408 + if (csr) {
  409 + for (chn = 0; chn < tot_channels; chn++)
  410 + kfree(csr->channels[chn]);
  411 + kfree(csr);
  412 + }
  413 + kfree(mci->csrows[i]);
  414 + }
  415 + kfree(mci->csrows);
  416 + }
  417 + kfree(mci);
  418 +
  419 + return NULL;
384 420 }
385 421 EXPORT_SYMBOL_GPL(edac_mc_alloc);
386 422  
387 423  
... ... @@ -393,10 +429,8 @@
393 429 {
394 430 debugf1("%s()\n", __func__);
395 431  
  432 + /* the mci instance is freed here, when the sysfs object is dropped */
396 433 edac_unregister_sysfs(mci);
397   -
398   - /* free the mci instance memory here */
399   - kfree(mci);
400 434 }
401 435 EXPORT_SYMBOL_GPL(edac_mc_free);
402 436  
403 437  
... ... @@ -668,13 +702,12 @@
668 702 for (i = 0; i < mci->nr_csrows; i++) {
669 703 int j;
670 704  
671   - edac_mc_dump_csrow(&mci->csrows[i]);
672   - for (j = 0; j < mci->csrows[i].nr_channels; j++)
673   - edac_mc_dump_channel(&mci->csrows[i].
674   - channels[j]);
  705 + edac_mc_dump_csrow(mci->csrows[i]);
  706 + for (j = 0; j < mci->csrows[i]->nr_channels; j++)
  707 + edac_mc_dump_channel(mci->csrows[i]->channels[j]);
675 708 }
676 709 for (i = 0; i < mci->tot_dimms; i++)
677   - edac_mc_dump_dimm(&mci->dimms[i]);
  710 + edac_mc_dump_dimm(mci->dimms[i]);
678 711 }
679 712 #endif
680 713 mutex_lock(&mem_ctls_mutex);
681 714  
682 715  
... ... @@ -793,17 +826,17 @@
793 826 /* FIXME - should return -1 */
794 827 int edac_mc_find_csrow_by_page(struct mem_ctl_info *mci, unsigned long page)
795 828 {
796   - struct csrow_info *csrows = mci->csrows;
  829 + struct csrow_info **csrows = mci->csrows;
797 830 int row, i, j, n;
798 831  
799 832 debugf1("MC%d: %s(): 0x%lx\n", mci->mc_idx, __func__, page);
800 833 row = -1;
801 834  
802 835 for (i = 0; i < mci->nr_csrows; i++) {
803   - struct csrow_info *csrow = &csrows[i];
  836 + struct csrow_info *csrow = csrows[i];
804 837 n = 0;
805 838 for (j = 0; j < csrow->nr_channels; j++) {
806   - struct dimm_info *dimm = csrow->channels[j].dimm;
  839 + struct dimm_info *dimm = csrow->channels[j]->dimm;
807 840 n += dimm->nr_pages;
808 841 }
809 842 if (n == 0)
... ... @@ -1062,7 +1095,7 @@
1062 1095 p = label;
1063 1096 *p = '\0';
1064 1097 for (i = 0; i < mci->tot_dimms; i++) {
1065   - struct dimm_info *dimm = &mci->dimms[i];
  1098 + struct dimm_info *dimm = mci->dimms[i];
1066 1099  
1067 1100 if (top_layer >= 0 && top_layer != dimm->location[0])
1068 1101 continue;
1069 1102  
1070 1103  
... ... @@ -1120,13 +1153,13 @@
1120 1153 strcpy(label, "unknown memory");
1121 1154 if (type == HW_EVENT_ERR_CORRECTED) {
1122 1155 if (row >= 0) {
1123   - mci->csrows[row].ce_count++;
  1156 + mci->csrows[row]->ce_count++;
1124 1157 if (chan >= 0)
1125   - mci->csrows[row].channels[chan].ce_count++;
  1158 + mci->csrows[row]->channels[chan]->ce_count++;
1126 1159 }
1127 1160 } else
1128 1161 if (row >= 0)
1129   - mci->csrows[row].ue_count++;
  1162 + mci->csrows[row]->ue_count++;
1130 1163 }
1131 1164  
1132 1165 /* Fill the RAM location data */
drivers/edac/edac_mc_sysfs.c
... ... @@ -82,7 +82,7 @@
82 82 &edac_mc_poll_msec, 0644);
83 83 MODULE_PARM_DESC(edac_mc_poll_msec, "Polling period in milliseconds");
84 84  
85   -static struct device mci_pdev;
  85 +static struct device *mci_pdev;
86 86  
87 87 /*
88 88 * various constants for Memory Controllers
... ... @@ -181,7 +181,7 @@
181 181 u32 nr_pages = 0;
182 182  
183 183 for (i = 0; i < csrow->nr_channels; i++)
184   - nr_pages += csrow->channels[i].dimm->nr_pages;
  184 + nr_pages += csrow->channels[i]->dimm->nr_pages;
185 185 return sprintf(data, "%u\n", PAGES_TO_MiB(nr_pages));
186 186 }
187 187  
... ... @@ -190,7 +190,7 @@
190 190 {
191 191 struct csrow_info *csrow = to_csrow(dev);
192 192  
193   - return sprintf(data, "%s\n", mem_types[csrow->channels[0].dimm->mtype]);
  193 + return sprintf(data, "%s\n", mem_types[csrow->channels[0]->dimm->mtype]);
194 194 }
195 195  
196 196 static ssize_t csrow_dev_type_show(struct device *dev,
... ... @@ -198,7 +198,7 @@
198 198 {
199 199 struct csrow_info *csrow = to_csrow(dev);
200 200  
201   - return sprintf(data, "%s\n", dev_types[csrow->channels[0].dimm->dtype]);
  201 + return sprintf(data, "%s\n", dev_types[csrow->channels[0]->dimm->dtype]);
202 202 }
203 203  
204 204 static ssize_t csrow_edac_mode_show(struct device *dev,
... ... @@ -207,7 +207,7 @@
207 207 {
208 208 struct csrow_info *csrow = to_csrow(dev);
209 209  
210   - return sprintf(data, "%s\n", edac_caps[csrow->channels[0].dimm->edac_mode]);
  210 + return sprintf(data, "%s\n", edac_caps[csrow->channels[0]->dimm->edac_mode]);
211 211 }
212 212  
213 213 /* show/store functions for DIMM Label attributes */
... ... @@ -217,7 +217,7 @@
217 217 {
218 218 struct csrow_info *csrow = to_csrow(dev);
219 219 unsigned chan = to_channel(mattr);
220   - struct rank_info *rank = &csrow->channels[chan];
  220 + struct rank_info *rank = csrow->channels[chan];
221 221  
222 222 /* if field has not been initialized, there is nothing to send */
223 223 if (!rank->dimm->label[0])
... ... @@ -233,7 +233,7 @@
233 233 {
234 234 struct csrow_info *csrow = to_csrow(dev);
235 235 unsigned chan = to_channel(mattr);
236   - struct rank_info *rank = &csrow->channels[chan];
  236 + struct rank_info *rank = csrow->channels[chan];
237 237  
238 238 ssize_t max_size = 0;
239 239  
... ... @@ -250,7 +250,7 @@
250 250 {
251 251 struct csrow_info *csrow = to_csrow(dev);
252 252 unsigned chan = to_channel(mattr);
253   - struct rank_info *rank = &csrow->channels[chan];
  253 + struct rank_info *rank = csrow->channels[chan];
254 254  
255 255 return sprintf(data, "%u\n", rank->ce_count);
256 256 }
257 257  
... ... @@ -283,9 +283,12 @@
283 283 NULL
284 284 };
285 285  
286   -static void csrow_attr_release(struct device *device)
  286 +static void csrow_attr_release(struct device *dev)
287 287 {
288   - debugf1("Releasing csrow device %s\n", dev_name(device));
  288 + struct csrow_info *csrow = container_of(dev, struct csrow_info, dev);
  289 +
  290 + debugf1("Releasing csrow device %s\n", dev_name(dev));
  291 + kfree(csrow);
289 292 }
290 293  
291 294 static struct device_type csrow_attr_type = {
... ... @@ -352,7 +355,7 @@
352 355 int chan, nr_pages = 0;
353 356  
354 357 for (chan = 0; chan < csrow->nr_channels; chan++)
355   - nr_pages += csrow->channels[chan].dimm->nr_pages;
  358 + nr_pages += csrow->channels[chan]->dimm->nr_pages;
356 359  
357 360 return nr_pages;
358 361 }
... ... @@ -382,7 +385,7 @@
382 385  
383 386 for (chan = 0; chan < csrow->nr_channels; chan++) {
384 387 /* Only expose populated DIMMs */
385   - if (!csrow->channels[chan].dimm->nr_pages)
  388 + if (!csrow->channels[chan]->dimm->nr_pages)
386 389 continue;
387 390 err = device_create_file(&csrow->dev,
388 391 dynamic_csrow_dimm_attr[chan]);
389 392  
... ... @@ -418,10 +421,10 @@
418 421 struct csrow_info *csrow;
419 422  
420 423 for (i = 0; i < mci->nr_csrows; i++) {
421   - csrow = &mci->csrows[i];
  424 + csrow = mci->csrows[i];
422 425 if (!nr_pages_per_csrow(csrow))
423 426 continue;
424   - err = edac_create_csrow_object(mci, &mci->csrows[i], i);
  427 + err = edac_create_csrow_object(mci, mci->csrows[i], i);
425 428 if (err < 0)
426 429 goto error;
427 430 }
428 431  
429 432  
... ... @@ -429,18 +432,18 @@
429 432  
430 433 error:
431 434 for (--i; i >= 0; i--) {
432   - csrow = &mci->csrows[i];
  435 + csrow = mci->csrows[i];
433 436 if (!nr_pages_per_csrow(csrow))
434 437 continue;
435 438 for (chan = csrow->nr_channels - 1; chan >= 0; chan--) {
436   - if (!csrow->channels[chan].dimm->nr_pages)
  439 + if (!csrow->channels[chan]->dimm->nr_pages)
437 440 continue;
438 441 device_remove_file(&csrow->dev,
439 442 dynamic_csrow_dimm_attr[chan]);
440 443 device_remove_file(&csrow->dev,
441 444 dynamic_csrow_ce_count_attr[chan]);
442 445 }
443   - put_device(&mci->csrows[i].dev);
  446 + put_device(&mci->csrows[i]->dev);
444 447 }
445 448  
446 449 return err;
447 450  
... ... @@ -452,11 +455,11 @@
452 455 struct csrow_info *csrow;
453 456  
454 457 for (i = mci->nr_csrows - 1; i >= 0; i--) {
455   - csrow = &mci->csrows[i];
  458 + csrow = mci->csrows[i];
456 459 if (!nr_pages_per_csrow(csrow))
457 460 continue;
458 461 for (chan = csrow->nr_channels - 1; chan >= 0; chan--) {
459   - if (!csrow->channels[chan].dimm->nr_pages)
  462 + if (!csrow->channels[chan]->dimm->nr_pages)
460 463 continue;
461 464 debugf1("Removing csrow %d channel %d sysfs nodes\n",
462 465 i, chan);
... ... @@ -465,8 +468,8 @@
465 468 device_remove_file(&csrow->dev,
466 469 dynamic_csrow_ce_count_attr[chan]);
467 470 }
468   - put_device(&mci->csrows[i].dev);
469   - device_del(&mci->csrows[i].dev);
  471 + put_device(&mci->csrows[i]->dev);
  472 + device_del(&mci->csrows[i]->dev);
470 473 }
471 474 }
472 475 #endif
473 476  
... ... @@ -585,9 +588,12 @@
585 588 NULL
586 589 };
587 590  
588   -static void dimm_attr_release(struct device *device)
  591 +static void dimm_attr_release(struct device *dev)
589 592 {
590   - debugf1("Releasing dimm device %s\n", dev_name(device));
  593 + struct dimm_info *dimm = container_of(dev, struct dimm_info, dev);
  594 +
  595 + debugf1("Releasing dimm device %s\n", dev_name(dev));
  596 + kfree(dimm);
591 597 }
592 598  
593 599 static struct device_type dimm_attr_type = {
594 600  
... ... @@ -641,13 +647,13 @@
641 647 mci->ce_noinfo_count = 0;
642 648  
643 649 for (row = 0; row < mci->nr_csrows; row++) {
644   - struct csrow_info *ri = &mci->csrows[row];
  650 + struct csrow_info *ri = mci->csrows[row];
645 651  
646 652 ri->ue_count = 0;
647 653 ri->ce_count = 0;
648 654  
649 655 for (chan = 0; chan < ri->nr_channels; chan++)
650   - ri->channels[chan].ce_count = 0;
  656 + ri->channels[chan]->ce_count = 0;
651 657 }
652 658  
653 659 cnt = 1;
654 660  
... ... @@ -779,10 +785,10 @@
779 785 int total_pages = 0, csrow_idx, j;
780 786  
781 787 for (csrow_idx = 0; csrow_idx < mci->nr_csrows; csrow_idx++) {
782   - struct csrow_info *csrow = &mci->csrows[csrow_idx];
  788 + struct csrow_info *csrow = mci->csrows[csrow_idx];
783 789  
784 790 for (j = 0; j < csrow->nr_channels; j++) {
785   - struct dimm_info *dimm = csrow->channels[j].dimm;
  791 + struct dimm_info *dimm = csrow->channels[j]->dimm;
786 792  
787 793 total_pages += dimm->nr_pages;
788 794 }
789 795  
... ... @@ -889,9 +895,12 @@
889 895 NULL
890 896 };
891 897  
892   -static void mci_attr_release(struct device *device)
  898 +static void mci_attr_release(struct device *dev)
893 899 {
894   - debugf1("Releasing mci device %s\n", dev_name(device));
  900 + struct mem_ctl_info *mci = container_of(dev, struct mem_ctl_info, dev);
  901 +
  902 + debugf1("Releasing csrow device %s\n", dev_name(dev));
  903 + kfree(mci);
895 904 }
896 905  
897 906 static struct device_type mci_attr_type = {
898 907  
899 908  
900 909  
... ... @@ -950,29 +959,28 @@
950 959 {
951 960 int i, err;
952 961  
953   - debugf0("%s() idx=%d\n", __func__, mci->mc_idx);
  962 + /*
  963 + * The memory controller needs its own bus, in order to avoid
  964 + * namespace conflicts at /sys/bus/edac.
  965 + */
  966 + mci->bus.name = kasprintf(GFP_KERNEL, "mc%d", mci->mc_idx);
  967 + if (!mci->bus.name)
  968 + return -ENOMEM;
  969 + debugf0("creating bus %s\n",mci->bus.name);
  970 + err = bus_register(&mci->bus);
  971 + if (err < 0)
  972 + return err;
954 973  
955 974 /* get the /sys/devices/system/edac subsys reference */
956   -
957 975 mci->dev.type = &mci_attr_type;
958 976 device_initialize(&mci->dev);
959 977  
960   - mci->dev.parent = &mci_pdev;
  978 + mci->dev.parent = mci_pdev;
961 979 mci->dev.bus = &mci->bus;
962 980 dev_set_name(&mci->dev, "mc%d", mci->mc_idx);
963 981 dev_set_drvdata(&mci->dev, mci);
964 982 pm_runtime_forbid(&mci->dev);
965 983  
966   - /*
967   - * The memory controller needs its own bus, in order to avoid
968   - * namespace conflicts at /sys/bus/edac.
969   - */
970   - debugf0("creating bus %s\n",mci->bus.name);
971   - mci->bus.name = kstrdup(dev_name(&mci->dev), GFP_KERNEL);
972   - err = bus_register(&mci->bus);
973   - if (err < 0)
974   - return err;
975   -
976 984 debugf0("%s(): creating device %s\n", __func__,
977 985 dev_name(&mci->dev));
978 986 err = device_add(&mci->dev);
... ... @@ -986,7 +994,7 @@
986 994 * Create the dimm/rank devices
987 995 */
988 996 for (i = 0; i < mci->tot_dimms; i++) {
989   - struct dimm_info *dimm = &mci->dimms[i];
  997 + struct dimm_info *dimm = mci->dimms[i];
990 998 /* Only expose populated DIMMs */
991 999 if (dimm->nr_pages == 0)
992 1000 continue;
... ... @@ -1023,7 +1031,7 @@
1023 1031  
1024 1032 fail:
1025 1033 for (i--; i >= 0; i--) {
1026   - struct dimm_info *dimm = &mci->dimms[i];
  1034 + struct dimm_info *dimm = mci->dimms[i];
1027 1035 if (dimm->nr_pages == 0)
1028 1036 continue;
1029 1037 put_device(&dimm->dev);
... ... @@ -1053,7 +1061,7 @@
1053 1061 #endif
1054 1062  
1055 1063 for (i = 0; i < mci->tot_dimms; i++) {
1056   - struct dimm_info *dimm = &mci->dimms[i];
  1064 + struct dimm_info *dimm = mci->dimms[i];
1057 1065 if (dimm->nr_pages == 0)
1058 1066 continue;
1059 1067 debugf0("%s(): removing device %s\n", __func__,
1060 1068  
... ... @@ -1072,9 +1080,15 @@
1072 1080 kfree(mci->bus.name);
1073 1081 }
1074 1082  
1075   -static void mc_attr_release(struct device *device)
  1083 +static void mc_attr_release(struct device *dev)
1076 1084 {
1077   - debugf1("Releasing device %s\n", dev_name(device));
  1085 + /*
  1086 + * There's no container structure here, as this is just the mci
  1087 + * parent device, used to create the /sys/devices/mc sysfs node.
  1088 + * So, there are no attributes on it.
  1089 + */
  1090 + debugf1("Releasing device %s\n", dev_name(dev));
  1091 + kfree(dev);
1078 1092 }
1079 1093  
1080 1094 static struct device_type mc_attr_type = {
1081 1095  
1082 1096  
1083 1097  
... ... @@ -1095,22 +1109,26 @@
1095 1109 return -EINVAL;
1096 1110 }
1097 1111  
1098   - mci_pdev.bus = edac_subsys;
1099   - mci_pdev.type = &mc_attr_type;
1100   - device_initialize(&mci_pdev);
1101   - dev_set_name(&mci_pdev, "mc");
  1112 + mci_pdev = kzalloc(sizeof(*mci_pdev), GFP_KERNEL);
1102 1113  
1103   - err = device_add(&mci_pdev);
  1114 + mci_pdev->bus = edac_subsys;
  1115 + mci_pdev->type = &mc_attr_type;
  1116 + device_initialize(mci_pdev);
  1117 + dev_set_name(mci_pdev, "mc");
  1118 +
  1119 + err = device_add(mci_pdev);
1104 1120 if (err < 0)
1105 1121 return err;
1106 1122  
  1123 + debugf0("device %s created\n", dev_name(mci_pdev));
  1124 +
1107 1125 return 0;
1108 1126 }
1109 1127  
1110 1128 void __exit edac_mc_sysfs_exit(void)
1111 1129 {
1112   - put_device(&mci_pdev);
1113   - device_del(&mci_pdev);
  1130 + put_device(mci_pdev);
  1131 + device_del(mci_pdev);
1114 1132 edac_put_sysfs_subsys();
1115 1133 }
drivers/edac/i3000_edac.c
... ... @@ -236,7 +236,7 @@
236 236 int row, multi_chan, channel;
237 237 unsigned long pfn, offset;
238 238  
239   - multi_chan = mci->csrows[0].nr_channels - 1;
  239 + multi_chan = mci->csrows[0]->nr_channels - 1;
240 240  
241 241 if (!(info->errsts & I3000_ERRSTS_BITS))
242 242 return 0;
... ... @@ -393,7 +393,7 @@
393 393 for (last_cumul_size = i = 0; i < mci->nr_csrows; i++) {
394 394 u8 value;
395 395 u32 cumul_size;
396   - struct csrow_info *csrow = &mci->csrows[i];
  396 + struct csrow_info *csrow = mci->csrows[i];
397 397  
398 398 value = drb[i];
399 399 cumul_size = value << (I3000_DRB_SHIFT - PAGE_SHIFT);
... ... @@ -410,7 +410,7 @@
410 410 last_cumul_size = cumul_size;
411 411  
412 412 for (j = 0; j < nr_channels; j++) {
413   - struct dimm_info *dimm = csrow->channels[j].dimm;
  413 + struct dimm_info *dimm = csrow->channels[j]->dimm;
414 414  
415 415 dimm->nr_pages = nr_pages / nr_channels;
416 416 dimm->grain = I3000_DEAP_GRAIN;
drivers/edac/i3200_edac.c
... ... @@ -379,7 +379,7 @@
379 379 */
380 380 for (i = 0; i < mci->nr_csrows; i++) {
381 381 unsigned long nr_pages;
382   - struct csrow_info *csrow = &mci->csrows[i];
  382 + struct csrow_info *csrow = mci->csrows[i];
383 383  
384 384 nr_pages = drb_to_nr_pages(drbs, stacked,
385 385 i / I3200_RANKS_PER_CHANNEL,
... ... @@ -389,7 +389,7 @@
389 389 continue;
390 390  
391 391 for (j = 0; j < nr_channels; j++) {
392   - struct dimm_info *dimm = csrow->channels[j].dimm;
  392 + struct dimm_info *dimm = csrow->channels[j]->dimm;
393 393  
394 394 dimm->nr_pages = nr_pages / nr_channels;
395 395 dimm->grain = nr_pages << PAGE_SHIFT;
drivers/edac/i5400_edac.c
... ... @@ -1203,8 +1203,8 @@
1203 1203  
1204 1204 size_mb = pvt->dimm_info[slot][channel].megabytes;
1205 1205  
1206   - debugf2("%s: dimm%zd (branch %d channel %d slot %d): %d.%03d GB\n",
1207   - __func__, dimm - mci->dimms,
  1206 + debugf2("%s: dimm (branch %d channel %d slot %d): %d.%03d GB\n",
  1207 + __func__,
1208 1208 channel / 2, channel % 2, slot,
1209 1209 size_mb / 1000, size_mb % 1000);
1210 1210  
... ... @@ -1227,7 +1227,7 @@
1227 1227 * With such single-DIMM mode, the SDCC algorithm degrades to SECDEC+.
1228 1228 */
1229 1229 if (ndimms == 1)
1230   - mci->dimms[0].edac_mode = EDAC_SECDED;
  1230 + mci->dimms[0]->edac_mode = EDAC_SECDED;
1231 1231  
1232 1232 return (ndimms == 0);
1233 1233 }
drivers/edac/i82443bxgx_edac.c
... ... @@ -197,8 +197,8 @@
197 197 pci_read_config_byte(pdev, I82443BXGX_DRAMC, &dramc);
198 198 row_high_limit_last = 0;
199 199 for (index = 0; index < mci->nr_csrows; index++) {
200   - csrow = &mci->csrows[index];
201   - dimm = csrow->channels[0].dimm;
  200 + csrow = mci->csrows[index];
  201 + dimm = csrow->channels[0]->dimm;
202 202  
203 203 pci_read_config_byte(pdev, I82443BXGX_DRB + index, &drbar);
204 204 debugf1("MC%d: %s: %s() Row=%d DRB = %#0x\n",
drivers/edac/i82860_edac.c
... ... @@ -116,7 +116,7 @@
116 116  
117 117 info->eap >>= PAGE_SHIFT;
118 118 row = edac_mc_find_csrow_by_page(mci, info->eap);
119   - dimm = mci->csrows[row].channels[0].dimm;
  119 + dimm = mci->csrows[row]->channels[0]->dimm;
120 120  
121 121 if (info->errsts & 0x0002)
122 122 edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci,
... ... @@ -161,8 +161,8 @@
161 161 * in all eight rows.
162 162 */
163 163 for (index = 0; index < mci->nr_csrows; index++) {
164   - csrow = &mci->csrows[index];
165   - dimm = csrow->channels[0].dimm;
  164 + csrow = mci->csrows[index];
  165 + dimm = csrow->channels[0]->dimm;
166 166  
167 167 pci_read_config_word(pdev, I82860_GBA + index * 2, &value);
168 168 cumul_size = (value & I82860_GBA_MASK) <<
drivers/edac/i82875p_edac.c
... ... @@ -227,7 +227,7 @@
227 227 {
228 228 int row, multi_chan;
229 229  
230   - multi_chan = mci->csrows[0].nr_channels - 1;
  230 + multi_chan = mci->csrows[0]->nr_channels - 1;
231 231  
232 232 if (!(info->errsts & 0x0081))
233 233 return 0;
... ... @@ -367,7 +367,7 @@
367 367 */
368 368  
369 369 for (index = 0; index < mci->nr_csrows; index++) {
370   - csrow = &mci->csrows[index];
  370 + csrow = mci->csrows[index];
371 371  
372 372 value = readb(ovrfl_window + I82875P_DRB + index);
373 373 cumul_size = value << (I82875P_DRB_SHIFT - PAGE_SHIFT);
... ... @@ -382,7 +382,7 @@
382 382 last_cumul_size = cumul_size;
383 383  
384 384 for (j = 0; j < nr_chans; j++) {
385   - dimm = csrow->channels[j].dimm;
  385 + dimm = csrow->channels[j]->dimm;
386 386  
387 387 dimm->nr_pages = nr_pages / nr_chans;
388 388 dimm->grain = 1 << 12; /* I82875P_EAP has 4KiB reolution */
drivers/edac/i82975x_edac.c
... ... @@ -308,10 +308,10 @@
308 308 (info->xeap & 1) ? 1 : 0, info->eap, (unsigned int) page);
309 309 return 0;
310 310 }
311   - chan = (mci->csrows[row].nr_channels == 1) ? 0 : info->eap & 1;
  311 + chan = (mci->csrows[row]->nr_channels == 1) ? 0 : info->eap & 1;
312 312 offst = info->eap
313 313 & ((1 << PAGE_SHIFT) -
314   - (1 << mci->csrows[row].channels[chan].dimm->grain));
  314 + (1 << mci->csrows[row]->channels[chan]->dimm->grain));
315 315  
316 316 if (info->errsts & 0x0002)
317 317 edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci,
... ... @@ -394,7 +394,7 @@
394 394 */
395 395  
396 396 for (index = 0; index < mci->nr_csrows; index++) {
397   - csrow = &mci->csrows[index];
  397 + csrow = mci->csrows[index];
398 398  
399 399 value = readb(mch_window + I82975X_DRB + index +
400 400 ((index >= 4) ? 0x80 : 0));
401 401  
... ... @@ -421,10 +421,10 @@
421 421 */
422 422 dtype = i82975x_dram_type(mch_window, index);
423 423 for (chan = 0; chan < csrow->nr_channels; chan++) {
424   - dimm = mci->csrows[index].channels[chan].dimm;
  424 + dimm = mci->csrows[index]->channels[chan]->dimm;
425 425  
426 426 dimm->nr_pages = nr_pages / csrow->nr_channels;
427   - strncpy(csrow->channels[chan].dimm->label,
  427 + strncpy(csrow->channels[chan]->dimm->label,
428 428 labels[(index >> 1) + (chan * 2)],
429 429 EDAC_MC_LABEL_LEN);
430 430 dimm->grain = 1 << 7; /* 128Byte cache-line resolution */
drivers/edac/mpc85xx_edac.c
... ... @@ -825,7 +825,7 @@
825 825 pfn = err_addr >> PAGE_SHIFT;
826 826  
827 827 for (row_index = 0; row_index < mci->nr_csrows; row_index++) {
828   - csrow = &mci->csrows[row_index];
  828 + csrow = mci->csrows[row_index];
829 829 if ((pfn >= csrow->first_page) && (pfn <= csrow->last_page))
830 830 break;
831 831 }
... ... @@ -945,8 +945,8 @@
945 945 u32 start;
946 946 u32 end;
947 947  
948   - csrow = &mci->csrows[index];
949   - dimm = csrow->channels[0].dimm;
  948 + csrow = mci->csrows[index];
  949 + dimm = csrow->channels[0]->dimm;
950 950  
951 951 cs_bnds = in_be32(pdata->mc_vbase + MPC85XX_MC_CS_BNDS_0 +
952 952 (index * MPC85XX_MC_CS_BNDS_OFS));
drivers/edac/mv64x60_edac.c
... ... @@ -670,8 +670,8 @@
670 670  
671 671 ctl = in_le32(pdata->mc_vbase + MV64X60_SDRAM_CONFIG);
672 672  
673   - csrow = &mci->csrows[0];
674   - dimm = csrow->channels[0].dimm;
  673 + csrow = mci->csrows[0];
  674 + dimm = csrow->channels[0]->dimm;
675 675  
676 676 dimm->nr_pages = pdata->total_mem >> PAGE_SHIFT;
677 677 dimm->grain = 8;
drivers/edac/pasemi_edac.c
... ... @@ -111,14 +111,14 @@
111 111 if (errsta & (MCDEBUG_ERRSTA_MBE_STATUS |
112 112 MCDEBUG_ERRSTA_RFL_STATUS)) {
113 113 edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci,
114   - mci->csrows[cs].first_page, 0, 0,
  114 + mci->csrows[cs]->first_page, 0, 0,
115 115 cs, 0, -1, mci->ctl_name, "", NULL);
116 116 }
117 117  
118 118 /* correctable/single-bit errors */
119 119 if (errsta & MCDEBUG_ERRSTA_SBE_STATUS)
120 120 edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci,
121   - mci->csrows[cs].first_page, 0, 0,
  121 + mci->csrows[cs]->first_page, 0, 0,
122 122 cs, 0, -1, mci->ctl_name, "", NULL);
123 123 }
124 124  
... ... @@ -141,8 +141,8 @@
141 141 int index;
142 142  
143 143 for (index = 0; index < mci->nr_csrows; index++) {
144   - csrow = &mci->csrows[index];
145   - dimm = csrow->channels[0].dimm;
  144 + csrow = mci->csrows[index];
  145 + dimm = csrow->channels[0]->dimm;
146 146  
147 147 pci_read_config_dword(pdev,
148 148 MCDRAM_RANKCFG + (index * 12),
drivers/edac/r82600_edac.c
... ... @@ -230,8 +230,8 @@
230 230 row_high_limit_last = 0;
231 231  
232 232 for (index = 0; index < mci->nr_csrows; index++) {
233   - csrow = &mci->csrows[index];
234   - dimm = csrow->channels[0].dimm;
  233 + csrow = mci->csrows[index];
  234 + dimm = csrow->channels[0]->dimm;
235 235  
236 236 /* find the DRAM Chip Select Base address and mask */
237 237 pci_read_config_byte(pdev, R82600_DRBA + index, &drbar);
drivers/edac/tile_edac.c
... ... @@ -84,10 +84,10 @@
84 84 */
85 85 static int __devinit tile_edac_init_csrows(struct mem_ctl_info *mci)
86 86 {
87   - struct csrow_info *csrow = &mci->csrows[0];
  87 + struct csrow_info *csrow = mci->csrows[0];
88 88 struct tile_edac_priv *priv = mci->pvt_info;
89 89 struct mshim_mem_info mem_info;
90   - struct dimm_info *dimm = csrow->channels[0].dimm;
  90 + struct dimm_info *dimm = csrow->channels[0]->dimm;
91 91  
92 92 if (hv_dev_pread(priv->hv_devhdl, 0, (HV_VirtAddr)&mem_info,
93 93 sizeof(struct mshim_mem_info), MSHIM_MEM_INFO_OFF) !=
drivers/edac/x38_edac.c
... ... @@ -378,7 +378,7 @@
378 378 */
379 379 for (i = 0; i < mci->nr_csrows; i++) {
380 380 unsigned long nr_pages;
381   - struct csrow_info *csrow = &mci->csrows[i];
  381 + struct csrow_info *csrow = mci->csrows[i];
382 382  
383 383 nr_pages = drb_to_nr_pages(drbs, stacked,
384 384 i / X38_RANKS_PER_CHANNEL,
... ... @@ -388,7 +388,7 @@
388 388 continue;
389 389  
390 390 for (j = 0; j < x38_channel_num; j++) {
391   - struct dimm_info *dimm = csrow->channels[j].dimm;
  391 + struct dimm_info *dimm = csrow->channels[j]->dimm;
392 392  
393 393 dimm->nr_pages = nr_pages / x38_channel_num;
394 394 dimm->grain = nr_pages << PAGE_SHIFT;
include/linux/edac.h
... ... @@ -412,23 +412,21 @@
412 412 #define EDAC_MAX_LAYERS 3
413 413  
414 414 /**
415   - * EDAC_DIMM_PTR - Macro responsible to find a pointer inside a pointer array
  415 + * EDAC_DIMM_OFF - Macro responsible to get a pointer offset inside a pointer array
416 416 * for the element given by [layer0,layer1,layer2] position
417 417 *
418 418 * @layers: a struct edac_mc_layer array, describing how many elements
419 419 * were allocated for each layer
420   - * @var: name of the var where we want to get the pointer
421   - * (like mci->dimms)
422 420 * @n_layers: Number of layers at the @layers array
423 421 * @layer0: layer0 position
424 422 * @layer1: layer1 position. Unused if n_layers < 2
425 423 * @layer2: layer2 position. Unused if n_layers < 3
426 424 *
427   - * For 1 layer, this macro returns &var[layer0]
  425 + * For 1 layer, this macro returns &var[layer0] - &var
428 426 * For 2 layers, this macro is similar to allocate a bi-dimensional array
429   - * and to return "&var[layer0][layer1]"
  427 + * and to return "&var[layer0][layer1] - &var"
430 428 * For 3 layers, this macro is similar to allocate a tri-dimensional array
431   - * and to return "&var[layer0][layer1][layer2]"
  429 + * and to return "&var[layer0][layer1][layer2] - &var"
432 430 *
433 431 * A loop could be used here to make it more generic, but, as we only have
434 432 * 3 layers, this is a little faster.
435 433  
436 434  
437 435  
438 436  
439 437  
... ... @@ -436,17 +434,46 @@
436 434 * a NULL is returned, causing an OOPS during the memory allocation routine,
437 435 * with would point to the developer that he's doing something wrong.
438 436 */
439   -#define EDAC_DIMM_PTR(layers, var, nlayers, layer0, layer1, layer2) ({ \
440   - typeof(var) __p; \
  437 +#define EDAC_DIMM_OFF(layers, nlayers, layer0, layer1, layer2) ({ \
  438 + int __i; \
441 439 if ((nlayers) == 1) \
442   - __p = &var[layer0]; \
  440 + __i = layer0; \
443 441 else if ((nlayers) == 2) \
444   - __p = &var[(layer1) + ((layers[1]).size * (layer0))]; \
  442 + __i = (layer1) + ((layers[1]).size * (layer0)); \
445 443 else if ((nlayers) == 3) \
446   - __p = &var[(layer2) + ((layers[2]).size * ((layer1) + \
447   - ((layers[1]).size * (layer0))))]; \
  444 + __i = (layer2) + ((layers[2]).size * ((layer1) + \
  445 + ((layers[1]).size * (layer0)))); \
448 446 else \
  447 + __i = -EINVAL; \
  448 + __i; \
  449 +})
  450 +
  451 +/**
  452 + * EDAC_DIMM_PTR - Macro responsible to get a pointer inside a pointer array
  453 + * for the element given by [layer0,layer1,layer2] position
  454 + *
  455 + * @layers: a struct edac_mc_layer array, describing how many elements
  456 + * were allocated for each layer
  457 + * @var: name of the var where we want to get the pointer
  458 + * (like mci->dimms)
  459 + * @n_layers: Number of layers at the @layers array
  460 + * @layer0: layer0 position
  461 + * @layer1: layer1 position. Unused if n_layers < 2
  462 + * @layer2: layer2 position. Unused if n_layers < 3
  463 + *
  464 + * For 1 layer, this macro returns &var[layer0]
  465 + * For 2 layers, this macro is similar to allocate a bi-dimensional array
  466 + * and to return "&var[layer0][layer1]"
  467 + * For 3 layers, this macro is similar to allocate a tri-dimensional array
  468 + * and to return "&var[layer0][layer1][layer2]"
  469 + */
  470 +#define EDAC_DIMM_PTR(layers, var, nlayers, layer0, layer1, layer2) ({ \
  471 + typeof(*var) __p; \
  472 + int ___i = EDAC_DIMM_OFF(layers, nlayers, layer0, layer1, layer2); \
  473 + if (___i < 0) \
449 474 __p = NULL; \
  475 + else \
  476 + __p = (var)[___i]; \
450 477 __p; \
451 478 })
452 479  
... ... @@ -486,8 +513,6 @@
486 513 * patches in this series will fix this issue.
487 514 */
488 515 struct rank_info {
489   - struct device dev;
490   -
491 516 int chan_idx;
492 517 struct csrow_info *csrow;
493 518 struct dimm_info *dimm;
... ... @@ -513,7 +538,7 @@
513 538  
514 539 /* channel information for this csrow */
515 540 u32 nr_channels;
516   - struct rank_info *channels;
  541 + struct rank_info **channels;
517 542 };
518 543  
519 544 /*
... ... @@ -572,7 +597,7 @@
572 597 unsigned long (*ctl_page_to_phys) (struct mem_ctl_info * mci,
573 598 unsigned long page);
574 599 int mc_idx;
575   - struct csrow_info *csrows;
  600 + struct csrow_info **csrows;
576 601 unsigned nr_csrows, num_cschannel;
577 602  
578 603 /*
... ... @@ -592,7 +617,7 @@
592 617 * DIMM info. Will eventually remove the entire csrows_info some day
593 618 */
594 619 unsigned tot_dimms;
595   - struct dimm_info *dimms;
  620 + struct dimm_info **dimms;
596 621  
597 622 /*
598 623 * FIXME - what about controllers on other busses? - IDs must be