aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/edac/ie31200_edac.c
diff options
context:
space:
mode:
authorJason Baron <jbaron@akamai.com>2014-07-09 17:13:07 -0400
committerBorislav Petkov <bp@suse.de>2014-07-10 04:55:12 -0400
commit78fd4d1242e88fbe5ea269087a47bd7e05bf84a1 (patch)
tree8b2433163ac374ea191e74f784c36a994eb5fb87 /drivers/edac/ie31200_edac.c
parent7ee40b897d18ab03111eda9a6a0550e98166eada (diff)
ie31200_edac: Allocate mci and map mchbar first
Check for memory allocation and mchbar mapping failures before initializing the dimm info tables needlessly. Signed-off-by: Jason Baron <jbaron@akamai.com> Suggested-by: Borislav Petkov <bp@suse.de> Link: http://lkml.kernel.org/r/ead8f53e699f1ce21c2e17f3cffb4685d4faf72a.1404939455.git.jbaron@akamai.com Signed-off-by: Borislav Petkov <bp@suse.de>
Diffstat (limited to 'drivers/edac/ie31200_edac.c')
-rw-r--r--drivers/edac/ie31200_edac.c71
1 files changed, 33 insertions, 38 deletions
diff --git a/drivers/edac/ie31200_edac.c b/drivers/edac/ie31200_edac.c
index 6d3d2c3cb6d6..a981dc6fd88e 100644
--- a/drivers/edac/ie31200_edac.c
+++ b/drivers/edac/ie31200_edac.c
@@ -328,8 +328,7 @@ static void __iomem *ie31200_map_mchbar(struct pci_dev *pdev)
328 328
329static int ie31200_probe1(struct pci_dev *pdev, int dev_idx) 329static int ie31200_probe1(struct pci_dev *pdev, int dev_idx)
330{ 330{
331 int rc; 331 int i, j, ret;
332 int i, j;
333 struct mem_ctl_info *mci = NULL; 332 struct mem_ctl_info *mci = NULL;
334 struct edac_mc_layer layers[2]; 333 struct edac_mc_layer layers[2];
335 struct dimm_data dimm_info[IE31200_CHANNELS][IE31200_DIMMS_PER_CHANNEL]; 334 struct dimm_data dimm_info[IE31200_CHANNELS][IE31200_DIMMS_PER_CHANNEL];
@@ -344,31 +343,7 @@ static int ie31200_probe1(struct pci_dev *pdev, int dev_idx)
344 return -ENODEV; 343 return -ENODEV;
345 } 344 }
346 345
347 window = ie31200_map_mchbar(pdev);
348 if (!window)
349 return -ENODEV;
350
351 /* populate DIMM info */
352 for (i = 0; i < IE31200_CHANNELS; i++) {
353 addr_decode = readl(window + IE31200_MAD_DIMM_0_OFFSET +
354 (i * 4));
355 edac_dbg(0, "addr_decode: 0x%x\n", addr_decode);
356 for (j = 0; j < IE31200_DIMMS_PER_CHANNEL; j++) {
357 dimm_info[i][j].size = (addr_decode >> (j * 8)) &
358 IE31200_MAD_DIMM_SIZE;
359 dimm_info[i][j].dual_rank = (addr_decode &
360 (IE31200_MAD_DIMM_A_RANK << j)) ? 1 : 0;
361 dimm_info[i][j].x16_width = (addr_decode &
362 (IE31200_MAD_DIMM_A_WIDTH << j)) ? 1 : 0;
363 edac_dbg(0, "size: 0x%x, rank: %d, width: %d\n",
364 dimm_info[i][j].size,
365 dimm_info[i][j].dual_rank,
366 dimm_info[i][j].x16_width);
367 }
368 }
369
370 nr_channels = how_many_channels(pdev); 346 nr_channels = how_many_channels(pdev);
371
372 layers[0].type = EDAC_MC_LAYER_CHIP_SELECT; 347 layers[0].type = EDAC_MC_LAYER_CHIP_SELECT;
373 layers[0].size = IE31200_DIMMS; 348 layers[0].size = IE31200_DIMMS;
374 layers[0].is_virt_csrow = true; 349 layers[0].is_virt_csrow = true;
@@ -377,19 +352,20 @@ static int ie31200_probe1(struct pci_dev *pdev, int dev_idx)
377 layers[1].is_virt_csrow = false; 352 layers[1].is_virt_csrow = false;
378 mci = edac_mc_alloc(0, ARRAY_SIZE(layers), layers, 353 mci = edac_mc_alloc(0, ARRAY_SIZE(layers), layers,
379 sizeof(struct ie31200_priv)); 354 sizeof(struct ie31200_priv));
380
381 rc = -ENOMEM;
382 if (!mci) 355 if (!mci)
383 goto fail_unmap; 356 return -ENOMEM;
384 357
385 edac_dbg(3, "MC: init mci\n"); 358 window = ie31200_map_mchbar(pdev);
359 if (!window) {
360 ret = -ENODEV;
361 goto fail_free;
362 }
386 363
364 edac_dbg(3, "MC: init mci\n");
387 mci->pdev = &pdev->dev; 365 mci->pdev = &pdev->dev;
388 mci->mtype_cap = MEM_FLAG_DDR3; 366 mci->mtype_cap = MEM_FLAG_DDR3;
389
390 mci->edac_ctl_cap = EDAC_FLAG_SECDED; 367 mci->edac_ctl_cap = EDAC_FLAG_SECDED;
391 mci->edac_cap = EDAC_FLAG_SECDED; 368 mci->edac_cap = EDAC_FLAG_SECDED;
392
393 mci->mod_name = EDAC_MOD_STR; 369 mci->mod_name = EDAC_MOD_STR;
394 mci->mod_ver = IE31200_REVISION; 370 mci->mod_ver = IE31200_REVISION;
395 mci->ctl_name = ie31200_devs[dev_idx].ctl_name; 371 mci->ctl_name = ie31200_devs[dev_idx].ctl_name;
@@ -399,6 +375,25 @@ static int ie31200_probe1(struct pci_dev *pdev, int dev_idx)
399 priv = mci->pvt_info; 375 priv = mci->pvt_info;
400 priv->window = window; 376 priv->window = window;
401 377
378 /* populate DIMM info */
379 for (i = 0; i < IE31200_CHANNELS; i++) {
380 addr_decode = readl(window + IE31200_MAD_DIMM_0_OFFSET +
381 (i * 4));
382 edac_dbg(0, "addr_decode: 0x%x\n", addr_decode);
383 for (j = 0; j < IE31200_DIMMS_PER_CHANNEL; j++) {
384 dimm_info[i][j].size = (addr_decode >> (j * 8)) &
385 IE31200_MAD_DIMM_SIZE;
386 dimm_info[i][j].dual_rank = (addr_decode &
387 (IE31200_MAD_DIMM_A_RANK << j)) ? 1 : 0;
388 dimm_info[i][j].x16_width = (addr_decode &
389 (IE31200_MAD_DIMM_A_WIDTH << j)) ? 1 : 0;
390 edac_dbg(0, "size: 0x%x, rank: %d, width: %d\n",
391 dimm_info[i][j].size,
392 dimm_info[i][j].dual_rank,
393 dimm_info[i][j].x16_width);
394 }
395 }
396
402 /* 397 /*
403 * The dram rank boundary (DRB) reg values are boundary addresses 398 * The dram rank boundary (DRB) reg values are boundary addresses
404 * for each DRAM rank with a granularity of 64MB. DRB regs are 399 * for each DRAM rank with a granularity of 64MB. DRB regs are
@@ -439,23 +434,23 @@ static int ie31200_probe1(struct pci_dev *pdev, int dev_idx)
439 434
440 ie31200_clear_error_info(mci); 435 ie31200_clear_error_info(mci);
441 436
442 rc = -ENODEV;
443 if (edac_mc_add_mc(mci)) { 437 if (edac_mc_add_mc(mci)) {
444 edac_dbg(3, "MC: failed edac_mc_add_mc()\n"); 438 edac_dbg(3, "MC: failed edac_mc_add_mc()\n");
445 goto fail_free; 439 ret = -ENODEV;
440 goto fail_unmap;
446 } 441 }
447 442
448 /* get this far and it's successful */ 443 /* get this far and it's successful */
449 edac_dbg(3, "MC: success\n"); 444 edac_dbg(3, "MC: success\n");
450 return 0; 445 return 0;
451 446
452fail_free:
453 if (mci)
454 edac_mc_free(mci);
455fail_unmap: 447fail_unmap:
456 iounmap(window); 448 iounmap(window);
457 449
458 return rc; 450fail_free:
451 edac_mc_free(mci);
452
453 return ret;
459} 454}
460 455
461static int ie31200_init_one(struct pci_dev *pdev, 456static int ie31200_init_one(struct pci_dev *pdev,