aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/edac/x38_edac.c
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
commit8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch)
treea8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /drivers/edac/x38_edac.c
parent406089d01562f1e2bf9f089fd7637009ebaad589 (diff)
Patched in Tegra support.
Diffstat (limited to 'drivers/edac/x38_edac.c')
-rw-r--r--drivers/edac/x38_edac.c95
1 files changed, 43 insertions, 52 deletions
diff --git a/drivers/edac/x38_edac.c b/drivers/edac/x38_edac.c
index c9db24d95ca..b6f47de152f 100644
--- a/drivers/edac/x38_edac.c
+++ b/drivers/edac/x38_edac.c
@@ -103,10 +103,10 @@ static int how_many_channel(struct pci_dev *pdev)
103 103
104 pci_read_config_byte(pdev, X38_CAPID0 + 8, &capid0_8b); 104 pci_read_config_byte(pdev, X38_CAPID0 + 8, &capid0_8b);
105 if (capid0_8b & 0x20) { /* check DCD: Dual Channel Disable */ 105 if (capid0_8b & 0x20) { /* check DCD: Dual Channel Disable */
106 edac_dbg(0, "In single channel mode\n"); 106 debugf0("In single channel mode.\n");
107 x38_channel_num = 1; 107 x38_channel_num = 1;
108 } else { 108 } else {
109 edac_dbg(0, "In dual channel mode\n"); 109 debugf0("In dual channel mode.\n");
110 x38_channel_num = 2; 110 x38_channel_num = 2;
111 } 111 }
112 112
@@ -151,7 +151,7 @@ static void x38_clear_error_info(struct mem_ctl_info *mci)
151{ 151{
152 struct pci_dev *pdev; 152 struct pci_dev *pdev;
153 153
154 pdev = to_pci_dev(mci->pdev); 154 pdev = to_pci_dev(mci->dev);
155 155
156 /* 156 /*
157 * Clear any error bits. 157 * Clear any error bits.
@@ -172,7 +172,7 @@ static void x38_get_and_clear_error_info(struct mem_ctl_info *mci,
172 struct pci_dev *pdev; 172 struct pci_dev *pdev;
173 void __iomem *window = mci->pvt_info; 173 void __iomem *window = mci->pvt_info;
174 174
175 pdev = to_pci_dev(mci->pdev); 175 pdev = to_pci_dev(mci->dev);
176 176
177 /* 177 /*
178 * This is a mess because there is no atomic way to read all the 178 * This is a mess because there is no atomic way to read all the
@@ -215,26 +215,19 @@ static void x38_process_error_info(struct mem_ctl_info *mci,
215 return; 215 return;
216 216
217 if ((info->errsts ^ info->errsts2) & X38_ERRSTS_BITS) { 217 if ((info->errsts ^ info->errsts2) & X38_ERRSTS_BITS) {
218 edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, 1, 0, 0, 0, 218 edac_mc_handle_ce_no_info(mci, "UE overwrote CE");
219 -1, -1, -1,
220 "UE overwrote CE", "");
221 info->errsts = info->errsts2; 219 info->errsts = info->errsts2;
222 } 220 }
223 221
224 for (channel = 0; channel < x38_channel_num; channel++) { 222 for (channel = 0; channel < x38_channel_num; channel++) {
225 log = info->eccerrlog[channel]; 223 log = info->eccerrlog[channel];
226 if (log & X38_ECCERRLOG_UE) { 224 if (log & X38_ECCERRLOG_UE) {
227 edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, 1, 225 edac_mc_handle_ue(mci, 0, 0,
228 0, 0, 0, 226 eccerrlog_row(channel, log), "x38 UE");
229 eccerrlog_row(channel, log),
230 -1, -1,
231 "x38 UE", "");
232 } else if (log & X38_ECCERRLOG_CE) { 227 } else if (log & X38_ECCERRLOG_CE) {
233 edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, 1, 228 edac_mc_handle_ce(mci, 0, 0,
234 0, 0, eccerrlog_syndrome(log), 229 eccerrlog_syndrome(log),
235 eccerrlog_row(channel, log), 230 eccerrlog_row(channel, log), 0, "x38 CE");
236 -1, -1,
237 "x38 CE", "");
238 } 231 }
239 } 232 }
240} 233}
@@ -243,7 +236,7 @@ static void x38_check(struct mem_ctl_info *mci)
243{ 236{
244 struct x38_error_info info; 237 struct x38_error_info info;
245 238
246 edac_dbg(1, "MC%d\n", mci->mc_idx); 239 debugf1("MC%d: %s()\n", mci->mc_idx, __func__);
247 x38_get_and_clear_error_info(mci, &info); 240 x38_get_and_clear_error_info(mci, &info);
248 x38_process_error_info(mci, &info); 241 x38_process_error_info(mci, &info);
249} 242}
@@ -324,14 +317,14 @@ static unsigned long drb_to_nr_pages(
324static int x38_probe1(struct pci_dev *pdev, int dev_idx) 317static int x38_probe1(struct pci_dev *pdev, int dev_idx)
325{ 318{
326 int rc; 319 int rc;
327 int i, j; 320 int i;
328 struct mem_ctl_info *mci = NULL; 321 struct mem_ctl_info *mci = NULL;
329 struct edac_mc_layer layers[2]; 322 unsigned long last_page;
330 u16 drbs[X38_CHANNELS][X38_RANKS_PER_CHANNEL]; 323 u16 drbs[X38_CHANNELS][X38_RANKS_PER_CHANNEL];
331 bool stacked; 324 bool stacked;
332 void __iomem *window; 325 void __iomem *window;
333 326
334 edac_dbg(0, "MC:\n"); 327 debugf0("MC: %s()\n", __func__);
335 328
336 window = x38_map_mchbar(pdev); 329 window = x38_map_mchbar(pdev);
337 if (!window) 330 if (!window)
@@ -342,19 +335,13 @@ static int x38_probe1(struct pci_dev *pdev, int dev_idx)
342 how_many_channel(pdev); 335 how_many_channel(pdev);
343 336
344 /* FIXME: unconventional pvt_info usage */ 337 /* FIXME: unconventional pvt_info usage */
345 layers[0].type = EDAC_MC_LAYER_CHIP_SELECT; 338 mci = edac_mc_alloc(0, X38_RANKS, x38_channel_num, 0);
346 layers[0].size = X38_RANKS;
347 layers[0].is_virt_csrow = true;
348 layers[1].type = EDAC_MC_LAYER_CHANNEL;
349 layers[1].size = x38_channel_num;
350 layers[1].is_virt_csrow = false;
351 mci = edac_mc_alloc(0, ARRAY_SIZE(layers), layers, 0);
352 if (!mci) 339 if (!mci)
353 return -ENOMEM; 340 return -ENOMEM;
354 341
355 edac_dbg(3, "MC: init mci\n"); 342 debugf3("MC: %s(): init mci\n", __func__);
356 343
357 mci->pdev = &pdev->dev; 344 mci->dev = &pdev->dev;
358 mci->mtype_cap = MEM_FLAG_DDR2; 345 mci->mtype_cap = MEM_FLAG_DDR2;
359 346
360 mci->edac_ctl_cap = EDAC_FLAG_SECDED; 347 mci->edac_ctl_cap = EDAC_FLAG_SECDED;
@@ -376,38 +363,41 @@ static int x38_probe1(struct pci_dev *pdev, int dev_idx)
376 * cumulative; the last one will contain the total memory 363 * cumulative; the last one will contain the total memory
377 * contained in all ranks. 364 * contained in all ranks.
378 */ 365 */
366 last_page = -1UL;
379 for (i = 0; i < mci->nr_csrows; i++) { 367 for (i = 0; i < mci->nr_csrows; i++) {
380 unsigned long nr_pages; 368 unsigned long nr_pages;
381 struct csrow_info *csrow = mci->csrows[i]; 369 struct csrow_info *csrow = &mci->csrows[i];
382 370
383 nr_pages = drb_to_nr_pages(drbs, stacked, 371 nr_pages = drb_to_nr_pages(drbs, stacked,
384 i / X38_RANKS_PER_CHANNEL, 372 i / X38_RANKS_PER_CHANNEL,
385 i % X38_RANKS_PER_CHANNEL); 373 i % X38_RANKS_PER_CHANNEL);
386 374
387 if (nr_pages == 0) 375 if (nr_pages == 0) {
376 csrow->mtype = MEM_EMPTY;
388 continue; 377 continue;
378 }
389 379
390 for (j = 0; j < x38_channel_num; j++) { 380 csrow->first_page = last_page + 1;
391 struct dimm_info *dimm = csrow->channels[j]->dimm; 381 last_page += nr_pages;
382 csrow->last_page = last_page;
383 csrow->nr_pages = nr_pages;
392 384
393 dimm->nr_pages = nr_pages / x38_channel_num; 385 csrow->grain = nr_pages << PAGE_SHIFT;
394 dimm->grain = nr_pages << PAGE_SHIFT; 386 csrow->mtype = MEM_DDR2;
395 dimm->mtype = MEM_DDR2; 387 csrow->dtype = DEV_UNKNOWN;
396 dimm->dtype = DEV_UNKNOWN; 388 csrow->edac_mode = EDAC_UNKNOWN;
397 dimm->edac_mode = EDAC_UNKNOWN;
398 }
399 } 389 }
400 390
401 x38_clear_error_info(mci); 391 x38_clear_error_info(mci);
402 392
403 rc = -ENODEV; 393 rc = -ENODEV;
404 if (edac_mc_add_mc(mci)) { 394 if (edac_mc_add_mc(mci)) {
405 edac_dbg(3, "MC: failed edac_mc_add_mc()\n"); 395 debugf3("MC: %s(): failed edac_mc_add_mc()\n", __func__);
406 goto fail; 396 goto fail;
407 } 397 }
408 398
409 /* get this far and it's successful */ 399 /* get this far and it's successful */
410 edac_dbg(3, "MC: success\n"); 400 debugf3("MC: %s(): success\n", __func__);
411 return 0; 401 return 0;
412 402
413fail: 403fail:
@@ -418,11 +408,12 @@ fail:
418 return rc; 408 return rc;
419} 409}
420 410
421static int x38_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) 411static int __devinit x38_init_one(struct pci_dev *pdev,
412 const struct pci_device_id *ent)
422{ 413{
423 int rc; 414 int rc;
424 415
425 edac_dbg(0, "MC:\n"); 416 debugf0("MC: %s()\n", __func__);
426 417
427 if (pci_enable_device(pdev) < 0) 418 if (pci_enable_device(pdev) < 0)
428 return -EIO; 419 return -EIO;
@@ -434,11 +425,11 @@ static int x38_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
434 return rc; 425 return rc;
435} 426}
436 427
437static void x38_remove_one(struct pci_dev *pdev) 428static void __devexit x38_remove_one(struct pci_dev *pdev)
438{ 429{
439 struct mem_ctl_info *mci; 430 struct mem_ctl_info *mci;
440 431
441 edac_dbg(0, "\n"); 432 debugf0("%s()\n", __func__);
442 433
443 mci = edac_mc_del_mc(&pdev->dev); 434 mci = edac_mc_del_mc(&pdev->dev);
444 if (!mci) 435 if (!mci)
@@ -449,7 +440,7 @@ static void x38_remove_one(struct pci_dev *pdev)
449 edac_mc_free(mci); 440 edac_mc_free(mci);
450} 441}
451 442
452static DEFINE_PCI_DEVICE_TABLE(x38_pci_tbl) = { 443static const struct pci_device_id x38_pci_tbl[] __devinitdata = {
453 { 444 {
454 PCI_VEND_DEV(INTEL, X38_HB), PCI_ANY_ID, PCI_ANY_ID, 0, 0, 445 PCI_VEND_DEV(INTEL, X38_HB), PCI_ANY_ID, PCI_ANY_ID, 0, 0,
455 X38}, 446 X38},
@@ -463,7 +454,7 @@ MODULE_DEVICE_TABLE(pci, x38_pci_tbl);
463static struct pci_driver x38_driver = { 454static struct pci_driver x38_driver = {
464 .name = EDAC_MOD_STR, 455 .name = EDAC_MOD_STR,
465 .probe = x38_init_one, 456 .probe = x38_init_one,
466 .remove = x38_remove_one, 457 .remove = __devexit_p(x38_remove_one),
467 .id_table = x38_pci_tbl, 458 .id_table = x38_pci_tbl,
468}; 459};
469 460
@@ -471,7 +462,7 @@ static int __init x38_init(void)
471{ 462{
472 int pci_rc; 463 int pci_rc;
473 464
474 edac_dbg(3, "MC:\n"); 465 debugf3("MC: %s()\n", __func__);
475 466
476 /* Ensure that the OPSTATE is set correctly for POLL or NMI */ 467 /* Ensure that the OPSTATE is set correctly for POLL or NMI */
477 opstate_init(); 468 opstate_init();
@@ -485,14 +476,14 @@ static int __init x38_init(void)
485 mci_pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 476 mci_pdev = pci_get_device(PCI_VENDOR_ID_INTEL,
486 PCI_DEVICE_ID_INTEL_X38_HB, NULL); 477 PCI_DEVICE_ID_INTEL_X38_HB, NULL);
487 if (!mci_pdev) { 478 if (!mci_pdev) {
488 edac_dbg(0, "x38 pci_get_device fail\n"); 479 debugf0("x38 pci_get_device fail\n");
489 pci_rc = -ENODEV; 480 pci_rc = -ENODEV;
490 goto fail1; 481 goto fail1;
491 } 482 }
492 483
493 pci_rc = x38_init_one(mci_pdev, x38_pci_tbl); 484 pci_rc = x38_init_one(mci_pdev, x38_pci_tbl);
494 if (pci_rc < 0) { 485 if (pci_rc < 0) {
495 edac_dbg(0, "x38 init fail\n"); 486 debugf0("x38 init fail\n");
496 pci_rc = -ENODEV; 487 pci_rc = -ENODEV;
497 goto fail1; 488 goto fail1;
498 } 489 }
@@ -512,7 +503,7 @@ fail0:
512 503
513static void __exit x38_exit(void) 504static void __exit x38_exit(void)
514{ 505{
515 edac_dbg(3, "MC:\n"); 506 debugf3("MC: %s()\n", __func__);
516 507
517 pci_unregister_driver(&x38_driver); 508 pci_unregister_driver(&x38_driver);
518 if (!x38_registered) { 509 if (!x38_registered) {