diff options
author | Jason Baron <jbaron@akamai.com> | 2014-07-09 23:13:07 +0200 |
---|---|---|
committer | Borislav Petkov <bp@suse.de> | 2014-07-10 10:55:12 +0200 |
commit | 78fd4d1242e88fbe5ea269087a47bd7e05bf84a1 (patch) | |
tree | 8b2433163ac374ea191e74f784c36a994eb5fb87 /drivers/edac/ie31200_edac.c | |
parent | ie31200_edac: Introduce the driver (diff) | |
download | linux-78fd4d1242e88fbe5ea269087a47bd7e05bf84a1.tar.xz linux-78fd4d1242e88fbe5ea269087a47bd7e05bf84a1.zip |
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.c | 71 |
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) static int ie31200_probe1(struct pci_dev *pdev, int dev_idx) { - int rc; - int i, j; + int i, j, ret; struct mem_ctl_info *mci = NULL; struct edac_mc_layer layers[2]; 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) return -ENODEV; } - window = ie31200_map_mchbar(pdev); - if (!window) - return -ENODEV; - - /* populate DIMM info */ - for (i = 0; i < IE31200_CHANNELS; i++) { - addr_decode = readl(window + IE31200_MAD_DIMM_0_OFFSET + - (i * 4)); - edac_dbg(0, "addr_decode: 0x%x\n", addr_decode); - for (j = 0; j < IE31200_DIMMS_PER_CHANNEL; j++) { - dimm_info[i][j].size = (addr_decode >> (j * 8)) & - IE31200_MAD_DIMM_SIZE; - dimm_info[i][j].dual_rank = (addr_decode & - (IE31200_MAD_DIMM_A_RANK << j)) ? 1 : 0; - dimm_info[i][j].x16_width = (addr_decode & - (IE31200_MAD_DIMM_A_WIDTH << j)) ? 1 : 0; - edac_dbg(0, "size: 0x%x, rank: %d, width: %d\n", - dimm_info[i][j].size, - dimm_info[i][j].dual_rank, - dimm_info[i][j].x16_width); - } - } - nr_channels = how_many_channels(pdev); - layers[0].type = EDAC_MC_LAYER_CHIP_SELECT; layers[0].size = IE31200_DIMMS; layers[0].is_virt_csrow = true; @@ -377,19 +352,20 @@ static int ie31200_probe1(struct pci_dev *pdev, int dev_idx) layers[1].is_virt_csrow = false; mci = edac_mc_alloc(0, ARRAY_SIZE(layers), layers, sizeof(struct ie31200_priv)); - - rc = -ENOMEM; if (!mci) - goto fail_unmap; + return -ENOMEM; - edac_dbg(3, "MC: init mci\n"); + window = ie31200_map_mchbar(pdev); + if (!window) { + ret = -ENODEV; + goto fail_free; + } + edac_dbg(3, "MC: init mci\n"); mci->pdev = &pdev->dev; mci->mtype_cap = MEM_FLAG_DDR3; - mci->edac_ctl_cap = EDAC_FLAG_SECDED; mci->edac_cap = EDAC_FLAG_SECDED; - mci->mod_name = EDAC_MOD_STR; mci->mod_ver = IE31200_REVISION; mci->ctl_name = ie31200_devs[dev_idx].ctl_name; @@ -399,6 +375,25 @@ static int ie31200_probe1(struct pci_dev *pdev, int dev_idx) priv = mci->pvt_info; priv->window = window; + /* populate DIMM info */ + for (i = 0; i < IE31200_CHANNELS; i++) { + addr_decode = readl(window + IE31200_MAD_DIMM_0_OFFSET + + (i * 4)); + edac_dbg(0, "addr_decode: 0x%x\n", addr_decode); + for (j = 0; j < IE31200_DIMMS_PER_CHANNEL; j++) { + dimm_info[i][j].size = (addr_decode >> (j * 8)) & + IE31200_MAD_DIMM_SIZE; + dimm_info[i][j].dual_rank = (addr_decode & + (IE31200_MAD_DIMM_A_RANK << j)) ? 1 : 0; + dimm_info[i][j].x16_width = (addr_decode & + (IE31200_MAD_DIMM_A_WIDTH << j)) ? 1 : 0; + edac_dbg(0, "size: 0x%x, rank: %d, width: %d\n", + dimm_info[i][j].size, + dimm_info[i][j].dual_rank, + dimm_info[i][j].x16_width); + } + } + /* * The dram rank boundary (DRB) reg values are boundary addresses * 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) ie31200_clear_error_info(mci); - rc = -ENODEV; if (edac_mc_add_mc(mci)) { edac_dbg(3, "MC: failed edac_mc_add_mc()\n"); - goto fail_free; + ret = -ENODEV; + goto fail_unmap; } /* get this far and it's successful */ edac_dbg(3, "MC: success\n"); return 0; -fail_free: - if (mci) - edac_mc_free(mci); fail_unmap: iounmap(window); - return rc; +fail_free: + edac_mc_free(mci); + + return ret; } static int ie31200_init_one(struct pci_dev *pdev, |