aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2012-04-24 14:05:43 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-06-11 12:23:45 -0400
commitde3910eb79ac8c0f29a11224661c0ebaaf813039 (patch)
tree44584d6691588b2c18823260be0e44f0c9872d02
parente39f4ea9b01f137f9e6fa631f3e9088fb9175e91 (diff)
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>
-rw-r--r--drivers/edac/amd64_edac.c10
-rw-r--r--drivers/edac/amd76x_edac.c8
-rw-r--r--drivers/edac/cell_edac.c8
-rw-r--r--drivers/edac/cpc925_edac.c8
-rw-r--r--drivers/edac/e752x_edac.c4
-rw-r--r--drivers/edac/e7xxx_edac.c4
-rw-r--r--drivers/edac/edac_mc.c107
-rw-r--r--drivers/edac/edac_mc_sysfs.c126
-rw-r--r--drivers/edac/i3000_edac.c6
-rw-r--r--drivers/edac/i3200_edac.c4
-rw-r--r--drivers/edac/i5400_edac.c6
-rw-r--r--drivers/edac/i82443bxgx_edac.c4
-rw-r--r--drivers/edac/i82860_edac.c6
-rw-r--r--drivers/edac/i82875p_edac.c6
-rw-r--r--drivers/edac/i82975x_edac.c10
-rw-r--r--drivers/edac/mpc85xx_edac.c6
-rw-r--r--drivers/edac/mv64x60_edac.c4
-rw-r--r--drivers/edac/pasemi_edac.c8
-rw-r--r--drivers/edac/r82600_edac.c4
-rw-r--r--drivers/edac/tile_edac.c4
-rw-r--r--drivers/edac/x38_edac.c4
-rw-r--r--include/linux/edac.h59
22 files changed, 242 insertions, 164 deletions
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index 9905834b560..9fbced7f65e 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -2205,6 +2205,7 @@ static u32 amd64_csrow_nr_pages(struct amd64_pvt *pvt, u8 dct, int csrow_nr)
2205static int init_csrows(struct mem_ctl_info *mci) 2205static int init_csrows(struct mem_ctl_info *mci)
2206{ 2206{
2207 struct csrow_info *csrow; 2207 struct csrow_info *csrow;
2208 struct dimm_info *dimm;
2208 struct amd64_pvt *pvt = mci->pvt_info; 2209 struct amd64_pvt *pvt = mci->pvt_info;
2209 u64 base, mask; 2210 u64 base, mask;
2210 u32 val; 2211 u32 val;
@@ -2222,7 +2223,7 @@ static int init_csrows(struct mem_ctl_info *mci)
2222 !!(val & NBCFG_CHIPKILL), !!(val & NBCFG_ECC_ENABLE)); 2223 !!(val & NBCFG_CHIPKILL), !!(val & NBCFG_ECC_ENABLE));
2223 2224
2224 for_each_chip_select(i, 0, pvt) { 2225 for_each_chip_select(i, 0, pvt) {
2225 csrow = &mci->csrows[i]; 2226 csrow = mci->csrows[i];
2226 2227
2227 if (!csrow_enabled(i, 0, pvt) && !csrow_enabled(i, 1, pvt)) { 2228 if (!csrow_enabled(i, 0, pvt) && !csrow_enabled(i, 1, pvt)) {
2228 debugf1("----CSROW %d EMPTY for node %d\n", i, 2229 debugf1("----CSROW %d EMPTY for node %d\n", i,
@@ -2257,9 +2258,10 @@ static int init_csrows(struct mem_ctl_info *mci)
2257 edac_mode = EDAC_NONE; 2258 edac_mode = EDAC_NONE;
2258 2259
2259 for (j = 0; j < pvt->channel_count; j++) { 2260 for (j = 0; j < pvt->channel_count; j++) {
2260 csrow->channels[j].dimm->mtype = mtype; 2261 dimm = csrow->channels[j]->dimm;
2261 csrow->channels[j].dimm->edac_mode = edac_mode; 2262 dimm->mtype = mtype;
2262 csrow->channels[j].dimm->nr_pages = nr_pages; 2263 dimm->edac_mode = edac_mode;
2264 dimm->nr_pages = nr_pages;
2263 } 2265 }
2264 } 2266 }
2265 2267
diff --git a/drivers/edac/amd76x_edac.c b/drivers/edac/amd76x_edac.c
index 7439786f3be..a0c9f82875c 100644
--- a/drivers/edac/amd76x_edac.c
+++ b/drivers/edac/amd76x_edac.c
@@ -146,7 +146,7 @@ static int amd76x_process_error_info(struct mem_ctl_info *mci,
146 if (handle_errors) { 146 if (handle_errors) {
147 row = (info->ecc_mode_status >> 4) & 0xf; 147 row = (info->ecc_mode_status >> 4) & 0xf;
148 edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, 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 row, 0, -1, 150 row, 0, -1,
151 mci->ctl_name, "", NULL); 151 mci->ctl_name, "", NULL);
152 } 152 }
@@ -161,7 +161,7 @@ static int amd76x_process_error_info(struct mem_ctl_info *mci,
161 if (handle_errors) { 161 if (handle_errors) {
162 row = info->ecc_mode_status & 0xf; 162 row = info->ecc_mode_status & 0xf;
163 edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, 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 row, 0, -1, 165 row, 0, -1,
166 mci->ctl_name, "", NULL); 166 mci->ctl_name, "", NULL);
167 } 167 }
@@ -194,8 +194,8 @@ static void amd76x_init_csrows(struct mem_ctl_info *mci, struct pci_dev *pdev,
194 int index; 194 int index;
195 195
196 for (index = 0; index < mci->nr_csrows; index++) { 196 for (index = 0; index < mci->nr_csrows; index++) {
197 csrow = &mci->csrows[index]; 197 csrow = mci->csrows[index];
198 dimm = csrow->channels[0].dimm; 198 dimm = csrow->channels[0]->dimm;
199 199
200 /* find the DRAM Chip Select Base address and mask */ 200 /* find the DRAM Chip Select Base address and mask */
201 pci_read_config_dword(pdev, 201 pci_read_config_dword(pdev,
diff --git a/drivers/edac/cell_edac.c b/drivers/edac/cell_edac.c
index 2e5b95374dc..478d8ee434d 100644
--- a/drivers/edac/cell_edac.c
+++ b/drivers/edac/cell_edac.c
@@ -33,7 +33,7 @@ struct cell_edac_priv
33static void cell_edac_count_ce(struct mem_ctl_info *mci, int chan, u64 ar) 33static void cell_edac_count_ce(struct mem_ctl_info *mci, int chan, u64 ar)
34{ 34{
35 struct cell_edac_priv *priv = mci->pvt_info; 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 unsigned long address, pfn, offset, syndrome; 37 unsigned long address, pfn, offset, syndrome;
38 38
39 dev_dbg(mci->pdev, "ECC CE err on node %d, channel %d, ar = 0x%016llx\n", 39 dev_dbg(mci->pdev, "ECC CE err on node %d, channel %d, ar = 0x%016llx\n",
@@ -56,7 +56,7 @@ static void cell_edac_count_ce(struct mem_ctl_info *mci, int chan, u64 ar)
56static void cell_edac_count_ue(struct mem_ctl_info *mci, int chan, u64 ar) 56static void cell_edac_count_ue(struct mem_ctl_info *mci, int chan, u64 ar)
57{ 57{
58 struct cell_edac_priv *priv = mci->pvt_info; 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 unsigned long address, pfn, offset; 60 unsigned long address, pfn, offset;
61 61
62 dev_dbg(mci->pdev, "ECC UE err on node %d, channel %d, ar = 0x%016llx\n", 62 dev_dbg(mci->pdev, "ECC UE err on node %d, channel %d, ar = 0x%016llx\n",
@@ -126,7 +126,7 @@ static void cell_edac_check(struct mem_ctl_info *mci)
126 126
127static void __devinit cell_edac_init_csrows(struct mem_ctl_info *mci) 127static 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 struct dimm_info *dimm; 130 struct dimm_info *dimm;
131 struct cell_edac_priv *priv = mci->pvt_info; 131 struct cell_edac_priv *priv = mci->pvt_info;
132 struct device_node *np; 132 struct device_node *np;
@@ -150,7 +150,7 @@ static void __devinit cell_edac_init_csrows(struct mem_ctl_info *mci)
150 csrow->last_page = csrow->first_page + nr_pages - 1; 150 csrow->last_page = csrow->first_page + nr_pages - 1;
151 151
152 for (j = 0; j < csrow->nr_channels; j++) { 152 for (j = 0; j < csrow->nr_channels; j++) {
153 dimm = csrow->channels[j].dimm; 153 dimm = csrow->channels[j]->dimm;
154 dimm->mtype = MEM_XDR; 154 dimm->mtype = MEM_XDR;
155 dimm->edac_mode = EDAC_SECDED; 155 dimm->edac_mode = EDAC_SECDED;
156 dimm->nr_pages = nr_pages / csrow->nr_channels; 156 dimm->nr_pages = nr_pages / csrow->nr_channels;
diff --git a/drivers/edac/cpc925_edac.c b/drivers/edac/cpc925_edac.c
index 3510aa44629..534491d6715 100644
--- a/drivers/edac/cpc925_edac.c
+++ b/drivers/edac/cpc925_edac.c
@@ -348,7 +348,7 @@ static void cpc925_init_csrows(struct mem_ctl_info *mci)
348 if (bba == 0) 348 if (bba == 0)
349 continue; /* not populated */ 349 continue; /* not populated */
350 350
351 csrow = &mci->csrows[index]; 351 csrow = mci->csrows[index];
352 352
353 row_size = bba * (1UL << 28); /* 256M */ 353 row_size = bba * (1UL << 28); /* 256M */
354 csrow->first_page = last_nr_pages; 354 csrow->first_page = last_nr_pages;
@@ -380,7 +380,7 @@ static void cpc925_init_csrows(struct mem_ctl_info *mci)
380 break; 380 break;
381 } 381 }
382 for (j = 0; j < csrow->nr_channels; j++) { 382 for (j = 0; j < csrow->nr_channels; j++) {
383 dimm = csrow->channels[j].dimm; 383 dimm = csrow->channels[j]->dimm;
384 dimm->nr_pages = nr_pages / csrow->nr_channels; 384 dimm->nr_pages = nr_pages / csrow->nr_channels;
385 dimm->mtype = MEM_RDDR; 385 dimm->mtype = MEM_RDDR;
386 dimm->edac_mode = EDAC_SECDED; 386 dimm->edac_mode = EDAC_SECDED;
@@ -463,7 +463,7 @@ static void cpc925_mc_get_pfn(struct mem_ctl_info *mci, u32 mear,
463 *csrow = rank; 463 *csrow = rank;
464 464
465#ifdef CONFIG_EDAC_DEBUG 465#ifdef CONFIG_EDAC_DEBUG
466 if (mci->csrows[rank].first_page == 0) { 466 if (mci->csrows[rank]->first_page == 0) {
467 cpc925_mc_printk(mci, KERN_ERR, "ECC occurs in a " 467 cpc925_mc_printk(mci, KERN_ERR, "ECC occurs in a "
468 "non-populated csrow, broken hardware?\n"); 468 "non-populated csrow, broken hardware?\n");
469 return; 469 return;
@@ -471,7 +471,7 @@ static void cpc925_mc_get_pfn(struct mem_ctl_info *mci, u32 mear,
471#endif 471#endif
472 472
473 /* Revert csrow number */ 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 /* Revert column address */ 476 /* Revert column address */
477 col += bcnt; 477 col += bcnt;
diff --git a/drivers/edac/e752x_edac.c b/drivers/edac/e752x_edac.c
index d1142ed8bd8..7cde7f1aafb 100644
--- a/drivers/edac/e752x_edac.c
+++ b/drivers/edac/e752x_edac.c
@@ -1096,7 +1096,7 @@ static void e752x_init_csrows(struct mem_ctl_info *mci, struct pci_dev *pdev,
1096 for (last_cumul_size = index = 0; index < mci->nr_csrows; index++) { 1096 for (last_cumul_size = index = 0; index < mci->nr_csrows; index++) {
1097 /* mem_dev 0=x8, 1=x4 */ 1097 /* mem_dev 0=x8, 1=x4 */
1098 mem_dev = (dra >> (index * 4 + 2)) & 0x3; 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 mem_dev = (mem_dev == 2); 1101 mem_dev = (mem_dev == 2);
1102 pci_read_config_byte(pdev, E752X_DRB + index, &value); 1102 pci_read_config_byte(pdev, E752X_DRB + index, &value);
@@ -1127,7 +1127,7 @@ static void e752x_init_csrows(struct mem_ctl_info *mci, struct pci_dev *pdev,
1127 } else 1127 } else
1128 edac_mode = EDAC_NONE; 1128 edac_mode = EDAC_NONE;
1129 for (i = 0; i < csrow->nr_channels; i++) { 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 debugf3("Initializing rank at (%i,%i)\n", index, i); 1132 debugf3("Initializing rank at (%i,%i)\n", index, i);
1133 dimm->nr_pages = nr_pages / csrow->nr_channels; 1133 dimm->nr_pages = nr_pages / csrow->nr_channels;
diff --git a/drivers/edac/e7xxx_edac.c b/drivers/edac/e7xxx_edac.c
index bab31aab983..c6c0ebaca37 100644
--- a/drivers/edac/e7xxx_edac.c
+++ b/drivers/edac/e7xxx_edac.c
@@ -378,7 +378,7 @@ static void e7xxx_init_csrows(struct mem_ctl_info *mci, struct pci_dev *pdev,
378 for (index = 0; index < mci->nr_csrows; index++) { 378 for (index = 0; index < mci->nr_csrows; index++) {
379 /* mem_dev 0=x8, 1=x4 */ 379 /* mem_dev 0=x8, 1=x4 */
380 mem_dev = (dra >> (index * 4 + 3)) & 0x1; 380 mem_dev = (dra >> (index * 4 + 3)) & 0x1;
381 csrow = &mci->csrows[index]; 381 csrow = mci->csrows[index];
382 382
383 pci_read_config_byte(pdev, E7XXX_DRB + index, &value); 383 pci_read_config_byte(pdev, E7XXX_DRB + index, &value);
384 /* convert a 64 or 32 MiB DRB to a page size. */ 384 /* convert a 64 or 32 MiB DRB to a page size. */
@@ -409,7 +409,7 @@ static void e7xxx_init_csrows(struct mem_ctl_info *mci, struct pci_dev *pdev,
409 edac_mode = EDAC_NONE; 409 edac_mode = EDAC_NONE;
410 410
411 for (j = 0; j < drc_chan + 1; j++) { 411 for (j = 0; j < drc_chan + 1; j++) {
412 dimm = csrow->channels[j].dimm; 412 dimm = csrow->channels[j]->dimm;
413 413
414 dimm->nr_pages = nr_pages / (drc_chan + 1); 414 dimm->nr_pages = nr_pages / (drc_chan + 1);
415 dimm->grain = 1 << 12; /* 4KiB - resolution of CELOG */ 415 dimm->grain = 1 << 12; /* 4KiB - resolution of CELOG */
diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c
index 4a6fdc03740..db2ba31ba2b 100644
--- a/drivers/edac/edac_mc.c
+++ b/drivers/edac/edac_mc.c
@@ -210,15 +210,15 @@ struct mem_ctl_info *edac_mc_alloc(unsigned mc_num,
210{ 210{
211 struct mem_ctl_info *mci; 211 struct mem_ctl_info *mci;
212 struct edac_mc_layer *layer; 212 struct edac_mc_layer *layer;
213 struct csrow_info *csi, *csr; 213 struct csrow_info *csr;
214 struct rank_info *chi, *chp, *chan; 214 struct rank_info *chan;
215 struct dimm_info *dimm; 215 struct dimm_info *dimm;
216 u32 *ce_per_layer[EDAC_MAX_LAYERS], *ue_per_layer[EDAC_MAX_LAYERS]; 216 u32 *ce_per_layer[EDAC_MAX_LAYERS], *ue_per_layer[EDAC_MAX_LAYERS];
217 unsigned pos[EDAC_MAX_LAYERS]; 217 unsigned pos[EDAC_MAX_LAYERS];
218 unsigned size, tot_dimms = 1, count = 1; 218 unsigned size, tot_dimms = 1, count = 1;
219 unsigned tot_csrows = 1, tot_channels = 1, tot_errcount = 0; 219 unsigned tot_csrows = 1, tot_channels = 1, tot_errcount = 0;
220 void *pvt, *p, *ptr = NULL; 220 void *pvt, *p, *ptr = NULL;
221 int i, j, row, chn, n, len; 221 int i, j, row, chn, n, len, off;
222 bool per_rank = false; 222 bool per_rank = false;
223 223
224 BUG_ON(n_layers > EDAC_MAX_LAYERS || n_layers == 0); 224 BUG_ON(n_layers > EDAC_MAX_LAYERS || n_layers == 0);
@@ -244,9 +244,6 @@ struct mem_ctl_info *edac_mc_alloc(unsigned mc_num,
244 */ 244 */
245 mci = edac_align_ptr(&ptr, sizeof(*mci), 1); 245 mci = edac_align_ptr(&ptr, sizeof(*mci), 1);
246 layer = edac_align_ptr(&ptr, sizeof(*layer), n_layers); 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 for (i = 0; i < n_layers; i++) { 247 for (i = 0; i < n_layers; i++) {
251 count *= layers[i].size; 248 count *= layers[i].size;
252 debugf4("%s: errcount layer %d size %d\n", __func__, i, count); 249 debugf4("%s: errcount layer %d size %d\n", __func__, i, count);
@@ -264,6 +261,7 @@ struct mem_ctl_info *edac_mc_alloc(unsigned mc_num,
264 tot_dimms, 261 tot_dimms,
265 per_rank ? "ranks" : "dimms", 262 per_rank ? "ranks" : "dimms",
266 tot_csrows * tot_channels); 263 tot_csrows * tot_channels);
264
267 mci = kzalloc(size, GFP_KERNEL); 265 mci = kzalloc(size, GFP_KERNEL);
268 if (mci == NULL) 266 if (mci == NULL)
269 return NULL; 267 return NULL;
@@ -272,9 +270,6 @@ struct mem_ctl_info *edac_mc_alloc(unsigned mc_num,
272 * rather than an imaginary chunk of memory located at address 0. 270 * rather than an imaginary chunk of memory located at address 0.
273 */ 271 */
274 layer = (struct edac_mc_layer *)(((char *)mci) + ((unsigned long)layer)); 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 for (i = 0; i < n_layers; i++) { 273 for (i = 0; i < n_layers; i++) {
279 mci->ce_per_layer[i] = (u32 *)((char *)mci + ((unsigned long)ce_per_layer[i])); 274 mci->ce_per_layer[i] = (u32 *)((char *)mci + ((unsigned long)ce_per_layer[i]));
280 mci->ue_per_layer[i] = (u32 *)((char *)mci + ((unsigned long)ue_per_layer[i])); 275 mci->ue_per_layer[i] = (u32 *)((char *)mci + ((unsigned long)ue_per_layer[i]));
@@ -283,8 +278,6 @@ struct mem_ctl_info *edac_mc_alloc(unsigned mc_num,
283 278
284 /* setup index and various internal pointers */ 279 /* setup index and various internal pointers */
285 mci->mc_idx = mc_num; 280 mci->mc_idx = mc_num;
286 mci->csrows = csi;
287 mci->dimms = dimm;
288 mci->tot_dimms = tot_dimms; 281 mci->tot_dimms = tot_dimms;
289 mci->pvt_info = pvt; 282 mci->pvt_info = pvt;
290 mci->n_layers = n_layers; 283 mci->n_layers = n_layers;
@@ -295,39 +288,60 @@ struct mem_ctl_info *edac_mc_alloc(unsigned mc_num,
295 mci->mem_is_per_rank = per_rank; 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 for (row = 0; row < tot_csrows; row++) { 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 csr->csrow_idx = row; 301 csr->csrow_idx = row;
303 csr->mci = mci; 302 csr->mci = mci;
304 csr->nr_channels = tot_channels; 303 csr->nr_channels = tot_channels;
305 chp = &chi[row * tot_channels]; 304 csr->channels = kcalloc(sizeof(*csr->channels), tot_channels,
306 csr->channels = chp; 305 GFP_KERNEL);
306 if (!csr->channels)
307 goto error;
307 308
308 for (chn = 0; chn < tot_channels; chn++) { 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 chan->chan_idx = chn; 314 chan->chan_idx = chn;
311 chan->csrow = csr; 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 memset(&pos, 0, sizeof(pos)); 326 memset(&pos, 0, sizeof(pos));
319 row = 0; 327 row = 0;
320 chn = 0; 328 chn = 0;
321 debugf4("%s: initializing %d %s\n", __func__, tot_dimms, 329 debugf4("%s: initializing %d %s\n", __func__, tot_dimms,
322 per_rank ? "ranks" : "dimms"); 330 per_rank ? "ranks" : "dimms");
323 for (i = 0; i < tot_dimms; i++) { 331 for (i = 0; i < tot_dimms; i++) {
324 chan = &csi[row].channels[chn]; 332 chan = mci->csrows[row]->channels[chn];
325 dimm = EDAC_DIMM_PTR(layer, mci->dimms, n_layers, 333 off = EDAC_DIMM_OFF(layer, n_layers, pos[0], pos[1], pos[2]);
326 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 dimm->mci = mci; 341 dimm->mci = mci;
328 342
329 debugf2("%s: %d: %s%zd (%d:%d:%d): row %d, chan %d\n", __func__, 343 debugf2("%s: %d: %s%i (%d:%d:%d): row %d, chan %d\n", __func__,
330 i, per_rank ? "rank" : "dimm", (dimm - mci->dimms), 344 i, per_rank ? "rank" : "dimm", off,
331 pos[0], pos[1], pos[2], row, chn); 345 pos[0], pos[1], pos[2], row, chn);
332 346
333 /* 347 /*
@@ -381,6 +395,28 @@ struct mem_ctl_info *edac_mc_alloc(unsigned mc_num,
381 */ 395 */
382 396
383 return mci; 397 return mci;
398
399error:
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}
385EXPORT_SYMBOL_GPL(edac_mc_alloc); 421EXPORT_SYMBOL_GPL(edac_mc_alloc);
386 422
@@ -393,10 +429,8 @@ void edac_mc_free(struct mem_ctl_info *mci)
393{ 429{
394 debugf1("%s()\n", __func__); 430 debugf1("%s()\n", __func__);
395 431
432 /* the mci instance is freed here, when the sysfs object is dropped */
396 edac_unregister_sysfs(mci); 433 edac_unregister_sysfs(mci);
397
398 /* free the mci instance memory here */
399 kfree(mci);
400} 434}
401EXPORT_SYMBOL_GPL(edac_mc_free); 435EXPORT_SYMBOL_GPL(edac_mc_free);
402 436
@@ -668,13 +702,12 @@ int edac_mc_add_mc(struct mem_ctl_info *mci)
668 for (i = 0; i < mci->nr_csrows; i++) { 702 for (i = 0; i < mci->nr_csrows; i++) {
669 int j; 703 int j;
670 704
671 edac_mc_dump_csrow(&mci->csrows[i]); 705 edac_mc_dump_csrow(mci->csrows[i]);
672 for (j = 0; j < mci->csrows[i].nr_channels; j++) 706 for (j = 0; j < mci->csrows[i]->nr_channels; j++)
673 edac_mc_dump_channel(&mci->csrows[i]. 707 edac_mc_dump_channel(mci->csrows[i]->channels[j]);
674 channels[j]);
675 } 708 }
676 for (i = 0; i < mci->tot_dimms; i++) 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#endif 712#endif
680 mutex_lock(&mem_ctls_mutex); 713 mutex_lock(&mem_ctls_mutex);
@@ -793,17 +826,17 @@ static void edac_mc_scrub_block(unsigned long page, unsigned long offset,
793/* FIXME - should return -1 */ 826/* FIXME - should return -1 */
794int edac_mc_find_csrow_by_page(struct mem_ctl_info *mci, unsigned long page) 827int 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 int row, i, j, n; 830 int row, i, j, n;
798 831
799 debugf1("MC%d: %s(): 0x%lx\n", mci->mc_idx, __func__, page); 832 debugf1("MC%d: %s(): 0x%lx\n", mci->mc_idx, __func__, page);
800 row = -1; 833 row = -1;
801 834
802 for (i = 0; i < mci->nr_csrows; i++) { 835 for (i = 0; i < mci->nr_csrows; i++) {
803 struct csrow_info *csrow = &csrows[i]; 836 struct csrow_info *csrow = csrows[i];
804 n = 0; 837 n = 0;
805 for (j = 0; j < csrow->nr_channels; j++) { 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 n += dimm->nr_pages; 840 n += dimm->nr_pages;
808 } 841 }
809 if (n == 0) 842 if (n == 0)
@@ -1062,7 +1095,7 @@ void edac_mc_handle_error(const enum hw_event_mc_err_type type,
1062 p = label; 1095 p = label;
1063 *p = '\0'; 1096 *p = '\0';
1064 for (i = 0; i < mci->tot_dimms; i++) { 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 if (top_layer >= 0 && top_layer != dimm->location[0]) 1100 if (top_layer >= 0 && top_layer != dimm->location[0])
1068 continue; 1101 continue;
@@ -1120,13 +1153,13 @@ void edac_mc_handle_error(const enum hw_event_mc_err_type type,
1120 strcpy(label, "unknown memory"); 1153 strcpy(label, "unknown memory");
1121 if (type == HW_EVENT_ERR_CORRECTED) { 1154 if (type == HW_EVENT_ERR_CORRECTED) {
1122 if (row >= 0) { 1155 if (row >= 0) {
1123 mci->csrows[row].ce_count++; 1156 mci->csrows[row]->ce_count++;
1124 if (chan >= 0) 1157 if (chan >= 0)
1125 mci->csrows[row].channels[chan].ce_count++; 1158 mci->csrows[row]->channels[chan]->ce_count++;
1126 } 1159 }
1127 } else 1160 } else
1128 if (row >= 0) 1161 if (row >= 0)
1129 mci->csrows[row].ue_count++; 1162 mci->csrows[row]->ue_count++;
1130 } 1163 }
1131 1164
1132 /* Fill the RAM location data */ 1165 /* Fill the RAM location data */
diff --git a/drivers/edac/edac_mc_sysfs.c b/drivers/edac/edac_mc_sysfs.c
index 0f671907c90..87b8d7d6385 100644
--- a/drivers/edac/edac_mc_sysfs.c
+++ b/drivers/edac/edac_mc_sysfs.c
@@ -82,7 +82,7 @@ module_param_call(edac_mc_poll_msec, edac_set_poll_msec, param_get_int,
82 &edac_mc_poll_msec, 0644); 82 &edac_mc_poll_msec, 0644);
83MODULE_PARM_DESC(edac_mc_poll_msec, "Polling period in milliseconds"); 83MODULE_PARM_DESC(edac_mc_poll_msec, "Polling period in milliseconds");
84 84
85static struct device mci_pdev; 85static struct device *mci_pdev;
86 86
87/* 87/*
88 * various constants for Memory Controllers 88 * various constants for Memory Controllers
@@ -181,7 +181,7 @@ static ssize_t csrow_size_show(struct device *dev,
181 u32 nr_pages = 0; 181 u32 nr_pages = 0;
182 182
183 for (i = 0; i < csrow->nr_channels; i++) 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 return sprintf(data, "%u\n", PAGES_TO_MiB(nr_pages)); 185 return sprintf(data, "%u\n", PAGES_TO_MiB(nr_pages));
186} 186}
187 187
@@ -190,7 +190,7 @@ static ssize_t csrow_mem_type_show(struct device *dev,
190{ 190{
191 struct csrow_info *csrow = to_csrow(dev); 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
196static ssize_t csrow_dev_type_show(struct device *dev, 196static ssize_t csrow_dev_type_show(struct device *dev,
@@ -198,7 +198,7 @@ static ssize_t csrow_dev_type_show(struct device *dev,
198{ 198{
199 struct csrow_info *csrow = to_csrow(dev); 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
204static ssize_t csrow_edac_mode_show(struct device *dev, 204static ssize_t csrow_edac_mode_show(struct device *dev,
@@ -207,7 +207,7 @@ static ssize_t csrow_edac_mode_show(struct device *dev,
207{ 207{
208 struct csrow_info *csrow = to_csrow(dev); 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/* show/store functions for DIMM Label attributes */ 213/* show/store functions for DIMM Label attributes */
@@ -217,7 +217,7 @@ static ssize_t channel_dimm_label_show(struct device *dev,
217{ 217{
218 struct csrow_info *csrow = to_csrow(dev); 218 struct csrow_info *csrow = to_csrow(dev);
219 unsigned chan = to_channel(mattr); 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 /* if field has not been initialized, there is nothing to send */ 222 /* if field has not been initialized, there is nothing to send */
223 if (!rank->dimm->label[0]) 223 if (!rank->dimm->label[0])
@@ -233,7 +233,7 @@ static ssize_t channel_dimm_label_store(struct device *dev,
233{ 233{
234 struct csrow_info *csrow = to_csrow(dev); 234 struct csrow_info *csrow = to_csrow(dev);
235 unsigned chan = to_channel(mattr); 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 ssize_t max_size = 0; 238 ssize_t max_size = 0;
239 239
@@ -250,7 +250,7 @@ static ssize_t channel_ce_count_show(struct device *dev,
250{ 250{
251 struct csrow_info *csrow = to_csrow(dev); 251 struct csrow_info *csrow = to_csrow(dev);
252 unsigned chan = to_channel(mattr); 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 return sprintf(data, "%u\n", rank->ce_count); 255 return sprintf(data, "%u\n", rank->ce_count);
256} 256}
@@ -283,9 +283,12 @@ static const struct attribute_group *csrow_attr_groups[] = {
283 NULL 283 NULL
284}; 284};
285 285
286static void csrow_attr_release(struct device *device) 286static 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
291static struct device_type csrow_attr_type = { 294static struct device_type csrow_attr_type = {
@@ -352,7 +355,7 @@ static inline int nr_pages_per_csrow(struct csrow_info *csrow)
352 int chan, nr_pages = 0; 355 int chan, nr_pages = 0;
353 356
354 for (chan = 0; chan < csrow->nr_channels; chan++) 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 return nr_pages; 360 return nr_pages;
358} 361}
@@ -382,7 +385,7 @@ static int edac_create_csrow_object(struct mem_ctl_info *mci,
382 385
383 for (chan = 0; chan < csrow->nr_channels; chan++) { 386 for (chan = 0; chan < csrow->nr_channels; chan++) {
384 /* Only expose populated DIMMs */ 387 /* Only expose populated DIMMs */
385 if (!csrow->channels[chan].dimm->nr_pages) 388 if (!csrow->channels[chan]->dimm->nr_pages)
386 continue; 389 continue;
387 err = device_create_file(&csrow->dev, 390 err = device_create_file(&csrow->dev,
388 dynamic_csrow_dimm_attr[chan]); 391 dynamic_csrow_dimm_attr[chan]);
@@ -418,10 +421,10 @@ static int edac_create_csrow_objects(struct mem_ctl_info *mci)
418 struct csrow_info *csrow; 421 struct csrow_info *csrow;
419 422
420 for (i = 0; i < mci->nr_csrows; i++) { 423 for (i = 0; i < mci->nr_csrows; i++) {
421 csrow = &mci->csrows[i]; 424 csrow = mci->csrows[i];
422 if (!nr_pages_per_csrow(csrow)) 425 if (!nr_pages_per_csrow(csrow))
423 continue; 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 if (err < 0) 428 if (err < 0)
426 goto error; 429 goto error;
427 } 430 }
@@ -429,18 +432,18 @@ static int edac_create_csrow_objects(struct mem_ctl_info *mci)
429 432
430error: 433error:
431 for (--i; i >= 0; i--) { 434 for (--i; i >= 0; i--) {
432 csrow = &mci->csrows[i]; 435 csrow = mci->csrows[i];
433 if (!nr_pages_per_csrow(csrow)) 436 if (!nr_pages_per_csrow(csrow))
434 continue; 437 continue;
435 for (chan = csrow->nr_channels - 1; chan >= 0; chan--) { 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 continue; 440 continue;
438 device_remove_file(&csrow->dev, 441 device_remove_file(&csrow->dev,
439 dynamic_csrow_dimm_attr[chan]); 442 dynamic_csrow_dimm_attr[chan]);
440 device_remove_file(&csrow->dev, 443 device_remove_file(&csrow->dev,
441 dynamic_csrow_ce_count_attr[chan]); 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 return err; 449 return err;
@@ -452,11 +455,11 @@ static void edac_delete_csrow_objects(struct mem_ctl_info *mci)
452 struct csrow_info *csrow; 455 struct csrow_info *csrow;
453 456
454 for (i = mci->nr_csrows - 1; i >= 0; i--) { 457 for (i = mci->nr_csrows - 1; i >= 0; i--) {
455 csrow = &mci->csrows[i]; 458 csrow = mci->csrows[i];
456 if (!nr_pages_per_csrow(csrow)) 459 if (!nr_pages_per_csrow(csrow))
457 continue; 460 continue;
458 for (chan = csrow->nr_channels - 1; chan >= 0; chan--) { 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 continue; 463 continue;
461 debugf1("Removing csrow %d channel %d sysfs nodes\n", 464 debugf1("Removing csrow %d channel %d sysfs nodes\n",
462 i, chan); 465 i, chan);
@@ -465,8 +468,8 @@ static void edac_delete_csrow_objects(struct mem_ctl_info *mci)
465 device_remove_file(&csrow->dev, 468 device_remove_file(&csrow->dev,
466 dynamic_csrow_ce_count_attr[chan]); 469 dynamic_csrow_ce_count_attr[chan]);
467 } 470 }
468 put_device(&mci->csrows[i].dev); 471 put_device(&mci->csrows[i]->dev);
469 device_del(&mci->csrows[i].dev); 472 device_del(&mci->csrows[i]->dev);
470 } 473 }
471} 474}
472#endif 475#endif
@@ -585,9 +588,12 @@ static const struct attribute_group *dimm_attr_groups[] = {
585 NULL 588 NULL
586}; 589};
587 590
588static void dimm_attr_release(struct device *device) 591static 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
593static struct device_type dimm_attr_type = { 599static struct device_type dimm_attr_type = {
@@ -641,13 +647,13 @@ static ssize_t mci_reset_counters_store(struct device *dev,
641 mci->ce_noinfo_count = 0; 647 mci->ce_noinfo_count = 0;
642 648
643 for (row = 0; row < mci->nr_csrows; row++) { 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 ri->ue_count = 0; 652 ri->ue_count = 0;
647 ri->ce_count = 0; 653 ri->ce_count = 0;
648 654
649 for (chan = 0; chan < ri->nr_channels; chan++) 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 cnt = 1; 659 cnt = 1;
@@ -779,10 +785,10 @@ static ssize_t mci_size_mb_show(struct device *dev,
779 int total_pages = 0, csrow_idx, j; 785 int total_pages = 0, csrow_idx, j;
780 786
781 for (csrow_idx = 0; csrow_idx < mci->nr_csrows; csrow_idx++) { 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 for (j = 0; j < csrow->nr_channels; j++) { 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 total_pages += dimm->nr_pages; 793 total_pages += dimm->nr_pages;
788 } 794 }
@@ -889,9 +895,12 @@ static const struct attribute_group *mci_attr_groups[] = {
889 NULL 895 NULL
890}; 896};
891 897
892static void mci_attr_release(struct device *device) 898static 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
897static struct device_type mci_attr_type = { 906static struct device_type mci_attr_type = {
@@ -950,29 +959,28 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci)
950{ 959{
951 int i, err; 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 /* get the /sys/devices/system/edac subsys reference */ 974 /* get the /sys/devices/system/edac subsys reference */
956
957 mci->dev.type = &mci_attr_type; 975 mci->dev.type = &mci_attr_type;
958 device_initialize(&mci->dev); 976 device_initialize(&mci->dev);
959 977
960 mci->dev.parent = &mci_pdev; 978 mci->dev.parent = mci_pdev;
961 mci->dev.bus = &mci->bus; 979 mci->dev.bus = &mci->bus;
962 dev_set_name(&mci->dev, "mc%d", mci->mc_idx); 980 dev_set_name(&mci->dev, "mc%d", mci->mc_idx);
963 dev_set_drvdata(&mci->dev, mci); 981 dev_set_drvdata(&mci->dev, mci);
964 pm_runtime_forbid(&mci->dev); 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 debugf0("%s(): creating device %s\n", __func__, 984 debugf0("%s(): creating device %s\n", __func__,
977 dev_name(&mci->dev)); 985 dev_name(&mci->dev));
978 err = device_add(&mci->dev); 986 err = device_add(&mci->dev);
@@ -986,7 +994,7 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci)
986 * Create the dimm/rank devices 994 * Create the dimm/rank devices
987 */ 995 */
988 for (i = 0; i < mci->tot_dimms; i++) { 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 /* Only expose populated DIMMs */ 998 /* Only expose populated DIMMs */
991 if (dimm->nr_pages == 0) 999 if (dimm->nr_pages == 0)
992 continue; 1000 continue;
@@ -1023,7 +1031,7 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci)
1023 1031
1024fail: 1032fail:
1025 for (i--; i >= 0; i--) { 1033 for (i--; i >= 0; i--) {
1026 struct dimm_info *dimm = &mci->dimms[i]; 1034 struct dimm_info *dimm = mci->dimms[i];
1027 if (dimm->nr_pages == 0) 1035 if (dimm->nr_pages == 0)
1028 continue; 1036 continue;
1029 put_device(&dimm->dev); 1037 put_device(&dimm->dev);
@@ -1053,7 +1061,7 @@ void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci)
1053#endif 1061#endif
1054 1062
1055 for (i = 0; i < mci->tot_dimms; i++) { 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 if (dimm->nr_pages == 0) 1065 if (dimm->nr_pages == 0)
1058 continue; 1066 continue;
1059 debugf0("%s(): removing device %s\n", __func__, 1067 debugf0("%s(): removing device %s\n", __func__,
@@ -1072,9 +1080,15 @@ void edac_unregister_sysfs(struct mem_ctl_info *mci)
1072 kfree(mci->bus.name); 1080 kfree(mci->bus.name);
1073} 1081}
1074 1082
1075static void mc_attr_release(struct device *device) 1083static 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
1080static struct device_type mc_attr_type = { 1094static struct device_type mc_attr_type = {
@@ -1095,21 +1109,25 @@ int __init edac_mc_sysfs_init(void)
1095 return -EINVAL; 1109 return -EINVAL;
1096 } 1110 }
1097 1111
1098 mci_pdev.bus = edac_subsys; 1112 mci_pdev = kzalloc(sizeof(*mci_pdev), GFP_KERNEL);
1099 mci_pdev.type = &mc_attr_type; 1113
1100 device_initialize(&mci_pdev); 1114 mci_pdev->bus = edac_subsys;
1101 dev_set_name(&mci_pdev, "mc"); 1115 mci_pdev->type = &mc_attr_type;
1116 device_initialize(mci_pdev);
1117 dev_set_name(mci_pdev, "mc");
1102 1118
1103 err = device_add(&mci_pdev); 1119 err = device_add(mci_pdev);
1104 if (err < 0) 1120 if (err < 0)
1105 return err; 1121 return err;
1106 1122
1123 debugf0("device %s created\n", dev_name(mci_pdev));
1124
1107 return 0; 1125 return 0;
1108} 1126}
1109 1127
1110void __exit edac_mc_sysfs_exit(void) 1128void __exit edac_mc_sysfs_exit(void)
1111{ 1129{
1112 put_device(&mci_pdev); 1130 put_device(mci_pdev);
1113 device_del(&mci_pdev); 1131 device_del(mci_pdev);
1114 edac_put_sysfs_subsys(); 1132 edac_put_sysfs_subsys();
1115} 1133}
diff --git a/drivers/edac/i3000_edac.c b/drivers/edac/i3000_edac.c
index d1ebd9b9ad6..812213da7f9 100644
--- a/drivers/edac/i3000_edac.c
+++ b/drivers/edac/i3000_edac.c
@@ -236,7 +236,7 @@ static int i3000_process_error_info(struct mem_ctl_info *mci,
236 int row, multi_chan, channel; 236 int row, multi_chan, channel;
237 unsigned long pfn, offset; 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 if (!(info->errsts & I3000_ERRSTS_BITS)) 241 if (!(info->errsts & I3000_ERRSTS_BITS))
242 return 0; 242 return 0;
@@ -393,7 +393,7 @@ static int i3000_probe1(struct pci_dev *pdev, int dev_idx)
393 for (last_cumul_size = i = 0; i < mci->nr_csrows; i++) { 393 for (last_cumul_size = i = 0; i < mci->nr_csrows; i++) {
394 u8 value; 394 u8 value;
395 u32 cumul_size; 395 u32 cumul_size;
396 struct csrow_info *csrow = &mci->csrows[i]; 396 struct csrow_info *csrow = mci->csrows[i];
397 397
398 value = drb[i]; 398 value = drb[i];
399 cumul_size = value << (I3000_DRB_SHIFT - PAGE_SHIFT); 399 cumul_size = value << (I3000_DRB_SHIFT - PAGE_SHIFT);
@@ -410,7 +410,7 @@ static int i3000_probe1(struct pci_dev *pdev, int dev_idx)
410 last_cumul_size = cumul_size; 410 last_cumul_size = cumul_size;
411 411
412 for (j = 0; j < nr_channels; j++) { 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 dimm->nr_pages = nr_pages / nr_channels; 415 dimm->nr_pages = nr_pages / nr_channels;
416 dimm->grain = I3000_DEAP_GRAIN; 416 dimm->grain = I3000_DEAP_GRAIN;
diff --git a/drivers/edac/i3200_edac.c b/drivers/edac/i3200_edac.c
index 600a05df375..c5f0fb31d5e 100644
--- a/drivers/edac/i3200_edac.c
+++ b/drivers/edac/i3200_edac.c
@@ -379,7 +379,7 @@ static int i3200_probe1(struct pci_dev *pdev, int dev_idx)
379 */ 379 */
380 for (i = 0; i < mci->nr_csrows; i++) { 380 for (i = 0; i < mci->nr_csrows; i++) {
381 unsigned long nr_pages; 381 unsigned long nr_pages;
382 struct csrow_info *csrow = &mci->csrows[i]; 382 struct csrow_info *csrow = mci->csrows[i];
383 383
384 nr_pages = drb_to_nr_pages(drbs, stacked, 384 nr_pages = drb_to_nr_pages(drbs, stacked,
385 i / I3200_RANKS_PER_CHANNEL, 385 i / I3200_RANKS_PER_CHANNEL,
@@ -389,7 +389,7 @@ static int i3200_probe1(struct pci_dev *pdev, int dev_idx)
389 continue; 389 continue;
390 390
391 for (j = 0; j < nr_channels; j++) { 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 dimm->nr_pages = nr_pages / nr_channels; 394 dimm->nr_pages = nr_pages / nr_channels;
395 dimm->grain = nr_pages << PAGE_SHIFT; 395 dimm->grain = nr_pages << PAGE_SHIFT;
diff --git a/drivers/edac/i5400_edac.c b/drivers/edac/i5400_edac.c
index ba60694437b..0570cf3d256 100644
--- a/drivers/edac/i5400_edac.c
+++ b/drivers/edac/i5400_edac.c
@@ -1203,8 +1203,8 @@ static int i5400_init_dimms(struct mem_ctl_info *mci)
1203 1203
1204 size_mb = pvt->dimm_info[slot][channel].megabytes; 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", 1206 debugf2("%s: dimm (branch %d channel %d slot %d): %d.%03d GB\n",
1207 __func__, dimm - mci->dimms, 1207 __func__,
1208 channel / 2, channel % 2, slot, 1208 channel / 2, channel % 2, slot,
1209 size_mb / 1000, size_mb % 1000); 1209 size_mb / 1000, size_mb % 1000);
1210 1210
@@ -1227,7 +1227,7 @@ static int i5400_init_dimms(struct mem_ctl_info *mci)
1227 * With such single-DIMM mode, the SDCC algorithm degrades to SECDEC+. 1227 * With such single-DIMM mode, the SDCC algorithm degrades to SECDEC+.
1228 */ 1228 */
1229 if (ndimms == 1) 1229 if (ndimms == 1)
1230 mci->dimms[0].edac_mode = EDAC_SECDED; 1230 mci->dimms[0]->edac_mode = EDAC_SECDED;
1231 1231
1232 return (ndimms == 0); 1232 return (ndimms == 0);
1233} 1233}
diff --git a/drivers/edac/i82443bxgx_edac.c b/drivers/edac/i82443bxgx_edac.c
index 65fd2e1eceb..0f2751bf3ff 100644
--- a/drivers/edac/i82443bxgx_edac.c
+++ b/drivers/edac/i82443bxgx_edac.c
@@ -197,8 +197,8 @@ static void i82443bxgx_init_csrows(struct mem_ctl_info *mci,
197 pci_read_config_byte(pdev, I82443BXGX_DRAMC, &dramc); 197 pci_read_config_byte(pdev, I82443BXGX_DRAMC, &dramc);
198 row_high_limit_last = 0; 198 row_high_limit_last = 0;
199 for (index = 0; index < mci->nr_csrows; index++) { 199 for (index = 0; index < mci->nr_csrows; index++) {
200 csrow = &mci->csrows[index]; 200 csrow = mci->csrows[index];
201 dimm = csrow->channels[0].dimm; 201 dimm = csrow->channels[0]->dimm;
202 202
203 pci_read_config_byte(pdev, I82443BXGX_DRB + index, &drbar); 203 pci_read_config_byte(pdev, I82443BXGX_DRB + index, &drbar);
204 debugf1("MC%d: %s: %s() Row=%d DRB = %#0x\n", 204 debugf1("MC%d: %s: %s() Row=%d DRB = %#0x\n",
diff --git a/drivers/edac/i82860_edac.c b/drivers/edac/i82860_edac.c
index 8f335000094..06a3c8d26d1 100644
--- a/drivers/edac/i82860_edac.c
+++ b/drivers/edac/i82860_edac.c
@@ -116,7 +116,7 @@ static int i82860_process_error_info(struct mem_ctl_info *mci,
116 116
117 info->eap >>= PAGE_SHIFT; 117 info->eap >>= PAGE_SHIFT;
118 row = edac_mc_find_csrow_by_page(mci, info->eap); 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 if (info->errsts & 0x0002) 121 if (info->errsts & 0x0002)
122 edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, 122 edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci,
@@ -161,8 +161,8 @@ static void i82860_init_csrows(struct mem_ctl_info *mci, struct pci_dev *pdev)
161 * in all eight rows. 161 * in all eight rows.
162 */ 162 */
163 for (index = 0; index < mci->nr_csrows; index++) { 163 for (index = 0; index < mci->nr_csrows; index++) {
164 csrow = &mci->csrows[index]; 164 csrow = mci->csrows[index];
165 dimm = csrow->channels[0].dimm; 165 dimm = csrow->channels[0]->dimm;
166 166
167 pci_read_config_word(pdev, I82860_GBA + index * 2, &value); 167 pci_read_config_word(pdev, I82860_GBA + index * 2, &value);
168 cumul_size = (value & I82860_GBA_MASK) << 168 cumul_size = (value & I82860_GBA_MASK) <<
diff --git a/drivers/edac/i82875p_edac.c b/drivers/edac/i82875p_edac.c
index a47c6b25db3..97fd6b769c8 100644
--- a/drivers/edac/i82875p_edac.c
+++ b/drivers/edac/i82875p_edac.c
@@ -227,7 +227,7 @@ static int i82875p_process_error_info(struct mem_ctl_info *mci,
227{ 227{
228 int row, multi_chan; 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 if (!(info->errsts & 0x0081)) 232 if (!(info->errsts & 0x0081))
233 return 0; 233 return 0;
@@ -367,7 +367,7 @@ static void i82875p_init_csrows(struct mem_ctl_info *mci,
367 */ 367 */
368 368
369 for (index = 0; index < mci->nr_csrows; index++) { 369 for (index = 0; index < mci->nr_csrows; index++) {
370 csrow = &mci->csrows[index]; 370 csrow = mci->csrows[index];
371 371
372 value = readb(ovrfl_window + I82875P_DRB + index); 372 value = readb(ovrfl_window + I82875P_DRB + index);
373 cumul_size = value << (I82875P_DRB_SHIFT - PAGE_SHIFT); 373 cumul_size = value << (I82875P_DRB_SHIFT - PAGE_SHIFT);
@@ -382,7 +382,7 @@ static void i82875p_init_csrows(struct mem_ctl_info *mci,
382 last_cumul_size = cumul_size; 382 last_cumul_size = cumul_size;
383 383
384 for (j = 0; j < nr_chans; j++) { 384 for (j = 0; j < nr_chans; j++) {
385 dimm = csrow->channels[j].dimm; 385 dimm = csrow->channels[j]->dimm;
386 386
387 dimm->nr_pages = nr_pages / nr_chans; 387 dimm->nr_pages = nr_pages / nr_chans;
388 dimm->grain = 1 << 12; /* I82875P_EAP has 4KiB reolution */ 388 dimm->grain = 1 << 12; /* I82875P_EAP has 4KiB reolution */
diff --git a/drivers/edac/i82975x_edac.c b/drivers/edac/i82975x_edac.c
index 8b26401efa1..4d239ab31e3 100644
--- a/drivers/edac/i82975x_edac.c
+++ b/drivers/edac/i82975x_edac.c
@@ -308,10 +308,10 @@ static int i82975x_process_error_info(struct mem_ctl_info *mci,
308 (info->xeap & 1) ? 1 : 0, info->eap, (unsigned int) page); 308 (info->xeap & 1) ? 1 : 0, info->eap, (unsigned int) page);
309 return 0; 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 offst = info->eap 312 offst = info->eap
313 & ((1 << PAGE_SHIFT) - 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 if (info->errsts & 0x0002) 316 if (info->errsts & 0x0002)
317 edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, 317 edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci,
@@ -394,7 +394,7 @@ static void i82975x_init_csrows(struct mem_ctl_info *mci,
394 */ 394 */
395 395
396 for (index = 0; index < mci->nr_csrows; index++) { 396 for (index = 0; index < mci->nr_csrows; index++) {
397 csrow = &mci->csrows[index]; 397 csrow = mci->csrows[index];
398 398
399 value = readb(mch_window + I82975X_DRB + index + 399 value = readb(mch_window + I82975X_DRB + index +
400 ((index >= 4) ? 0x80 : 0)); 400 ((index >= 4) ? 0x80 : 0));
@@ -421,10 +421,10 @@ static void i82975x_init_csrows(struct mem_ctl_info *mci,
421 */ 421 */
422 dtype = i82975x_dram_type(mch_window, index); 422 dtype = i82975x_dram_type(mch_window, index);
423 for (chan = 0; chan < csrow->nr_channels; chan++) { 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 dimm->nr_pages = nr_pages / csrow->nr_channels; 426 dimm->nr_pages = nr_pages / csrow->nr_channels;
427 strncpy(csrow->channels[chan].dimm->label, 427 strncpy(csrow->channels[chan]->dimm->label,
428 labels[(index >> 1) + (chan * 2)], 428 labels[(index >> 1) + (chan * 2)],
429 EDAC_MC_LABEL_LEN); 429 EDAC_MC_LABEL_LEN);
430 dimm->grain = 1 << 7; /* 128Byte cache-line resolution */ 430 dimm->grain = 1 << 7; /* 128Byte cache-line resolution */
diff --git a/drivers/edac/mpc85xx_edac.c b/drivers/edac/mpc85xx_edac.c
index d132dbbd9bd..0db6f1e8465 100644
--- a/drivers/edac/mpc85xx_edac.c
+++ b/drivers/edac/mpc85xx_edac.c
@@ -825,7 +825,7 @@ static void mpc85xx_mc_check(struct mem_ctl_info *mci)
825 pfn = err_addr >> PAGE_SHIFT; 825 pfn = err_addr >> PAGE_SHIFT;
826 826
827 for (row_index = 0; row_index < mci->nr_csrows; row_index++) { 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 if ((pfn >= csrow->first_page) && (pfn <= csrow->last_page)) 829 if ((pfn >= csrow->first_page) && (pfn <= csrow->last_page))
830 break; 830 break;
831 } 831 }
@@ -945,8 +945,8 @@ static void __devinit mpc85xx_init_csrows(struct mem_ctl_info *mci)
945 u32 start; 945 u32 start;
946 u32 end; 946 u32 end;
947 947
948 csrow = &mci->csrows[index]; 948 csrow = mci->csrows[index];
949 dimm = csrow->channels[0].dimm; 949 dimm = csrow->channels[0]->dimm;
950 950
951 cs_bnds = in_be32(pdata->mc_vbase + MPC85XX_MC_CS_BNDS_0 + 951 cs_bnds = in_be32(pdata->mc_vbase + MPC85XX_MC_CS_BNDS_0 +
952 (index * MPC85XX_MC_CS_BNDS_OFS)); 952 (index * MPC85XX_MC_CS_BNDS_OFS));
diff --git a/drivers/edac/mv64x60_edac.c b/drivers/edac/mv64x60_edac.c
index ff6b8e248e8..3a58ba9158d 100644
--- a/drivers/edac/mv64x60_edac.c
+++ b/drivers/edac/mv64x60_edac.c
@@ -670,8 +670,8 @@ static void mv64x60_init_csrows(struct mem_ctl_info *mci,
670 670
671 ctl = in_le32(pdata->mc_vbase + MV64X60_SDRAM_CONFIG); 671 ctl = in_le32(pdata->mc_vbase + MV64X60_SDRAM_CONFIG);
672 672
673 csrow = &mci->csrows[0]; 673 csrow = mci->csrows[0];
674 dimm = csrow->channels[0].dimm; 674 dimm = csrow->channels[0]->dimm;
675 675
676 dimm->nr_pages = pdata->total_mem >> PAGE_SHIFT; 676 dimm->nr_pages = pdata->total_mem >> PAGE_SHIFT;
677 dimm->grain = 8; 677 dimm->grain = 8;
diff --git a/drivers/edac/pasemi_edac.c b/drivers/edac/pasemi_edac.c
index 92becaa8722..44f73b00df0 100644
--- a/drivers/edac/pasemi_edac.c
+++ b/drivers/edac/pasemi_edac.c
@@ -111,14 +111,14 @@ static void pasemi_edac_process_error_info(struct mem_ctl_info *mci, u32 errsta)
111 if (errsta & (MCDEBUG_ERRSTA_MBE_STATUS | 111 if (errsta & (MCDEBUG_ERRSTA_MBE_STATUS |
112 MCDEBUG_ERRSTA_RFL_STATUS)) { 112 MCDEBUG_ERRSTA_RFL_STATUS)) {
113 edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, 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 cs, 0, -1, mci->ctl_name, "", NULL); 115 cs, 0, -1, mci->ctl_name, "", NULL);
116 } 116 }
117 117
118 /* correctable/single-bit errors */ 118 /* correctable/single-bit errors */
119 if (errsta & MCDEBUG_ERRSTA_SBE_STATUS) 119 if (errsta & MCDEBUG_ERRSTA_SBE_STATUS)
120 edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, 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 cs, 0, -1, mci->ctl_name, "", NULL); 122 cs, 0, -1, mci->ctl_name, "", NULL);
123} 123}
124 124
@@ -141,8 +141,8 @@ static int pasemi_edac_init_csrows(struct mem_ctl_info *mci,
141 int index; 141 int index;
142 142
143 for (index = 0; index < mci->nr_csrows; index++) { 143 for (index = 0; index < mci->nr_csrows; index++) {
144 csrow = &mci->csrows[index]; 144 csrow = mci->csrows[index];
145 dimm = csrow->channels[0].dimm; 145 dimm = csrow->channels[0]->dimm;
146 146
147 pci_read_config_dword(pdev, 147 pci_read_config_dword(pdev,
148 MCDRAM_RANKCFG + (index * 12), 148 MCDRAM_RANKCFG + (index * 12),
diff --git a/drivers/edac/r82600_edac.c b/drivers/edac/r82600_edac.c
index cf4ccbdba85..445c9ff27b8 100644
--- a/drivers/edac/r82600_edac.c
+++ b/drivers/edac/r82600_edac.c
@@ -230,8 +230,8 @@ static void r82600_init_csrows(struct mem_ctl_info *mci, struct pci_dev *pdev,
230 row_high_limit_last = 0; 230 row_high_limit_last = 0;
231 231
232 for (index = 0; index < mci->nr_csrows; index++) { 232 for (index = 0; index < mci->nr_csrows; index++) {
233 csrow = &mci->csrows[index]; 233 csrow = mci->csrows[index];
234 dimm = csrow->channels[0].dimm; 234 dimm = csrow->channels[0]->dimm;
235 235
236 /* find the DRAM Chip Select Base address and mask */ 236 /* find the DRAM Chip Select Base address and mask */
237 pci_read_config_byte(pdev, R82600_DRBA + index, &drbar); 237 pci_read_config_byte(pdev, R82600_DRBA + index, &drbar);
diff --git a/drivers/edac/tile_edac.c b/drivers/edac/tile_edac.c
index 604bc4df653..fc77f77fa06 100644
--- a/drivers/edac/tile_edac.c
+++ b/drivers/edac/tile_edac.c
@@ -84,10 +84,10 @@ static void tile_edac_check(struct mem_ctl_info *mci)
84 */ 84 */
85static int __devinit tile_edac_init_csrows(struct mem_ctl_info *mci) 85static 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 struct tile_edac_priv *priv = mci->pvt_info; 88 struct tile_edac_priv *priv = mci->pvt_info;
89 struct mshim_mem_info mem_info; 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 if (hv_dev_pread(priv->hv_devhdl, 0, (HV_VirtAddr)&mem_info, 92 if (hv_dev_pread(priv->hv_devhdl, 0, (HV_VirtAddr)&mem_info,
93 sizeof(struct mshim_mem_info), MSHIM_MEM_INFO_OFF) != 93 sizeof(struct mshim_mem_info), MSHIM_MEM_INFO_OFF) !=
diff --git a/drivers/edac/x38_edac.c b/drivers/edac/x38_edac.c
index f9506f26e2b..ae699be78b2 100644
--- a/drivers/edac/x38_edac.c
+++ b/drivers/edac/x38_edac.c
@@ -378,7 +378,7 @@ static int x38_probe1(struct pci_dev *pdev, int dev_idx)
378 */ 378 */
379 for (i = 0; i < mci->nr_csrows; i++) { 379 for (i = 0; i < mci->nr_csrows; i++) {
380 unsigned long nr_pages; 380 unsigned long nr_pages;
381 struct csrow_info *csrow = &mci->csrows[i]; 381 struct csrow_info *csrow = mci->csrows[i];
382 382
383 nr_pages = drb_to_nr_pages(drbs, stacked, 383 nr_pages = drb_to_nr_pages(drbs, stacked,
384 i / X38_RANKS_PER_CHANNEL, 384 i / X38_RANKS_PER_CHANNEL,
@@ -388,7 +388,7 @@ static int x38_probe1(struct pci_dev *pdev, int dev_idx)
388 continue; 388 continue;
389 389
390 for (j = 0; j < x38_channel_num; j++) { 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 dimm->nr_pages = nr_pages / x38_channel_num; 393 dimm->nr_pages = nr_pages / x38_channel_num;
394 dimm->grain = nr_pages << PAGE_SHIFT; 394 dimm->grain = nr_pages << PAGE_SHIFT;
diff --git a/include/linux/edac.h b/include/linux/edac.h
index 64ae0c5cf62..6677af853e3 100644
--- a/include/linux/edac.h
+++ b/include/linux/edac.h
@@ -412,23 +412,21 @@ struct edac_mc_layer {
412#define EDAC_MAX_LAYERS 3 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 * for the element given by [layer0,layer1,layer2] position 416 * for the element given by [layer0,layer1,layer2] position
417 * 417 *
418 * @layers: a struct edac_mc_layer array, describing how many elements 418 * @layers: a struct edac_mc_layer array, describing how many elements
419 * were allocated for each layer 419 * were allocated for each layer
420 * @var: name of the var where we want to get the pointer
421 * (like mci->dimms)
422 * @n_layers: Number of layers at the @layers array 420 * @n_layers: Number of layers at the @layers array
423 * @layer0: layer0 position 421 * @layer0: layer0 position
424 * @layer1: layer1 position. Unused if n_layers < 2 422 * @layer1: layer1 position. Unused if n_layers < 2
425 * @layer2: layer2 position. Unused if n_layers < 3 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 * For 2 layers, this macro is similar to allocate a bi-dimensional array 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 * For 3 layers, this macro is similar to allocate a tri-dimensional array 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 * A loop could be used here to make it more generic, but, as we only have 431 * A loop could be used here to make it more generic, but, as we only have
434 * 3 layers, this is a little faster. 432 * 3 layers, this is a little faster.
@@ -436,17 +434,46 @@ struct edac_mc_layer {
436 * a NULL is returned, causing an OOPS during the memory allocation routine, 434 * a NULL is returned, causing an OOPS during the memory allocation routine,
437 * with would point to the developer that he's doing something wrong. 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) ({ \ 437#define EDAC_DIMM_OFF(layers, nlayers, layer0, layer1, layer2) ({ \
440 typeof(var) __p; \ 438 int __i; \
441 if ((nlayers) == 1) \ 439 if ((nlayers) == 1) \
442 __p = &var[layer0]; \ 440 __i = layer0; \
443 else if ((nlayers) == 2) \ 441 else if ((nlayers) == 2) \
444 __p = &var[(layer1) + ((layers[1]).size * (layer0))]; \ 442 __i = (layer1) + ((layers[1]).size * (layer0)); \
445 else if ((nlayers) == 3) \ 443 else if ((nlayers) == 3) \
446 __p = &var[(layer2) + ((layers[2]).size * ((layer1) + \ 444 __i = (layer2) + ((layers[2]).size * ((layer1) + \
447 ((layers[1]).size * (layer0))))]; \ 445 ((layers[1]).size * (layer0)))); \
448 else \ 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 __p = NULL; \ 474 __p = NULL; \
475 else \
476 __p = (var)[___i]; \
450 __p; \ 477 __p; \
451}) 478})
452 479
@@ -486,8 +513,6 @@ struct dimm_info {
486 * patches in this series will fix this issue. 513 * patches in this series will fix this issue.
487 */ 514 */
488struct rank_info { 515struct rank_info {
489 struct device dev;
490
491 int chan_idx; 516 int chan_idx;
492 struct csrow_info *csrow; 517 struct csrow_info *csrow;
493 struct dimm_info *dimm; 518 struct dimm_info *dimm;
@@ -513,7 +538,7 @@ struct csrow_info {
513 538
514 /* channel information for this csrow */ 539 /* channel information for this csrow */
515 u32 nr_channels; 540 u32 nr_channels;
516 struct rank_info *channels; 541 struct rank_info **channels;
517}; 542};
518 543
519/* 544/*
@@ -572,7 +597,7 @@ struct mem_ctl_info {
572 unsigned long (*ctl_page_to_phys) (struct mem_ctl_info * mci, 597 unsigned long (*ctl_page_to_phys) (struct mem_ctl_info * mci,
573 unsigned long page); 598 unsigned long page);
574 int mc_idx; 599 int mc_idx;
575 struct csrow_info *csrows; 600 struct csrow_info **csrows;
576 unsigned nr_csrows, num_cschannel; 601 unsigned nr_csrows, num_cschannel;
577 602
578 /* 603 /*
@@ -592,7 +617,7 @@ struct mem_ctl_info {
592 * DIMM info. Will eventually remove the entire csrows_info some day 617 * DIMM info. Will eventually remove the entire csrows_info some day
593 */ 618 */
594 unsigned tot_dimms; 619 unsigned tot_dimms;
595 struct dimm_info *dimms; 620 struct dimm_info **dimms;
596 621
597 /* 622 /*
598 * FIXME - what about controllers on other busses? - IDs must be 623 * FIXME - what about controllers on other busses? - IDs must be