Commit 084a4fccef39ac7abb039511f32380f28d0b67e6

Authored by Mauro Carvalho Chehab
1 parent a7d7d2e1a0

edac: move dimm properties to struct dimm_info

On systems based on chip select rows, all channels need to use memories
with the same properties, otherwise the memories on channels A and B
won't be recognized.

However, such assumption is not true for all types of memory
controllers.

Controllers for FB-DIMM's don't have such requirements.

Also, modern Intel controllers seem to be capable of handling such
differences.

So, we need to get rid of storing the DIMM information into a per-csrow
data, storing it, instead at the right place.

The first step is to move grain, mtype, dtype and edac_mode to the
per-dimm struct.

Reviewed-by: Aristeu Rozanski <arozansk@redhat.com>
Reviewed-by: Borislav Petkov <borislav.petkov@amd.com>
Acked-by: Chris Metcalf <cmetcalf@tilera.com>
Cc: Doug Thompson <norsk5@yahoo.com>
Cc: Borislav Petkov <borislav.petkov@amd.com>
Cc: Mark Gross <mark.gross@intel.com>
Cc: Jason Uhlenkott <juhlenko@akamai.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: Joe Perches <joe@perches.com>
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: James Bottomley <James.Bottomley@parallels.com>
Cc: "Niklas Söderlund" <niklas.soderlund@ericsson.com>
Cc: Shaohui Xie <Shaohui.Xie@freescale.com>
Cc: Josh Boyer <jwboyer@gmail.com>
Cc: Mike Williams <mike@mikebwilliams.com>
Cc: linuxppc-dev@lists.ozlabs.org
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

Showing 28 changed files with 334 additions and 257 deletions Side-by-side Diff

drivers/edac/amd64_edac.c
... ... @@ -2187,7 +2187,9 @@
2187 2187 struct amd64_pvt *pvt = mci->pvt_info;
2188 2188 u64 input_addr_min, input_addr_max, sys_addr, base, mask;
2189 2189 u32 val;
2190   - int i, empty = 1;
  2190 + int i, j, empty = 1;
  2191 + enum mem_type mtype;
  2192 + enum edac_type edac_mode;
2191 2193  
2192 2194 amd64_read_pci_cfg(pvt->F3, NBCFG, &val);
2193 2195  
... ... @@ -2224,7 +2226,7 @@
2224 2226 csrow->page_mask = ~mask;
2225 2227 /* 8 bytes of resolution */
2226 2228  
2227   - csrow->mtype = amd64_determine_memory_type(pvt, i);
  2229 + mtype = amd64_determine_memory_type(pvt, i);
2228 2230  
2229 2231 debugf1(" for MC node %d csrow %d:\n", pvt->mc_node_id, i);
2230 2232 debugf1(" input_addr_min: 0x%lx input_addr_max: 0x%lx\n",
2231 2233  
... ... @@ -2241,11 +2243,15 @@
2241 2243 * determine whether CHIPKILL or JUST ECC or NO ECC is operating
2242 2244 */
2243 2245 if (pvt->nbcfg & NBCFG_ECC_ENABLE)
2244   - csrow->edac_mode =
2245   - (pvt->nbcfg & NBCFG_CHIPKILL) ?
2246   - EDAC_S4ECD4ED : EDAC_SECDED;
  2246 + edac_mode = (pvt->nbcfg & NBCFG_CHIPKILL) ?
  2247 + EDAC_S4ECD4ED : EDAC_SECDED;
2247 2248 else
2248   - csrow->edac_mode = EDAC_NONE;
  2249 + edac_mode = EDAC_NONE;
  2250 +
  2251 + for (j = 0; j < pvt->channel_count; j++) {
  2252 + csrow->channels[j].dimm->mtype = mtype;
  2253 + csrow->channels[j].dimm->edac_mode = edac_mode;
  2254 + }
2249 2255 }
2250 2256  
2251 2257 return empty;
drivers/edac/amd76x_edac.c
... ... @@ -186,11 +186,13 @@
186 186 enum edac_type edac_mode)
187 187 {
188 188 struct csrow_info *csrow;
  189 + struct dimm_info *dimm;
189 190 u32 mba, mba_base, mba_mask, dms;
190 191 int index;
191 192  
192 193 for (index = 0; index < mci->nr_csrows; index++) {
193 194 csrow = &mci->csrows[index];
  195 + dimm = csrow->channels[0].dimm;
194 196  
195 197 /* find the DRAM Chip Select Base address and mask */
196 198 pci_read_config_dword(pdev,
... ... @@ -206,10 +208,10 @@
206 208 csrow->nr_pages = (mba_mask + 1) >> PAGE_SHIFT;
207 209 csrow->last_page = csrow->first_page + csrow->nr_pages - 1;
208 210 csrow->page_mask = mba_mask >> PAGE_SHIFT;
209   - csrow->grain = csrow->nr_pages << PAGE_SHIFT;
210   - csrow->mtype = MEM_RDDR;
211   - csrow->dtype = ((dms >> index) & 0x1) ? DEV_X4 : DEV_UNKNOWN;
212   - csrow->edac_mode = edac_mode;
  211 + dimm->grain = csrow->nr_pages << PAGE_SHIFT;
  212 + dimm->mtype = MEM_RDDR;
  213 + dimm->dtype = ((dms >> index) & 0x1) ? DEV_X4 : DEV_UNKNOWN;
  214 + dimm->edac_mode = edac_mode;
213 215 }
214 216 }
215 217  
drivers/edac/cell_edac.c
... ... @@ -124,8 +124,10 @@
124 124 static void __devinit cell_edac_init_csrows(struct mem_ctl_info *mci)
125 125 {
126 126 struct csrow_info *csrow = &mci->csrows[0];
  127 + struct dimm_info *dimm;
127 128 struct cell_edac_priv *priv = mci->pvt_info;
128 129 struct device_node *np;
  130 + int j;
129 131  
130 132 for (np = NULL;
131 133 (np = of_find_node_by_name(np, "memory")) != NULL;) {
... ... @@ -142,8 +144,12 @@
142 144 csrow->first_page = r.start >> PAGE_SHIFT;
143 145 csrow->nr_pages = resource_size(&r) >> PAGE_SHIFT;
144 146 csrow->last_page = csrow->first_page + csrow->nr_pages - 1;
145   - csrow->mtype = MEM_XDR;
146   - csrow->edac_mode = EDAC_SECDED;
  147 +
  148 + for (j = 0; j < csrow->nr_channels; j++) {
  149 + dimm = csrow->channels[j].dimm;
  150 + dimm->mtype = MEM_XDR;
  151 + dimm->edac_mode = EDAC_SECDED;
  152 + }
147 153 dev_dbg(mci->dev,
148 154 "Initialized on node %d, chanmask=0x%x,"
149 155 " first_page=0x%lx, nr_pages=0x%x\n",
drivers/edac/cpc925_edac.c
... ... @@ -329,7 +329,8 @@
329 329 {
330 330 struct cpc925_mc_pdata *pdata = mci->pvt_info;
331 331 struct csrow_info *csrow;
332   - int index;
  332 + struct dimm_info *dimm;
  333 + int index, j;
333 334 u32 mbmr, mbbar, bba;
334 335 unsigned long row_size, last_nr_pages = 0;
335 336  
336 337  
337 338  
... ... @@ -354,32 +355,35 @@
354 355 csrow->last_page = csrow->first_page + csrow->nr_pages - 1;
355 356 last_nr_pages = csrow->last_page + 1;
356 357  
357   - csrow->mtype = MEM_RDDR;
358   - csrow->edac_mode = EDAC_SECDED;
  358 + for (j = 0; j < csrow->nr_channels; j++) {
  359 + dimm = csrow->channels[j].dimm;
  360 + dimm->mtype = MEM_RDDR;
  361 + dimm->edac_mode = EDAC_SECDED;
359 362  
360   - switch (csrow->nr_channels) {
361   - case 1: /* Single channel */
362   - csrow->grain = 32; /* four-beat burst of 32 bytes */
363   - break;
364   - case 2: /* Dual channel */
365   - default:
366   - csrow->grain = 64; /* four-beat burst of 64 bytes */
367   - break;
368   - }
  363 + switch (csrow->nr_channels) {
  364 + case 1: /* Single channel */
  365 + dimm->grain = 32; /* four-beat burst of 32 bytes */
  366 + break;
  367 + case 2: /* Dual channel */
  368 + default:
  369 + dimm->grain = 64; /* four-beat burst of 64 bytes */
  370 + break;
  371 + }
369 372  
370   - switch ((mbmr & MBMR_MODE_MASK) >> MBMR_MODE_SHIFT) {
371   - case 6: /* 0110, no way to differentiate X8 VS X16 */
372   - case 5: /* 0101 */
373   - case 8: /* 1000 */
374   - csrow->dtype = DEV_X16;
375   - break;
376   - case 7: /* 0111 */
377   - case 9: /* 1001 */
378   - csrow->dtype = DEV_X8;
379   - break;
380   - default:
381   - csrow->dtype = DEV_UNKNOWN;
382   - break;
  373 + switch ((mbmr & MBMR_MODE_MASK) >> MBMR_MODE_SHIFT) {
  374 + case 6: /* 0110, no way to differentiate X8 VS X16 */
  375 + case 5: /* 0101 */
  376 + case 8: /* 1000 */
  377 + dimm->dtype = DEV_X16;
  378 + break;
  379 + case 7: /* 0111 */
  380 + case 9: /* 1001 */
  381 + dimm->dtype = DEV_X8;
  382 + break;
  383 + default:
  384 + dimm->dtype = DEV_UNKNOWN;
  385 + break;
  386 + }
383 387 }
384 388 }
385 389 }
386 390  
... ... @@ -962,9 +966,9 @@
962 966 goto err2;
963 967 }
964 968  
965   - nr_channels = cpc925_mc_get_channels(vbase);
  969 + nr_channels = cpc925_mc_get_channels(vbase) + 1;
966 970 mci = edac_mc_alloc(sizeof(struct cpc925_mc_pdata),
967   - CPC925_NR_CSROWS, nr_channels + 1, edac_mc_idx);
  971 + CPC925_NR_CSROWS, nr_channels, edac_mc_idx);
968 972 if (!mci) {
969 973 cpc925_printk(KERN_ERR, "No memory for mem_ctl_info\n");
970 974 res = -ENOMEM;
drivers/edac/e752x_edac.c
... ... @@ -1044,7 +1044,7 @@
1044 1044 int drc_drbg; /* DRB granularity 0=64mb, 1=128mb */
1045 1045 int drc_ddim; /* DRAM Data Integrity Mode 0=none, 2=edac */
1046 1046 u8 value;
1047   - u32 dra, drc, cumul_size;
  1047 + u32 dra, drc, cumul_size, i;
1048 1048  
1049 1049 dra = 0;
1050 1050 for (index = 0; index < 4; index++) {
... ... @@ -1053,7 +1053,7 @@
1053 1053 dra |= dra_reg << (index * 8);
1054 1054 }
1055 1055 pci_read_config_dword(pdev, E752X_DRC, &drc);
1056   - drc_chan = dual_channel_active(ddrcsr);
  1056 + drc_chan = dual_channel_active(ddrcsr) ? 1 : 0;
1057 1057 drc_drbg = drc_chan + 1; /* 128 in dual mode, 64 in single */
1058 1058 drc_ddim = (drc >> 20) & 0x3;
1059 1059  
1060 1060  
... ... @@ -1080,24 +1080,28 @@
1080 1080 csrow->last_page = cumul_size - 1;
1081 1081 csrow->nr_pages = cumul_size - last_cumul_size;
1082 1082 last_cumul_size = cumul_size;
1083   - csrow->grain = 1 << 12; /* 4KiB - resolution of CELOG */
1084   - csrow->mtype = MEM_RDDR; /* only one type supported */
1085   - csrow->dtype = mem_dev ? DEV_X4 : DEV_X8;
1086 1083  
1087   - /*
1088   - * if single channel or x8 devices then SECDED
1089   - * if dual channel and x4 then S4ECD4ED
1090   - */
1091   - if (drc_ddim) {
1092   - if (drc_chan && mem_dev) {
1093   - csrow->edac_mode = EDAC_S4ECD4ED;
1094   - mci->edac_cap |= EDAC_FLAG_S4ECD4ED;
1095   - } else {
1096   - csrow->edac_mode = EDAC_SECDED;
1097   - mci->edac_cap |= EDAC_FLAG_SECDED;
1098   - }
1099   - } else
1100   - csrow->edac_mode = EDAC_NONE;
  1084 + for (i = 0; i < drc_chan + 1; i++) {
  1085 + struct dimm_info *dimm = csrow->channels[i].dimm;
  1086 + dimm->grain = 1 << 12; /* 4KiB - resolution of CELOG */
  1087 + dimm->mtype = MEM_RDDR; /* only one type supported */
  1088 + dimm->dtype = mem_dev ? DEV_X4 : DEV_X8;
  1089 +
  1090 + /*
  1091 + * if single channel or x8 devices then SECDED
  1092 + * if dual channel and x4 then S4ECD4ED
  1093 + */
  1094 + if (drc_ddim) {
  1095 + if (drc_chan && mem_dev) {
  1096 + dimm->edac_mode = EDAC_S4ECD4ED;
  1097 + mci->edac_cap |= EDAC_FLAG_S4ECD4ED;
  1098 + } else {
  1099 + dimm->edac_mode = EDAC_SECDED;
  1100 + mci->edac_cap |= EDAC_FLAG_SECDED;
  1101 + }
  1102 + } else
  1103 + dimm->edac_mode = EDAC_NONE;
  1104 + }
1101 1105 }
1102 1106 }
1103 1107  
drivers/edac/e7xxx_edac.c
... ... @@ -347,11 +347,12 @@
347 347 int dev_idx, u32 drc)
348 348 {
349 349 unsigned long last_cumul_size;
350   - int index;
  350 + int index, j;
351 351 u8 value;
352 352 u32 dra, cumul_size;
353 353 int drc_chan, drc_drbg, drc_ddim, mem_dev;
354 354 struct csrow_info *csrow;
  355 + struct dimm_info *dimm;
355 356  
356 357 pci_read_config_dword(pdev, E7XXX_DRA, &dra);
357 358 drc_chan = dual_channel_active(drc, dev_idx);
358 359  
... ... @@ -381,24 +382,29 @@
381 382 csrow->last_page = cumul_size - 1;
382 383 csrow->nr_pages = cumul_size - last_cumul_size;
383 384 last_cumul_size = cumul_size;
384   - csrow->grain = 1 << 12; /* 4KiB - resolution of CELOG */
385   - csrow->mtype = MEM_RDDR; /* only one type supported */
386   - csrow->dtype = mem_dev ? DEV_X4 : DEV_X8;
387 385  
388   - /*
389   - * if single channel or x8 devices then SECDED
390   - * if dual channel and x4 then S4ECD4ED
391   - */
392   - if (drc_ddim) {
393   - if (drc_chan && mem_dev) {
394   - csrow->edac_mode = EDAC_S4ECD4ED;
395   - mci->edac_cap |= EDAC_FLAG_S4ECD4ED;
396   - } else {
397   - csrow->edac_mode = EDAC_SECDED;
398   - mci->edac_cap |= EDAC_FLAG_SECDED;
399   - }
400   - } else
401   - csrow->edac_mode = EDAC_NONE;
  386 + for (j = 0; j < drc_chan + 1; j++) {
  387 + dimm = csrow->channels[j].dimm;
  388 +
  389 + dimm->grain = 1 << 12; /* 4KiB - resolution of CELOG */
  390 + dimm->mtype = MEM_RDDR; /* only one type supported */
  391 + dimm->dtype = mem_dev ? DEV_X4 : DEV_X8;
  392 +
  393 + /*
  394 + * if single channel or x8 devices then SECDED
  395 + * if dual channel and x4 then S4ECD4ED
  396 + */
  397 + if (drc_ddim) {
  398 + if (drc_chan && mem_dev) {
  399 + dimm->edac_mode = EDAC_S4ECD4ED;
  400 + mci->edac_cap |= EDAC_FLAG_S4ECD4ED;
  401 + } else {
  402 + dimm->edac_mode = EDAC_SECDED;
  403 + mci->edac_cap |= EDAC_FLAG_SECDED;
  404 + }
  405 + } else
  406 + dimm->edac_mode = EDAC_NONE;
  407 + }
402 408 }
403 409 }
404 410  
drivers/edac/edac_mc.c
... ... @@ -43,7 +43,7 @@
43 43 {
44 44 debugf4("\tchannel = %p\n", chan);
45 45 debugf4("\tchannel->chan_idx = %d\n", chan->chan_idx);
46   - debugf4("\tchannel->ce_count = %d\n", chan->ce_count);
  46 + debugf4("\tchannel->ce_count = %d\n", chan->dimm->ce_count);
47 47 debugf4("\tchannel->label = '%s'\n", chan->dimm->label);
48 48 debugf4("\tchannel->csrow = %p\n\n", chan->csrow);
49 49 }
... ... @@ -695,6 +695,7 @@
695 695 {
696 696 unsigned long remapped_page;
697 697 char *label = NULL;
  698 + u32 grain;
698 699  
699 700 debugf3("MC%d: %s()\n", mci->mc_idx, __func__);
700 701  
... ... @@ -719,6 +720,7 @@
719 720 }
720 721  
721 722 label = mci->csrows[row].channels[channel].dimm->label;
  723 + grain = mci->csrows[row].channels[channel].dimm->grain;
722 724  
723 725 if (edac_mc_get_log_ce())
724 726 /* FIXME - put in DIMM location */
725 727  
... ... @@ -726,11 +728,12 @@
726 728 "CE page 0x%lx, offset 0x%lx, grain %d, syndrome "
727 729 "0x%lx, row %d, channel %d, label \"%s\": %s\n",
728 730 page_frame_number, offset_in_page,
729   - mci->csrows[row].grain, syndrome, row, channel,
  731 + grain, syndrome, row, channel,
730 732 label, msg);
731 733  
732 734 mci->ce_count++;
733 735 mci->csrows[row].ce_count++;
  736 + mci->csrows[row].channels[channel].dimm->ce_count++;
734 737 mci->csrows[row].channels[channel].ce_count++;
735 738  
736 739 if (mci->scrub_mode & SCRUB_SW_SRC) {
... ... @@ -747,8 +750,7 @@
747 750 mci->ctl_page_to_phys(mci, page_frame_number) :
748 751 page_frame_number;
749 752  
750   - edac_mc_scrub_block(remapped_page, offset_in_page,
751   - mci->csrows[row].grain);
  753 + edac_mc_scrub_block(remapped_page, offset_in_page, grain);
752 754 }
753 755 }
754 756 EXPORT_SYMBOL_GPL(edac_mc_handle_ce);
... ... @@ -774,6 +776,7 @@
774 776 int chan;
775 777 int chars;
776 778 char *label = NULL;
  779 + u32 grain;
777 780  
778 781 debugf3("MC%d: %s()\n", mci->mc_idx, __func__);
779 782  
... ... @@ -787,6 +790,7 @@
787 790 return;
788 791 }
789 792  
  793 + grain = mci->csrows[row].channels[0].dimm->grain;
790 794 label = mci->csrows[row].channels[0].dimm->label;
791 795 chars = snprintf(pos, len + 1, "%s", label);
792 796 len -= chars;
793 797  
... ... @@ -804,14 +808,13 @@
804 808 edac_mc_printk(mci, KERN_EMERG,
805 809 "UE page 0x%lx, offset 0x%lx, grain %d, row %d, "
806 810 "labels \"%s\": %s\n", page_frame_number,
807   - offset_in_page, mci->csrows[row].grain, row,
808   - labels, msg);
  811 + offset_in_page, grain, row, labels, msg);
809 812  
810 813 if (edac_mc_get_panic_on_ue())
811 814 panic("EDAC MC%d: UE page 0x%lx, offset 0x%lx, grain %d, "
812 815 "row %d, labels \"%s\": %s\n", mci->mc_idx,
813 816 page_frame_number, offset_in_page,
814   - mci->csrows[row].grain, row, labels, msg);
  817 + grain, row, labels, msg);
815 818  
816 819 mci->ue_count++;
817 820 mci->csrows[row].ue_count++;
... ... @@ -883,6 +886,7 @@
883 886 chars = snprintf(pos, len + 1, "%s", label);
884 887 len -= chars;
885 888 pos += chars;
  889 +
886 890 chars = snprintf(pos, len + 1, "-%s",
887 891 mci->csrows[csrow].channels[channelb].dimm->label);
888 892  
... ... @@ -936,6 +940,7 @@
936 940  
937 941 mci->ce_count++;
938 942 mci->csrows[csrow].ce_count++;
  943 + mci->csrows[csrow].channels[channel].dimm->ce_count++;
939 944 mci->csrows[csrow].channels[channel].ce_count++;
940 945 }
941 946 EXPORT_SYMBOL(edac_mc_handle_fbd_ce);
drivers/edac/edac_mc_sysfs.c
... ... @@ -150,19 +150,19 @@
150 150 static ssize_t csrow_mem_type_show(struct csrow_info *csrow, char *data,
151 151 int private)
152 152 {
153   - return sprintf(data, "%s\n", mem_types[csrow->mtype]);
  153 + return sprintf(data, "%s\n", mem_types[csrow->channels[0].dimm->mtype]);
154 154 }
155 155  
156 156 static ssize_t csrow_dev_type_show(struct csrow_info *csrow, char *data,
157 157 int private)
158 158 {
159   - return sprintf(data, "%s\n", dev_types[csrow->dtype]);
  159 + return sprintf(data, "%s\n", dev_types[csrow->channels[0].dimm->dtype]);
160 160 }
161 161  
162 162 static ssize_t csrow_edac_mode_show(struct csrow_info *csrow, char *data,
163 163 int private)
164 164 {
165   - return sprintf(data, "%s\n", edac_caps[csrow->edac_mode]);
  165 + return sprintf(data, "%s\n", edac_caps[csrow->channels[0].dimm->edac_mode]);
166 166 }
167 167  
168 168 /* show/store functions for DIMM Label attributes */
drivers/edac/i3000_edac.c
... ... @@ -304,7 +304,7 @@
304 304 static int i3000_probe1(struct pci_dev *pdev, int dev_idx)
305 305 {
306 306 int rc;
307   - int i;
  307 + int i, j;
308 308 struct mem_ctl_info *mci = NULL;
309 309 unsigned long last_cumul_size;
310 310 int interleaved, nr_channels;
311 311  
312 312  
... ... @@ -386,19 +386,21 @@
386 386 cumul_size <<= 1;
387 387 debugf3("MC: %s(): (%d) cumul_size 0x%x\n",
388 388 __func__, i, cumul_size);
389   - if (cumul_size == last_cumul_size) {
390   - csrow->mtype = MEM_EMPTY;
  389 + if (cumul_size == last_cumul_size)
391 390 continue;
392   - }
393 391  
394 392 csrow->first_page = last_cumul_size;
395 393 csrow->last_page = cumul_size - 1;
396 394 csrow->nr_pages = cumul_size - last_cumul_size;
397 395 last_cumul_size = cumul_size;
398   - csrow->grain = I3000_DEAP_GRAIN;
399   - csrow->mtype = MEM_DDR2;
400   - csrow->dtype = DEV_UNKNOWN;
401   - csrow->edac_mode = EDAC_UNKNOWN;
  396 +
  397 + for (j = 0; j < nr_channels; j++) {
  398 + struct dimm_info *dimm = csrow->channels[j].dimm;
  399 + dimm->grain = I3000_DEAP_GRAIN;
  400 + dimm->mtype = MEM_DDR2;
  401 + dimm->dtype = DEV_UNKNOWN;
  402 + dimm->edac_mode = EDAC_UNKNOWN;
  403 + }
402 404 }
403 405  
404 406 /*
drivers/edac/i3200_edac.c
... ... @@ -319,7 +319,7 @@
319 319 static int i3200_probe1(struct pci_dev *pdev, int dev_idx)
320 320 {
321 321 int rc;
322   - int i;
  322 + int i, j;
323 323 struct mem_ctl_info *mci = NULL;
324 324 unsigned long last_page;
325 325 u16 drbs[I3200_CHANNELS][I3200_RANKS_PER_CHANNEL];
326 326  
327 327  
... ... @@ -375,20 +375,22 @@
375 375 i / I3200_RANKS_PER_CHANNEL,
376 376 i % I3200_RANKS_PER_CHANNEL);
377 377  
378   - if (nr_pages == 0) {
379   - csrow->mtype = MEM_EMPTY;
  378 + if (nr_pages == 0)
380 379 continue;
381   - }
382 380  
383 381 csrow->first_page = last_page + 1;
384 382 last_page += nr_pages;
385 383 csrow->last_page = last_page;
386 384 csrow->nr_pages = nr_pages;
387 385  
388   - csrow->grain = nr_pages << PAGE_SHIFT;
389   - csrow->mtype = MEM_DDR2;
390   - csrow->dtype = DEV_UNKNOWN;
391   - csrow->edac_mode = EDAC_UNKNOWN;
  386 + for (j = 0; j < nr_channels; j++) {
  387 + struct dimm_info *dimm = csrow->channels[j].dimm;
  388 +
  389 + dimm->grain = nr_pages << PAGE_SHIFT;
  390 + dimm->mtype = MEM_DDR2;
  391 + dimm->dtype = DEV_UNKNOWN;
  392 + dimm->edac_mode = EDAC_UNKNOWN;
  393 + }
392 394 }
393 395  
394 396 i3200_clear_error_info(mci);
drivers/edac/i5000_edac.c
... ... @@ -1268,25 +1268,23 @@
1268 1268 p_csrow->last_page = 9 + csrow * 20;
1269 1269 p_csrow->page_mask = 0xFFF;
1270 1270  
1271   - p_csrow->grain = 8;
1272   -
1273 1271 csrow_megs = 0;
1274 1272 for (channel = 0; channel < pvt->maxch; channel++) {
1275 1273 csrow_megs += pvt->dimm_info[csrow][channel].megabytes;
1276   - }
  1274 + p_csrow->channels[channel].dimm->grain = 8;
1277 1275  
1278   - p_csrow->nr_pages = csrow_megs << 8;
  1276 + /* Assume DDR2 for now */
  1277 + p_csrow->channels[channel].dimm->mtype = MEM_FB_DDR2;
1279 1278  
1280   - /* Assume DDR2 for now */
1281   - p_csrow->mtype = MEM_FB_DDR2;
  1279 + /* ask what device type on this row */
  1280 + if (MTR_DRAM_WIDTH(mtr))
  1281 + p_csrow->channels[channel].dimm->dtype = DEV_X8;
  1282 + else
  1283 + p_csrow->channels[channel].dimm->dtype = DEV_X4;
1282 1284  
1283   - /* ask what device type on this row */
1284   - if (MTR_DRAM_WIDTH(mtr))
1285   - p_csrow->dtype = DEV_X8;
1286   - else
1287   - p_csrow->dtype = DEV_X4;
1288   -
1289   - p_csrow->edac_mode = EDAC_S8ECD8ED;
  1285 + p_csrow->channels[channel].dimm->edac_mode = EDAC_S8ECD8ED;
  1286 + }
  1287 + p_csrow->nr_pages = csrow_megs << 8;
1290 1288  
1291 1289 empty = 0;
1292 1290 }
drivers/edac/i5100_edac.c
... ... @@ -428,12 +428,16 @@
428 428 const char *msg)
429 429 {
430 430 const int csrow = i5100_rank_to_csrow(mci, chan, rank);
  431 + char *label = NULL;
431 432  
  433 + if (mci->csrows[csrow].channels[0].dimm)
  434 + label = mci->csrows[csrow].channels[0].dimm->label;
  435 +
432 436 printk(KERN_ERR
433 437 "CE chan %d, bank %u, rank %u, syndrome 0x%lx, "
434 438 "cas %u, ras %u, csrow %u, label \"%s\": %s\n",
435 439 chan, bank, rank, syndrome, cas, ras,
436   - csrow, mci->csrows[csrow].channels[0].dimm->label, msg);
  440 + csrow, label, msg);
437 441  
438 442 mci->ce_count++;
439 443 mci->csrows[csrow].ce_count++;
440 444  
441 445  
... ... @@ -450,12 +454,16 @@
450 454 const char *msg)
451 455 {
452 456 const int csrow = i5100_rank_to_csrow(mci, chan, rank);
  457 + char *label = NULL;
453 458  
  459 + if (mci->csrows[csrow].channels[0].dimm)
  460 + label = mci->csrows[csrow].channels[0].dimm->label;
  461 +
454 462 printk(KERN_ERR
455 463 "UE chan %d, bank %u, rank %u, syndrome 0x%lx, "
456 464 "cas %u, ras %u, csrow %u, label \"%s\": %s\n",
457 465 chan, bank, rank, syndrome, cas, ras,
458   - csrow, mci->csrows[csrow].channels[0].dimm->label, msg);
  466 + csrow, label, msg);
459 467  
460 468 mci->ue_count++;
461 469 mci->csrows[csrow].ue_count++;
... ... @@ -837,6 +845,7 @@
837 845 int i;
838 846 unsigned long total_pages = 0UL;
839 847 struct i5100_priv *priv = mci->pvt_info;
  848 + struct dimm_info *dimm;
840 849  
841 850 for (i = 0; i < mci->nr_csrows; i++) {
842 851 const unsigned long npages = i5100_npages(mci, i);
843 852  
844 853  
845 854  
846 855  
847 856  
... ... @@ -852,27 +861,22 @@
852 861 */
853 862 mci->csrows[i].first_page = total_pages;
854 863 mci->csrows[i].last_page = total_pages + npages - 1;
855   - mci->csrows[i].page_mask = 0UL;
856   -
857 864 mci->csrows[i].nr_pages = npages;
858   - mci->csrows[i].grain = 32;
859 865 mci->csrows[i].csrow_idx = i;
860   - mci->csrows[i].dtype =
861   - (priv->mtr[chan][rank].width == 4) ? DEV_X4 : DEV_X8;
862   - mci->csrows[i].ue_count = 0;
863   - mci->csrows[i].ce_count = 0;
864   - mci->csrows[i].mtype = MEM_RDDR2;
865   - mci->csrows[i].edac_mode = EDAC_SECDED;
866 866 mci->csrows[i].mci = mci;
867 867 mci->csrows[i].nr_channels = 1;
868   - mci->csrows[i].channels[0].chan_idx = 0;
869   - mci->csrows[i].channels[0].ce_count = 0;
870 868 mci->csrows[i].channels[0].csrow = mci->csrows + i;
871   - snprintf(mci->csrows[i].channels[0].dimm->label,
872   - sizeof(mci->csrows[i].channels[0].dimm->label),
873   - "DIMM%u", i5100_rank_to_slot(mci, chan, rank));
874   -
875 869 total_pages += npages;
  870 +
  871 + dimm = mci->csrows[i].channels[0].dimm;
  872 + dimm->grain = 32;
  873 + dimm->dtype = (priv->mtr[chan][rank].width == 4) ?
  874 + DEV_X4 : DEV_X8;
  875 + dimm->mtype = MEM_RDDR2;
  876 + dimm->edac_mode = EDAC_SECDED;
  877 + snprintf(dimm->label, sizeof(dimm->label),
  878 + "DIMM%u",
  879 + i5100_rank_to_slot(mci, chan, rank));
876 880 }
877 881 }
878 882  
drivers/edac/i5400_edac.c
... ... @@ -1159,6 +1159,7 @@
1159 1159 int csrow_megs;
1160 1160 int channel;
1161 1161 int csrow;
  1162 + struct dimm_info *dimm;
1162 1163  
1163 1164 pvt = mci->pvt_info;
1164 1165  
1165 1166  
1166 1167  
... ... @@ -1184,24 +1185,17 @@
1184 1185 p_csrow->last_page = 9 + csrow * 20;
1185 1186 p_csrow->page_mask = 0xFFF;
1186 1187  
1187   - p_csrow->grain = 8;
1188   -
1189 1188 csrow_megs = 0;
1190   - for (channel = 0; channel < pvt->maxch; channel++)
  1189 + for (channel = 0; channel < pvt->maxch; channel++) {
1191 1190 csrow_megs += pvt->dimm_info[csrow][channel].megabytes;
1192 1191  
1193   - p_csrow->nr_pages = csrow_megs << 8;
1194   -
1195   - /* Assume DDR2 for now */
1196   - p_csrow->mtype = MEM_FB_DDR2;
1197   -
1198   - /* ask what device type on this row */
1199   - if (MTR_DRAM_WIDTH(mtr))
1200   - p_csrow->dtype = DEV_X8;
1201   - else
1202   - p_csrow->dtype = DEV_X4;
1203   -
1204   - p_csrow->edac_mode = EDAC_S8ECD8ED;
  1192 + p_csrow->nr_pages = csrow_megs << 8;
  1193 + dimm = p_csrow->channels[channel].dimm;
  1194 + dimm->grain = 8;
  1195 + dimm->dtype = MTR_DRAM_WIDTH(mtr) ? DEV_X8 : DEV_X4;
  1196 + dimm->mtype = MEM_RDDR2;
  1197 + dimm->edac_mode = EDAC_SECDED;
  1198 + }
1205 1199  
1206 1200 empty = 0;
1207 1201 }
drivers/edac/i7300_edac.c
... ... @@ -618,6 +618,7 @@
618 618 int slot, int ch, int branch,
619 619 struct i7300_dimm_info *dinfo,
620 620 struct csrow_info *p_csrow,
  621 + struct dimm_info *dimm,
621 622 u32 *nr_pages)
622 623 {
623 624 int mtr, ans, addrBits, channel;
624 625  
... ... @@ -663,10 +664,7 @@
663 664 debugf2("\t\tNUMCOL: %s\n", numcol_toString[MTR_DIMM_COLS(mtr)]);
664 665 debugf2("\t\tSIZE: %d MB\n", dinfo->megabytes);
665 666  
666   - p_csrow->grain = 8;
667   - p_csrow->mtype = MEM_FB_DDR2;
668 667 p_csrow->csrow_idx = slot;
669   - p_csrow->page_mask = 0;
670 668  
671 669 /*
672 670 * The type of error detection actually depends of the
673 671  
674 672  
675 673  
... ... @@ -677,15 +675,17 @@
677 675 * See datasheet Sections 7.3.6 to 7.3.8
678 676 */
679 677  
  678 + dimm->grain = 8;
  679 + dimm->mtype = MEM_FB_DDR2;
680 680 if (IS_SINGLE_MODE(pvt->mc_settings_a)) {
681   - p_csrow->edac_mode = EDAC_SECDED;
  681 + dimm->edac_mode = EDAC_SECDED;
682 682 debugf2("\t\tECC code is 8-byte-over-32-byte SECDED+ code\n");
683 683 } else {
684 684 debugf2("\t\tECC code is on Lockstep mode\n");
685 685 if (MTR_DRAM_WIDTH(mtr) == 8)
686   - p_csrow->edac_mode = EDAC_S8ECD8ED;
  686 + dimm->edac_mode = EDAC_S8ECD8ED;
687 687 else
688   - p_csrow->edac_mode = EDAC_S4ECD4ED;
  688 + dimm->edac_mode = EDAC_S4ECD4ED;
689 689 }
690 690  
691 691 /* ask what device type on this row */
692 692  
... ... @@ -694,9 +694,9 @@
694 694 IS_SCRBALGO_ENHANCED(pvt->mc_settings) ?
695 695 "enhanced" : "normal");
696 696  
697   - p_csrow->dtype = DEV_X8;
  697 + dimm->dtype = DEV_X8;
698 698 } else
699   - p_csrow->dtype = DEV_X4;
  699 + dimm->dtype = DEV_X4;
700 700  
701 701 return mtr;
702 702 }
... ... @@ -779,6 +779,7 @@
779 779 int mtr;
780 780 int ch, branch, slot, channel;
781 781 u32 last_page = 0, nr_pages;
  782 + struct dimm_info *dimm;
782 783  
783 784 pvt = mci->pvt_info;
784 785  
785 786  
786 787  
787 788  
... ... @@ -803,20 +804,24 @@
803 804 }
804 805  
805 806 /* Get the set of MTR[0-7] regs by each branch */
  807 + nr_pages = 0;
806 808 for (slot = 0; slot < MAX_SLOTS; slot++) {
807 809 int where = mtr_regs[slot];
808 810 for (branch = 0; branch < MAX_BRANCHES; branch++) {
809 811 pci_read_config_word(pvt->pci_dev_2x_0_fbd_branch[branch],
810 812 where,
811 813 &pvt->mtr[slot][branch]);
812   - for (ch = 0; ch < MAX_BRANCHES; ch++) {
  814 + for (ch = 0; ch < MAX_CH_PER_BRANCH; ch++) {
813 815 int channel = to_channel(ch, branch);
814 816  
815 817 dinfo = &pvt->dimm_info[slot][channel];
816 818 p_csrow = &mci->csrows[slot];
817 819  
  820 + dimm = p_csrow->channels[branch * MAX_CH_PER_BRANCH + ch].dimm;
  821 +
818 822 mtr = decode_mtr(pvt, slot, ch, branch,
819   - dinfo, p_csrow, &nr_pages);
  823 + dinfo, p_csrow, dimm,
  824 + &nr_pages);
820 825 /* if no DIMMS on this row, continue */
821 826 if (!MTR_DIMMS_PRESENT(mtr))
822 827 continue;
drivers/edac/i7core_edac.c
... ... @@ -592,7 +592,7 @@
592 592 return 0;
593 593 }
594 594  
595   -static int get_dimm_config(const struct mem_ctl_info *mci)
  595 +static int get_dimm_config(struct mem_ctl_info *mci)
596 596 {
597 597 struct i7core_pvt *pvt = mci->pvt_info;
598 598 struct csrow_info *csr;
... ... @@ -602,6 +602,7 @@
602 602 unsigned long last_page = 0;
603 603 enum edac_type mode;
604 604 enum mem_type mtype;
  605 + struct dimm_info *dimm;
605 606  
606 607 /* Get data from the MC register, function 0 */
607 608 pdev = pvt->pci_mcr[0];
... ... @@ -721,7 +722,6 @@
721 722 csr->nr_pages = npages;
722 723  
723 724 csr->page_mask = 0;
724   - csr->grain = 8;
725 725 csr->csrow_idx = csrow;
726 726 csr->nr_channels = 1;
727 727  
728 728  
729 729  
730 730  
731 731  
732 732  
... ... @@ -730,28 +730,27 @@
730 730  
731 731 pvt->csrow_map[i][j] = csrow;
732 732  
  733 + dimm = csr->channels[0].dimm;
733 734 switch (banks) {
734 735 case 4:
735   - csr->dtype = DEV_X4;
  736 + dimm->dtype = DEV_X4;
736 737 break;
737 738 case 8:
738   - csr->dtype = DEV_X8;
  739 + dimm->dtype = DEV_X8;
739 740 break;
740 741 case 16:
741   - csr->dtype = DEV_X16;
  742 + dimm->dtype = DEV_X16;
742 743 break;
743 744 default:
744   - csr->dtype = DEV_UNKNOWN;
  745 + dimm->dtype = DEV_UNKNOWN;
745 746 }
746 747  
747   - csr->edac_mode = mode;
748   - csr->mtype = mtype;
749   - snprintf(csr->channels[0].dimm->label,
750   - sizeof(csr->channels[0].dimm->label),
751   - "CPU#%uChannel#%u_DIMM#%u",
752   - pvt->i7core_dev->socket, i, j);
753   -
754   - csrow++;
  748 + snprintf(dimm->label, sizeof(dimm->label),
  749 + "CPU#%uChannel#%u_DIMM#%u",
  750 + pvt->i7core_dev->socket, i, j);
  751 + dimm->grain = 8;
  752 + dimm->edac_mode = mode;
  753 + dimm->mtype = mtype;
755 754 }
756 755  
757 756 pci_read_config_dword(pdev, MC_SAG_CH_0, &value[0]);
drivers/edac/i82443bxgx_edac.c
... ... @@ -12,7 +12,7 @@
12 12 * 440GX fix by Jason Uhlenkott <juhlenko@akamai.com>.
13 13 *
14 14 * Written with reference to 82443BX Host Bridge Datasheet:
15   - * http://download.intel.com/design/chipsets/datashts/29063301.pdf
  15 + * http://download.intel.com/design/chipsets/datashts/29063301.pdf
16 16 * references to this document given in [].
17 17 *
18 18 * This module doesn't support the 440LX, but it may be possible to
... ... @@ -189,6 +189,7 @@
189 189 enum mem_type mtype)
190 190 {
191 191 struct csrow_info *csrow;
  192 + struct dimm_info *dimm;
192 193 int index;
193 194 u8 drbar, dramc;
194 195 u32 row_base, row_high_limit, row_high_limit_last;
... ... @@ -197,6 +198,8 @@
197 198 row_high_limit_last = 0;
198 199 for (index = 0; index < mci->nr_csrows; index++) {
199 200 csrow = &mci->csrows[index];
  201 + dimm = csrow->channels[0].dimm;
  202 +
200 203 pci_read_config_byte(pdev, I82443BXGX_DRB + index, &drbar);
201 204 debugf1("MC%d: %s: %s() Row=%d DRB = %#0x\n",
202 205 mci->mc_idx, __FILE__, __func__, index, drbar);
203 206  
204 207  
... ... @@ -219,12 +222,12 @@
219 222 csrow->last_page = (row_high_limit >> PAGE_SHIFT) - 1;
220 223 csrow->nr_pages = csrow->last_page - csrow->first_page + 1;
221 224 /* EAP reports in 4kilobyte granularity [61] */
222   - csrow->grain = 1 << 12;
223   - csrow->mtype = mtype;
  225 + dimm->grain = 1 << 12;
  226 + dimm->mtype = mtype;
224 227 /* I don't think 440BX can tell you device type? FIXME? */
225   - csrow->dtype = DEV_UNKNOWN;
  228 + dimm->dtype = DEV_UNKNOWN;
226 229 /* Mode is global to all rows on 440BX */
227   - csrow->edac_mode = edac_mode;
  230 + dimm->edac_mode = edac_mode;
228 231 row_high_limit_last = row_high_limit;
229 232 }
230 233 }
drivers/edac/i82860_edac.c
... ... @@ -140,6 +140,7 @@
140 140 u16 value;
141 141 u32 cumul_size;
142 142 struct csrow_info *csrow;
  143 + struct dimm_info *dimm;
143 144 int index;
144 145  
145 146 pci_read_config_word(pdev, I82860_MCHCFG, &mchcfg_ddim);
... ... @@ -153,6 +154,8 @@
153 154 */
154 155 for (index = 0; index < mci->nr_csrows; index++) {
155 156 csrow = &mci->csrows[index];
  157 + dimm = csrow->channels[0].dimm;
  158 +
156 159 pci_read_config_word(pdev, I82860_GBA + index * 2, &value);
157 160 cumul_size = (value & I82860_GBA_MASK) <<
158 161 (I82860_GBA_SHIFT - PAGE_SHIFT);
... ... @@ -166,10 +169,10 @@
166 169 csrow->last_page = cumul_size - 1;
167 170 csrow->nr_pages = cumul_size - last_cumul_size;
168 171 last_cumul_size = cumul_size;
169   - csrow->grain = 1 << 12; /* I82860_EAP has 4KiB reolution */
170   - csrow->mtype = MEM_RMBS;
171   - csrow->dtype = DEV_UNKNOWN;
172   - csrow->edac_mode = mchcfg_ddim ? EDAC_SECDED : EDAC_NONE;
  172 + dimm->grain = 1 << 12; /* I82860_EAP has 4KiB reolution */
  173 + dimm->mtype = MEM_RMBS;
  174 + dimm->dtype = DEV_UNKNOWN;
  175 + dimm->edac_mode = mchcfg_ddim ? EDAC_SECDED : EDAC_NONE;
173 176 }
174 177 }
175 178  
drivers/edac/i82875p_edac.c
... ... @@ -342,11 +342,13 @@
342 342 void __iomem * ovrfl_window, u32 drc)
343 343 {
344 344 struct csrow_info *csrow;
  345 + struct dimm_info *dimm;
  346 + unsigned nr_chans = dual_channel_active(drc) + 1;
345 347 unsigned long last_cumul_size;
346 348 u8 value;
347 349 u32 drc_ddim; /* DRAM Data Integrity Mode 0=none,2=edac */
348 350 u32 cumul_size;
349   - int index;
  351 + int index, j;
350 352  
351 353 drc_ddim = (drc >> 18) & 0x1;
352 354 last_cumul_size = 0;
... ... @@ -371,10 +373,15 @@
371 373 csrow->last_page = cumul_size - 1;
372 374 csrow->nr_pages = cumul_size - last_cumul_size;
373 375 last_cumul_size = cumul_size;
374   - csrow->grain = 1 << 12; /* I82875P_EAP has 4KiB reolution */
375   - csrow->mtype = MEM_DDR;
376   - csrow->dtype = DEV_UNKNOWN;
377   - csrow->edac_mode = drc_ddim ? EDAC_SECDED : EDAC_NONE;
  376 +
  377 + for (j = 0; j < nr_chans; j++) {
  378 + dimm = csrow->channels[j].dimm;
  379 +
  380 + dimm->grain = 1 << 12; /* I82875P_EAP has 4KiB reolution */
  381 + dimm->mtype = MEM_DDR;
  382 + dimm->dtype = DEV_UNKNOWN;
  383 + dimm->edac_mode = drc_ddim ? EDAC_SECDED : EDAC_NONE;
  384 + }
378 385 }
379 386 }
380 387  
drivers/edac/i82975x_edac.c
... ... @@ -309,7 +309,7 @@
309 309 chan = (mci->csrows[row].nr_channels == 1) ? 0 : info->eap & 1;
310 310 offst = info->eap
311 311 & ((1 << PAGE_SHIFT) -
312   - (1 << mci->csrows[row].grain));
  312 + (1 << mci->csrows[row].channels[chan].dimm->grain));
313 313  
314 314 if (info->errsts & 0x0002)
315 315 edac_mc_handle_ue(mci, page, offst , row, "i82975x UE");
... ... @@ -372,6 +372,8 @@
372 372 u8 value;
373 373 u32 cumul_size;
374 374 int index, chan;
  375 + struct dimm_info *dimm;
  376 + enum dev_type dtype;
375 377  
376 378 last_cumul_size = 0;
377 379  
378 380  
... ... @@ -406,10 +408,17 @@
406 408 * [0-7] for single-channel; i.e. csrow->nr_channels = 1
407 409 * [0-3] for dual-channel; i.e. csrow->nr_channels = 2
408 410 */
409   - for (chan = 0; chan < csrow->nr_channels; chan++)
  411 + dtype = i82975x_dram_type(mch_window, index);
  412 + for (chan = 0; chan < csrow->nr_channels; chan++) {
  413 + dimm = mci->csrows[index].channels[chan].dimm;
410 414 strncpy(csrow->channels[chan].dimm->label,
411 415 labels[(index >> 1) + (chan * 2)],
412 416 EDAC_MC_LABEL_LEN);
  417 + dimm->grain = 1 << 7; /* 128Byte cache-line resolution */
  418 + dimm->dtype = i82975x_dram_type(mch_window, index);
  419 + dimm->mtype = MEM_DDR2; /* I82975x supports only DDR2 */
  420 + dimm->edac_mode = EDAC_SECDED; /* only supported */
  421 + }
413 422  
414 423 if (cumul_size == last_cumul_size)
415 424 continue; /* not populated */
... ... @@ -418,10 +427,6 @@
418 427 csrow->last_page = cumul_size - 1;
419 428 csrow->nr_pages = cumul_size - last_cumul_size;
420 429 last_cumul_size = cumul_size;
421   - csrow->grain = 1 << 7; /* 128Byte cache-line resolution */
422   - csrow->mtype = MEM_DDR2; /* I82975x supports only DDR2 */
423   - csrow->dtype = i82975x_dram_type(mch_window, index);
424   - csrow->edac_mode = EDAC_SECDED; /* only supported */
425 430 }
426 431 }
427 432  
drivers/edac/mpc85xx_edac.c
... ... @@ -883,6 +883,7 @@
883 883 {
884 884 struct mpc85xx_mc_pdata *pdata = mci->pvt_info;
885 885 struct csrow_info *csrow;
  886 + struct dimm_info *dimm;
886 887 u32 sdram_ctl;
887 888 u32 sdtype;
888 889 enum mem_type mtype;
... ... @@ -929,6 +930,8 @@
929 930 u32 end;
930 931  
931 932 csrow = &mci->csrows[index];
  933 + dimm = csrow->channels[0].dimm;
  934 +
932 935 cs_bnds = in_be32(pdata->mc_vbase + MPC85XX_MC_CS_BNDS_0 +
933 936 (index * MPC85XX_MC_CS_BNDS_OFS));
934 937  
935 938  
... ... @@ -945,12 +948,12 @@
945 948 csrow->first_page = start;
946 949 csrow->last_page = end;
947 950 csrow->nr_pages = end + 1 - start;
948   - csrow->grain = 8;
949   - csrow->mtype = mtype;
950   - csrow->dtype = DEV_UNKNOWN;
  951 + dimm->grain = 8;
  952 + dimm->mtype = mtype;
  953 + dimm->dtype = DEV_UNKNOWN;
951 954 if (sdram_ctl & DSC_X32_EN)
952   - csrow->dtype = DEV_X32;
953   - csrow->edac_mode = EDAC_SECDED;
  955 + dimm->dtype = DEV_X32;
  956 + dimm->edac_mode = EDAC_SECDED;
954 957 }
955 958 }
956 959  
drivers/edac/mv64x60_edac.c
... ... @@ -656,6 +656,8 @@
656 656 struct mv64x60_mc_pdata *pdata)
657 657 {
658 658 struct csrow_info *csrow;
  659 + struct dimm_info *dimm;
  660 +
659 661 u32 devtype;
660 662 u32 ctl;
661 663  
662 664  
663 665  
664 666  
665 667  
666 668  
667 669  
668 670  
... ... @@ -664,30 +666,30 @@
664 666 ctl = in_le32(pdata->mc_vbase + MV64X60_SDRAM_CONFIG);
665 667  
666 668 csrow = &mci->csrows[0];
667   - csrow->first_page = 0;
  669 + dimm = csrow->channels[0].dimm;
668 670 csrow->nr_pages = pdata->total_mem >> PAGE_SHIFT;
669 671 csrow->last_page = csrow->first_page + csrow->nr_pages - 1;
670   - csrow->grain = 8;
  672 + dimm->grain = 8;
671 673  
672   - csrow->mtype = (ctl & MV64X60_SDRAM_REGISTERED) ? MEM_RDDR : MEM_DDR;
  674 + dimm->mtype = (ctl & MV64X60_SDRAM_REGISTERED) ? MEM_RDDR : MEM_DDR;
673 675  
674 676 devtype = (ctl >> 20) & 0x3;
675 677 switch (devtype) {
676 678 case 0x0:
677   - csrow->dtype = DEV_X32;
  679 + dimm->dtype = DEV_X32;
678 680 break;
679 681 case 0x2: /* could be X8 too, but no way to tell */
680   - csrow->dtype = DEV_X16;
  682 + dimm->dtype = DEV_X16;
681 683 break;
682 684 case 0x3:
683   - csrow->dtype = DEV_X4;
  685 + dimm->dtype = DEV_X4;
684 686 break;
685 687 default:
686   - csrow->dtype = DEV_UNKNOWN;
  688 + dimm->dtype = DEV_UNKNOWN;
687 689 break;
688 690 }
689 691  
690   - csrow->edac_mode = EDAC_SECDED;
  692 + dimm->edac_mode = EDAC_SECDED;
691 693 }
692 694  
693 695 static int __devinit mv64x60_mc_err_probe(struct platform_device *pdev)
drivers/edac/pasemi_edac.c
... ... @@ -135,11 +135,13 @@
135 135 enum edac_type edac_mode)
136 136 {
137 137 struct csrow_info *csrow;
  138 + struct dimm_info *dimm;
138 139 u32 rankcfg;
139 140 int index;
140 141  
141 142 for (index = 0; index < mci->nr_csrows; index++) {
142 143 csrow = &mci->csrows[index];
  144 + dimm = csrow->channels[0].dimm;
143 145  
144 146 pci_read_config_dword(pdev,
145 147 MCDRAM_RANKCFG + (index * 12),
... ... @@ -177,10 +179,10 @@
177 179 csrow->last_page = csrow->first_page + csrow->nr_pages - 1;
178 180 last_page_in_mmc += csrow->nr_pages;
179 181 csrow->page_mask = 0;
180   - csrow->grain = PASEMI_EDAC_ERROR_GRAIN;
181   - csrow->mtype = MEM_DDR;
182   - csrow->dtype = DEV_UNKNOWN;
183   - csrow->edac_mode = edac_mode;
  182 + dimm->grain = PASEMI_EDAC_ERROR_GRAIN;
  183 + dimm->mtype = MEM_DDR;
  184 + dimm->dtype = DEV_UNKNOWN;
  185 + dimm->edac_mode = edac_mode;
184 186 }
185 187 return 0;
186 188 }
drivers/edac/ppc4xx_edac.c
... ... @@ -895,7 +895,7 @@
895 895 enum mem_type mtype;
896 896 enum dev_type dtype;
897 897 enum edac_type edac_mode;
898   - int row;
  898 + int row, j;
899 899 u32 mbxcf, size;
900 900 static u32 ppc4xx_last_page;
901 901  
902 902  
903 903  
904 904  
905 905  
... ... @@ -975,15 +975,18 @@
975 975 * possible values would be the PLB width (16), the
976 976 * page size (PAGE_SIZE) or the memory width (2 or 4).
977 977 */
  978 + for (j = 0; j < csi->nr_channels; j++) {
  979 + struct dimm_info *dimm = csi->channels[j].dimm;
978 980  
979   - csi->grain = 1;
  981 + dimm->grain = 1;
980 982  
981   - csi->mtype = mtype;
982   - csi->dtype = dtype;
  983 + dimm->mtype = mtype;
  984 + dimm->dtype = dtype;
983 985  
984   - csi->edac_mode = edac_mode;
  986 + dimm->edac_mode = edac_mode;
985 987  
986 988 ppc4xx_last_page += csi->nr_pages;
  989 + }
987 990 }
988 991  
989 992 done:
drivers/edac/r82600_edac.c
... ... @@ -216,6 +216,7 @@
216 216 u8 dramcr)
217 217 {
218 218 struct csrow_info *csrow;
  219 + struct dimm_info *dimm;
219 220 int index;
220 221 u8 drbar; /* SDRAM Row Boundary Address Register */
221 222 u32 row_high_limit, row_high_limit_last;
... ... @@ -227,6 +228,7 @@
227 228  
228 229 for (index = 0; index < mci->nr_csrows; index++) {
229 230 csrow = &mci->csrows[index];
  231 + dimm = csrow->channels[0].dimm;
230 232  
231 233 /* find the DRAM Chip Select Base address and mask */
232 234 pci_read_config_byte(pdev, R82600_DRBA + index, &drbar);
233 235  
234 236  
... ... @@ -250,13 +252,13 @@
250 252 csrow->nr_pages = csrow->last_page - csrow->first_page + 1;
251 253 /* Error address is top 19 bits - so granularity is *
252 254 * 14 bits */
253   - csrow->grain = 1 << 14;
254   - csrow->mtype = reg_sdram ? MEM_RDDR : MEM_DDR;
  255 + dimm->grain = 1 << 14;
  256 + dimm->mtype = reg_sdram ? MEM_RDDR : MEM_DDR;
255 257 /* FIXME - check that this is unknowable with this chipset */
256   - csrow->dtype = DEV_UNKNOWN;
  258 + dimm->dtype = DEV_UNKNOWN;
257 259  
258 260 /* Mode is global on 82600 */
259   - csrow->edac_mode = ecc_on ? EDAC_SECDED : EDAC_NONE;
  261 + dimm->edac_mode = ecc_on ? EDAC_SECDED : EDAC_NONE;
260 262 row_high_limit_last = row_high_limit;
261 263 }
262 264 }
drivers/edac/sb_edac.c
... ... @@ -551,7 +551,7 @@
551 551 return 0;
552 552 }
553 553  
554   -static int get_dimm_config(const struct mem_ctl_info *mci)
  554 +static int get_dimm_config(struct mem_ctl_info *mci)
555 555 {
556 556 struct sbridge_pvt *pvt = mci->pvt_info;
557 557 struct csrow_info *csr;
... ... @@ -561,6 +561,7 @@
561 561 u32 reg;
562 562 enum edac_type mode;
563 563 enum mem_type mtype;
  564 + struct dimm_info *dimm;
564 565  
565 566 pci_read_config_dword(pvt->pci_br, SAD_TARGET, &reg);
566 567 pvt->sbridge_dev->source_id = SOURCE_ID(reg);
... ... @@ -612,6 +613,7 @@
612 613 /* On all supported DDR3 DIMM types, there are 8 banks available */
613 614 banks = 8;
614 615  
  616 + dimm = mci->dimms;
615 617 for (i = 0; i < NUM_CHANNELS; i++) {
616 618 u32 mtr;
617 619  
618 620  
619 621  
620 622  
621 623  
622 624  
623 625  
624 626  
... ... @@ -634,29 +636,30 @@
634 636 pvt->sbridge_dev->mc, i, j,
635 637 size, npages,
636 638 banks, ranks, rows, cols);
637   - csr = &mci->csrows[csrow];
638 639  
  640 + /*
  641 + * Fake stuff. This controller doesn't see
  642 + * csrows.
  643 + */
  644 + csr = &mci->csrows[csrow];
639 645 csr->first_page = last_page;
640 646 csr->last_page = last_page + npages - 1;
641   - csr->page_mask = 0UL; /* Unused */
642 647 csr->nr_pages = npages;
643   - csr->grain = 32;
644 648 csr->csrow_idx = csrow;
645   - csr->dtype = (banks == 8) ? DEV_X8 : DEV_X4;
646   - csr->ce_count = 0;
647   - csr->ue_count = 0;
648   - csr->mtype = mtype;
649   - csr->edac_mode = mode;
650 649 csr->nr_channels = 1;
651 650 csr->channels[0].chan_idx = i;
652   - csr->channels[0].ce_count = 0;
653 651 pvt->csrow_map[i][j] = csrow;
654   - snprintf(csr->channels[0].dimm->label,
655   - sizeof(csr->channels[0].dimm->label),
656   - "CPU_SrcID#%u_Channel#%u_DIMM#%u",
657   - pvt->sbridge_dev->source_id, i, j);
658 652 last_page += npages;
659 653 csrow++;
  654 +
  655 + csr->channels[0].dimm = dimm;
  656 + dimm->grain = 32;
  657 + dimm->dtype = (banks == 8) ? DEV_X8 : DEV_X4;
  658 + dimm->mtype = mtype;
  659 + dimm->edac_mode = mode;
  660 + snprintf(dimm->label, sizeof(dimm->label),
  661 + "CPU_SrcID#%u_Channel#%u_DIMM#%u",
  662 + pvt->sbridge_dev->source_id, i, j);
660 663 }
661 664 }
662 665 }
drivers/edac/tile_edac.c
... ... @@ -84,6 +84,7 @@
84 84 struct csrow_info *csrow = &mci->csrows[0];
85 85 struct tile_edac_priv *priv = mci->pvt_info;
86 86 struct mshim_mem_info mem_info;
  87 + struct dimm_info *dimm = csrow->channels[0].dimm;
87 88  
88 89 if (hv_dev_pread(priv->hv_devhdl, 0, (HV_VirtAddr)&mem_info,
89 90 sizeof(struct mshim_mem_info), MSHIM_MEM_INFO_OFF) !=
90 91  
91 92  
92 93  
... ... @@ -93,16 +94,16 @@
93 94 }
94 95  
95 96 if (mem_info.mem_ecc)
96   - csrow->edac_mode = EDAC_SECDED;
  97 + dimm->edac_mode = EDAC_SECDED;
97 98 else
98   - csrow->edac_mode = EDAC_NONE;
  99 + dimm->edac_mode = EDAC_NONE;
99 100 switch (mem_info.mem_type) {
100 101 case DDR2:
101   - csrow->mtype = MEM_DDR2;
  102 + dimm->mtype = MEM_DDR2;
102 103 break;
103 104  
104 105 case DDR3:
105   - csrow->mtype = MEM_DDR3;
  106 + dimm->mtype = MEM_DDR3;
106 107 break;
107 108  
108 109 default:
... ... @@ -112,8 +113,8 @@
112 113 csrow->first_page = 0;
113 114 csrow->nr_pages = mem_info.mem_size >> PAGE_SHIFT;
114 115 csrow->last_page = csrow->first_page + csrow->nr_pages - 1;
115   - csrow->grain = TILE_EDAC_ERROR_GRAIN;
116   - csrow->dtype = DEV_UNKNOWN;
  116 + dimm->grain = TILE_EDAC_ERROR_GRAIN;
  117 + dimm->dtype = DEV_UNKNOWN;
117 118  
118 119 return 0;
119 120 }
drivers/edac/x38_edac.c
... ... @@ -317,7 +317,7 @@
317 317 static int x38_probe1(struct pci_dev *pdev, int dev_idx)
318 318 {
319 319 int rc;
320   - int i;
  320 + int i, j;
321 321 struct mem_ctl_info *mci = NULL;
322 322 unsigned long last_page;
323 323 u16 drbs[X38_CHANNELS][X38_RANKS_PER_CHANNEL];
324 324  
325 325  
... ... @@ -372,20 +372,21 @@
372 372 i / X38_RANKS_PER_CHANNEL,
373 373 i % X38_RANKS_PER_CHANNEL);
374 374  
375   - if (nr_pages == 0) {
376   - csrow->mtype = MEM_EMPTY;
  375 + if (nr_pages == 0)
377 376 continue;
378   - }
379 377  
380 378 csrow->first_page = last_page + 1;
381 379 last_page += nr_pages;
382 380 csrow->last_page = last_page;
383 381 csrow->nr_pages = nr_pages;
384 382  
385   - csrow->grain = nr_pages << PAGE_SHIFT;
386   - csrow->mtype = MEM_DDR2;
387   - csrow->dtype = DEV_UNKNOWN;
388   - csrow->edac_mode = EDAC_UNKNOWN;
  383 + for (j = 0; j < x38_channel_num; j++) {
  384 + struct dimm_info *dimm = csrow->channels[j].dimm;
  385 + dimm->grain = nr_pages << PAGE_SHIFT;
  386 + dimm->mtype = MEM_DDR2;
  387 + dimm->dtype = DEV_UNKNOWN;
  388 + dimm->edac_mode = EDAC_UNKNOWN;
  389 + }
389 390 }
390 391  
391 392 x38_clear_error_info(mci);
include/linux/edac.h
... ... @@ -318,6 +318,13 @@
318 318 unsigned memory_controller;
319 319 unsigned csrow;
320 320 unsigned csrow_channel;
  321 +
  322 + u32 grain; /* granularity of reported error in bytes */
  323 + enum dev_type dtype; /* memory device type */
  324 + enum mem_type mtype; /* memory dimm type */
  325 + enum edac_type edac_mode; /* EDAC mode for this dimm */
  326 +
  327 + u32 ce_count; /* Correctable Errors for this dimm */
321 328 };
322 329  
323 330 /**
324 331  
325 332  
... ... @@ -343,19 +350,17 @@
343 350 };
344 351  
345 352 struct csrow_info {
346   - unsigned long first_page; /* first page number in dimm */
347   - unsigned long last_page; /* last page number in dimm */
  353 + unsigned long first_page; /* first page number in csrow */
  354 + unsigned long last_page; /* last page number in csrow */
  355 + u32 nr_pages; /* number of pages in csrow */
348 356 unsigned long page_mask; /* used for interleaving -
349 357 * 0UL for non intlv
350 358 */
351   - u32 nr_pages; /* number of pages in csrow */
352   - u32 grain; /* granularity of reported error in bytes */
353   - int csrow_idx; /* the chip-select row */
354   - enum dev_type dtype; /* memory device type */
  359 + int csrow_idx; /* the chip-select row */
  360 +
355 361 u32 ue_count; /* Uncorrectable Errors for this csrow */
356 362 u32 ce_count; /* Correctable Errors for this csrow */
357   - enum mem_type mtype; /* memory csrow type */
358   - enum edac_type edac_mode; /* EDAC mode for this csrow */
  363 +
359 364 struct mem_ctl_info *mci; /* the parent */
360 365  
361 366 struct kobject kobj; /* sysfs kobject for this csrow */