diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-18 13:37:40 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-18 13:37:40 -0400 |
commit | e16b396ce314b2bcdfe6c173fe075bf8e3432368 (patch) | |
tree | 640f0f56f2ea676647af4eb42d32fa56be2ee549 /drivers/edac | |
parent | 7fd23a24717a327a66f3c32d11a20a2f169c824f (diff) | |
parent | e6e8dd5055a974935af1398c8648d4a9359b0ecb (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial: (47 commits)
doc: CONFIG_UNEVICTABLE_LRU doesn't exist anymore
Update cpuset info & webiste for cgroups
dcdbas: force SMI to happen when expected
arch/arm/Kconfig: remove one to many l's in the word.
asm-generic/user.h: Fix spelling in comment
drm: fix printk typo 'sracth'
Remove one to many n's in a word
Documentation/filesystems/romfs.txt: fixing link to genromfs
drivers:scsi Change printk typo initate -> initiate
serial, pch uart: Remove duplicate inclusion of linux/pci.h header
fs/eventpoll.c: fix spelling
mm: Fix out-of-date comments which refers non-existent functions
drm: Fix printk typo 'failled'
coh901318.c: Change initate to initiate.
mbox-db5500.c Change initate to initiate.
edac: correct i82975x error-info reported
edac: correct i82975x mci initialisation
edac: correct commented info
fs: update comments to point correct document
target: remove duplicate include of target/target_core_device.h from drivers/target/target_core_hba.c
...
Trivial conflict in fs/eventpoll.c (spelling vs addition)
Diffstat (limited to 'drivers/edac')
-rw-r--r-- | drivers/edac/i7300_edac.c | 2 | ||||
-rw-r--r-- | drivers/edac/i82975x_edac.c | 69 |
2 files changed, 45 insertions, 26 deletions
diff --git a/drivers/edac/i7300_edac.c b/drivers/edac/i7300_edac.c index 05523b504271..76d1f576cdc8 100644 --- a/drivers/edac/i7300_edac.c +++ b/drivers/edac/i7300_edac.c | |||
@@ -162,7 +162,7 @@ static struct edac_pci_ctl_info *i7300_pci; | |||
162 | #define AMBPRESENT_0 0x64 | 162 | #define AMBPRESENT_0 0x64 |
163 | #define AMBPRESENT_1 0x66 | 163 | #define AMBPRESENT_1 0x66 |
164 | 164 | ||
165 | const static u16 mtr_regs[MAX_SLOTS] = { | 165 | static const u16 mtr_regs[MAX_SLOTS] = { |
166 | 0x80, 0x84, 0x88, 0x8c, | 166 | 0x80, 0x84, 0x88, 0x8c, |
167 | 0x82, 0x86, 0x8a, 0x8e | 167 | 0x82, 0x86, 0x8a, 0x8e |
168 | }; | 168 | }; |
diff --git a/drivers/edac/i82975x_edac.c b/drivers/edac/i82975x_edac.c index 3218819b7286..92e65e7038e9 100644 --- a/drivers/edac/i82975x_edac.c +++ b/drivers/edac/i82975x_edac.c | |||
@@ -160,8 +160,8 @@ NOTE: Only ONE of the three must be enabled | |||
160 | * 3:2 Rank 1 architecture | 160 | * 3:2 Rank 1 architecture |
161 | * 1:0 Rank 0 architecture | 161 | * 1:0 Rank 0 architecture |
162 | * | 162 | * |
163 | * 00 => x16 devices; i.e 4 banks | 163 | * 00 => 4 banks |
164 | * 01 => x8 devices; i.e 8 banks | 164 | * 01 => 8 banks |
165 | */ | 165 | */ |
166 | #define I82975X_C0BNKARC 0x10e | 166 | #define I82975X_C0BNKARC 0x10e |
167 | #define I82975X_C1BNKARC 0x18e | 167 | #define I82975X_C1BNKARC 0x18e |
@@ -278,6 +278,7 @@ static int i82975x_process_error_info(struct mem_ctl_info *mci, | |||
278 | struct i82975x_error_info *info, int handle_errors) | 278 | struct i82975x_error_info *info, int handle_errors) |
279 | { | 279 | { |
280 | int row, multi_chan, chan; | 280 | int row, multi_chan, chan; |
281 | unsigned long offst, page; | ||
281 | 282 | ||
282 | multi_chan = mci->csrows[0].nr_channels - 1; | 283 | multi_chan = mci->csrows[0].nr_channels - 1; |
283 | 284 | ||
@@ -292,17 +293,19 @@ static int i82975x_process_error_info(struct mem_ctl_info *mci, | |||
292 | info->errsts = info->errsts2; | 293 | info->errsts = info->errsts2; |
293 | } | 294 | } |
294 | 295 | ||
295 | chan = info->eap & 1; | 296 | page = (unsigned long) info->eap; |
296 | info->eap >>= 1; | 297 | if (info->xeap & 1) |
297 | if (info->xeap ) | 298 | page |= 0x100000000ul; |
298 | info->eap |= 0x80000000; | 299 | chan = page & 1; |
299 | info->eap >>= PAGE_SHIFT; | 300 | page >>= 1; |
300 | row = edac_mc_find_csrow_by_page(mci, info->eap); | 301 | offst = page & ((1 << PAGE_SHIFT) - 1); |
302 | page >>= PAGE_SHIFT; | ||
303 | row = edac_mc_find_csrow_by_page(mci, page); | ||
301 | 304 | ||
302 | if (info->errsts & 0x0002) | 305 | if (info->errsts & 0x0002) |
303 | edac_mc_handle_ue(mci, info->eap, 0, row, "i82975x UE"); | 306 | edac_mc_handle_ue(mci, page, offst , row, "i82975x UE"); |
304 | else | 307 | else |
305 | edac_mc_handle_ce(mci, info->eap, 0, info->derrsyn, row, | 308 | edac_mc_handle_ce(mci, page, offst, info->derrsyn, row, |
306 | multi_chan ? chan : 0, | 309 | multi_chan ? chan : 0, |
307 | "i82975x CE"); | 310 | "i82975x CE"); |
308 | 311 | ||
@@ -344,11 +347,7 @@ static int dual_channel_active(void __iomem *mch_window) | |||
344 | static enum dev_type i82975x_dram_type(void __iomem *mch_window, int rank) | 347 | static enum dev_type i82975x_dram_type(void __iomem *mch_window, int rank) |
345 | { | 348 | { |
346 | /* | 349 | /* |
347 | * ASUS P5W DH either does not program this register or programs | 350 | * ECC is possible on i92975x ONLY with DEV_X8 |
348 | * it wrong! | ||
349 | * ECC is possible on i92975x ONLY with DEV_X8 which should mean 'val' | ||
350 | * for each rank should be 01b - the LSB of the word should be 0x55; | ||
351 | * but it reads 0! | ||
352 | */ | 351 | */ |
353 | return DEV_X8; | 352 | return DEV_X8; |
354 | } | 353 | } |
@@ -356,11 +355,15 @@ static enum dev_type i82975x_dram_type(void __iomem *mch_window, int rank) | |||
356 | static void i82975x_init_csrows(struct mem_ctl_info *mci, | 355 | static void i82975x_init_csrows(struct mem_ctl_info *mci, |
357 | struct pci_dev *pdev, void __iomem *mch_window) | 356 | struct pci_dev *pdev, void __iomem *mch_window) |
358 | { | 357 | { |
358 | static const char *labels[4] = { | ||
359 | "DIMM A1", "DIMM A2", | ||
360 | "DIMM B1", "DIMM B2" | ||
361 | }; | ||
359 | struct csrow_info *csrow; | 362 | struct csrow_info *csrow; |
360 | unsigned long last_cumul_size; | 363 | unsigned long last_cumul_size; |
361 | u8 value; | 364 | u8 value; |
362 | u32 cumul_size; | 365 | u32 cumul_size; |
363 | int index; | 366 | int index, chan; |
364 | 367 | ||
365 | last_cumul_size = 0; | 368 | last_cumul_size = 0; |
366 | 369 | ||
@@ -369,11 +372,7 @@ static void i82975x_init_csrows(struct mem_ctl_info *mci, | |||
369 | * The dram row boundary (DRB) reg values are boundary address | 372 | * The dram row boundary (DRB) reg values are boundary address |
370 | * for each DRAM row with a granularity of 32 or 64MB (single/dual | 373 | * for each DRAM row with a granularity of 32 or 64MB (single/dual |
371 | * channel operation). DRB regs are cumulative; therefore DRB7 will | 374 | * channel operation). DRB regs are cumulative; therefore DRB7 will |
372 | * contain the total memory contained in all eight rows. | 375 | * contain the total memory contained in all rows. |
373 | * | ||
374 | * FIXME: | ||
375 | * EDAC currently works for Dual-channel Interleaved configuration. | ||
376 | * Other configurations, which the chip supports, need fixing/testing. | ||
377 | * | 376 | * |
378 | */ | 377 | */ |
379 | 378 | ||
@@ -384,8 +383,26 @@ static void i82975x_init_csrows(struct mem_ctl_info *mci, | |||
384 | ((index >= 4) ? 0x80 : 0)); | 383 | ((index >= 4) ? 0x80 : 0)); |
385 | cumul_size = value; | 384 | cumul_size = value; |
386 | cumul_size <<= (I82975X_DRB_SHIFT - PAGE_SHIFT); | 385 | cumul_size <<= (I82975X_DRB_SHIFT - PAGE_SHIFT); |
386 | /* | ||
387 | * Adjust cumul_size w.r.t number of channels | ||
388 | * | ||
389 | */ | ||
390 | if (csrow->nr_channels > 1) | ||
391 | cumul_size <<= 1; | ||
387 | debugf3("%s(): (%d) cumul_size 0x%x\n", __func__, index, | 392 | debugf3("%s(): (%d) cumul_size 0x%x\n", __func__, index, |
388 | cumul_size); | 393 | cumul_size); |
394 | |||
395 | /* | ||
396 | * Initialise dram labels | ||
397 | * index values: | ||
398 | * [0-7] for single-channel; i.e. csrow->nr_channels = 1 | ||
399 | * [0-3] for dual-channel; i.e. csrow->nr_channels = 2 | ||
400 | */ | ||
401 | for (chan = 0; chan < csrow->nr_channels; chan++) | ||
402 | strncpy(csrow->channels[chan].label, | ||
403 | labels[(index >> 1) + (chan * 2)], | ||
404 | EDAC_MC_LABEL_LEN); | ||
405 | |||
389 | if (cumul_size == last_cumul_size) | 406 | if (cumul_size == last_cumul_size) |
390 | continue; /* not populated */ | 407 | continue; /* not populated */ |
391 | 408 | ||
@@ -393,8 +410,8 @@ static void i82975x_init_csrows(struct mem_ctl_info *mci, | |||
393 | csrow->last_page = cumul_size - 1; | 410 | csrow->last_page = cumul_size - 1; |
394 | csrow->nr_pages = cumul_size - last_cumul_size; | 411 | csrow->nr_pages = cumul_size - last_cumul_size; |
395 | last_cumul_size = cumul_size; | 412 | last_cumul_size = cumul_size; |
396 | csrow->grain = 1 << 7; /* I82975X_EAP has 128B resolution */ | 413 | csrow->grain = 1 << 6; /* I82975X_EAP has 64B resolution */ |
397 | csrow->mtype = MEM_DDR; /* i82975x supports only DDR2 */ | 414 | csrow->mtype = MEM_DDR2; /* I82975x supports only DDR2 */ |
398 | csrow->dtype = i82975x_dram_type(mch_window, index); | 415 | csrow->dtype = i82975x_dram_type(mch_window, index); |
399 | csrow->edac_mode = EDAC_SECDED; /* only supported */ | 416 | csrow->edac_mode = EDAC_SECDED; /* only supported */ |
400 | } | 417 | } |
@@ -515,18 +532,20 @@ static int i82975x_probe1(struct pci_dev *pdev, int dev_idx) | |||
515 | 532 | ||
516 | debugf3("%s(): init mci\n", __func__); | 533 | debugf3("%s(): init mci\n", __func__); |
517 | mci->dev = &pdev->dev; | 534 | mci->dev = &pdev->dev; |
518 | mci->mtype_cap = MEM_FLAG_DDR; | 535 | mci->mtype_cap = MEM_FLAG_DDR2; |
519 | mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_SECDED; | 536 | mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_SECDED; |
520 | mci->edac_cap = EDAC_FLAG_NONE | EDAC_FLAG_SECDED; | 537 | mci->edac_cap = EDAC_FLAG_NONE | EDAC_FLAG_SECDED; |
521 | mci->mod_name = EDAC_MOD_STR; | 538 | mci->mod_name = EDAC_MOD_STR; |
522 | mci->mod_ver = I82975X_REVISION; | 539 | mci->mod_ver = I82975X_REVISION; |
523 | mci->ctl_name = i82975x_devs[dev_idx].ctl_name; | 540 | mci->ctl_name = i82975x_devs[dev_idx].ctl_name; |
541 | mci->dev_name = pci_name(pdev); | ||
524 | mci->edac_check = i82975x_check; | 542 | mci->edac_check = i82975x_check; |
525 | mci->ctl_page_to_phys = NULL; | 543 | mci->ctl_page_to_phys = NULL; |
526 | debugf3("%s(): init pvt\n", __func__); | 544 | debugf3("%s(): init pvt\n", __func__); |
527 | pvt = (struct i82975x_pvt *) mci->pvt_info; | 545 | pvt = (struct i82975x_pvt *) mci->pvt_info; |
528 | pvt->mch_window = mch_window; | 546 | pvt->mch_window = mch_window; |
529 | i82975x_init_csrows(mci, pdev, mch_window); | 547 | i82975x_init_csrows(mci, pdev, mch_window); |
548 | mci->scrub_mode = SCRUB_HW_SRC; | ||
530 | i82975x_get_error_info(mci, &discard); /* clear counters */ | 549 | i82975x_get_error_info(mci, &discard); /* clear counters */ |
531 | 550 | ||
532 | /* finalize this instance of memory controller with edac core */ | 551 | /* finalize this instance of memory controller with edac core */ |
@@ -664,7 +683,7 @@ module_init(i82975x_init); | |||
664 | module_exit(i82975x_exit); | 683 | module_exit(i82975x_exit); |
665 | 684 | ||
666 | MODULE_LICENSE("GPL"); | 685 | MODULE_LICENSE("GPL"); |
667 | MODULE_AUTHOR("Arvind R. <arvind@acarlab.com>"); | 686 | MODULE_AUTHOR("Arvind R. <arvino55@gmail.com>"); |
668 | MODULE_DESCRIPTION("MC support for Intel 82975 memory hub controllers"); | 687 | MODULE_DESCRIPTION("MC support for Intel 82975 memory hub controllers"); |
669 | 688 | ||
670 | module_param(edac_op_state, int, 0444); | 689 | module_param(edac_op_state, int, 0444); |