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