summaryrefslogtreecommitdiff
path: root/drivers/edac/i7core_edac.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/edac/i7core_edac.c')
-rw-r--r--drivers/edac/i7core_edac.c77
1 files changed, 44 insertions, 33 deletions
diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c
index 75ad847593b7..91e0a88ef904 100644
--- a/drivers/edac/i7core_edac.c
+++ b/drivers/edac/i7core_edac.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-only
/* Intel i7 core/Nehalem Memory Controller kernel module
*
* This driver supports the memory controllers found on the Intel
@@ -5,13 +6,10 @@
* Xeon 55xx and Xeon 56xx also known as Nehalem, Nehalem-EP, Lynnfield
* and Westmere-EP.
*
- * This file may be distributed under the terms of the
- * GNU General Public License version 2 only.
- *
* Copyright (c) 2009-2010 by:
* Mauro Carvalho Chehab
*
- * Red Hat Inc. http://www.redhat.com
+ * Red Hat Inc. https://www.redhat.com
*
* Forked and adapted from the i5400_edac driver
*
@@ -378,7 +376,7 @@ static const struct pci_id_table pci_dev_table[] = {
PCI_ID_TABLE_ENTRY(pci_dev_descr_i7core_nehalem),
PCI_ID_TABLE_ENTRY(pci_dev_descr_lynnfield),
PCI_ID_TABLE_ENTRY(pci_dev_descr_i7core_westmere),
- {0,} /* 0 terminated list. */
+ { NULL, }
};
/*
@@ -387,7 +385,7 @@ static const struct pci_id_table pci_dev_table[] = {
static const struct pci_device_id i7core_pci_tbl[] = {
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_X58_HUB_MGMT)},
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LYNNFIELD_QPI_LINK0)},
- {0,} /* 0 terminated list. */
+ { 0, }
};
/****************************************************************************
@@ -461,7 +459,7 @@ static struct i7core_dev *alloc_i7core_dev(u8 socket,
if (!i7core_dev)
return NULL;
- i7core_dev->pdev = kzalloc(sizeof(*i7core_dev->pdev) * table->n_devs,
+ i7core_dev->pdev = kcalloc(table->n_devs, sizeof(*i7core_dev->pdev),
GFP_KERNEL);
if (!i7core_dev->pdev) {
kfree(i7core_dev);
@@ -587,8 +585,7 @@ static int get_dimm_config(struct mem_ctl_info *mci)
if (!DIMM_PRESENT(dimm_dod[j]))
continue;
- dimm = EDAC_DIMM_PTR(mci->layers, mci->dimms, mci->n_layers,
- i, j, 0);
+ dimm = edac_get_dimm(mci, i, j, 0);
banks = numbank(MC_DOD_NUMBANK(dimm_dod[j]));
ranks = numrank(MC_DOD_NUMRANK(dimm_dod[j]));
rows = numrow(MC_DOD_NUMROW(dimm_dod[j]));
@@ -597,7 +594,7 @@ static int get_dimm_config(struct mem_ctl_info *mci)
/* DDR3 has 8 I/O banks */
size = (rows * cols * banks * ranks) >> (20 - 3);
- edac_dbg(0, "\tdimm %d %d Mb offset: %x, bank: %d, rank: %d, row: %#x, col: %#x\n",
+ edac_dbg(0, "\tdimm %d %d MiB offset: %x, bank: %d, rank: %d, row: %#x, col: %#x\n",
j, size,
RANKOFFSET(dimm_dod[j]),
banks, ranks, rows, cols);
@@ -724,7 +721,7 @@ static ssize_t i7core_inject_type_store(struct device *dev,
const char *data, size_t count)
{
struct mem_ctl_info *mci = to_mci(dev);
-struct i7core_pvt *pvt = mci->pvt_info;
+ struct i7core_pvt *pvt = mci->pvt_info;
unsigned long value;
int rc;
@@ -1079,7 +1076,7 @@ static struct attribute *i7core_addrmatch_attrs[] = {
NULL
};
-static struct attribute_group addrmatch_grp = {
+static const struct attribute_group addrmatch_grp = {
.attrs = i7core_addrmatch_attrs,
};
@@ -1094,7 +1091,7 @@ static void addrmatch_release(struct device *device)
kfree(device);
}
-static struct device_type addrmatch_type = {
+static const struct device_type addrmatch_type = {
.groups = addrmatch_groups,
.release = addrmatch_release,
};
@@ -1110,7 +1107,7 @@ static struct attribute *i7core_udimm_counters_attrs[] = {
NULL
};
-static struct attribute_group all_channel_counts_grp = {
+static const struct attribute_group all_channel_counts_grp = {
.attrs = i7core_udimm_counters_attrs,
};
@@ -1125,7 +1122,7 @@ static void all_channel_counts_release(struct device *device)
kfree(device);
}
-static struct device_type all_channel_counts_type = {
+static const struct device_type all_channel_counts_type = {
.groups = all_channel_counts_groups,
.release = all_channel_counts_release,
};
@@ -1177,15 +1174,14 @@ static int i7core_create_sysfs_devices(struct mem_ctl_info *mci)
rc = device_add(pvt->addrmatch_dev);
if (rc < 0)
- return rc;
+ goto err_put_addrmatch;
if (!pvt->is_registered) {
pvt->chancounts_dev = kzalloc(sizeof(*pvt->chancounts_dev),
GFP_KERNEL);
if (!pvt->chancounts_dev) {
- put_device(pvt->addrmatch_dev);
- device_del(pvt->addrmatch_dev);
- return -ENOMEM;
+ rc = -ENOMEM;
+ goto err_del_addrmatch;
}
pvt->chancounts_dev->type = &all_channel_counts_type;
@@ -1199,9 +1195,18 @@ static int i7core_create_sysfs_devices(struct mem_ctl_info *mci)
rc = device_add(pvt->chancounts_dev);
if (rc < 0)
- return rc;
+ goto err_put_chancounts;
}
return 0;
+
+err_put_chancounts:
+ put_device(pvt->chancounts_dev);
+err_del_addrmatch:
+ device_del(pvt->addrmatch_dev);
+err_put_addrmatch:
+ put_device(pvt->addrmatch_dev);
+
+ return rc;
}
static void i7core_delete_sysfs_devices(struct mem_ctl_info *mci)
@@ -1211,11 +1216,11 @@ static void i7core_delete_sysfs_devices(struct mem_ctl_info *mci)
edac_dbg(1, "\n");
if (!pvt->is_registered) {
- put_device(pvt->chancounts_dev);
device_del(pvt->chancounts_dev);
+ put_device(pvt->chancounts_dev);
}
- put_device(pvt->addrmatch_dev);
device_del(pvt->addrmatch_dev);
+ put_device(pvt->addrmatch_dev);
}
/****************************************************************************
@@ -1703,10 +1708,11 @@ static void i7core_mce_output_error(struct mem_ctl_info *mci,
u32 errnum = find_first_bit(&error, 32);
if (uncorrected_error) {
+ core_err_cnt = 1;
if (ripv)
- tp_event = HW_EVENT_ERR_FATAL;
- else
tp_event = HW_EVENT_ERR_UNCORRECTED;
+ else
+ tp_event = HW_EVENT_ERR_FATAL;
} else {
tp_event = HW_EVENT_ERR_CORRECTED;
}
@@ -1743,7 +1749,7 @@ static void i7core_mce_output_error(struct mem_ctl_info *mci,
err = "write parity error";
break;
case 19:
- err = "redundacy loss";
+ err = "redundancy loss";
break;
case 20:
err = "reserved";
@@ -1807,14 +1813,12 @@ static int i7core_mce_check_error(struct notifier_block *nb, unsigned long val,
struct mce *mce = (struct mce *)data;
struct i7core_dev *i7_dev;
struct mem_ctl_info *mci;
- struct i7core_pvt *pvt;
i7_dev = get_i7core_dev(mce->socketid);
- if (!i7_dev)
+ if (!i7_dev || (mce->kflags & MCE_HANDLED_CEC))
return NOTIFY_DONE;
mci = i7_dev->mci;
- pvt = mci->pvt_info;
/*
* Just let mcelog handle it if the error is
@@ -1830,7 +1834,8 @@ static int i7core_mce_check_error(struct notifier_block *nb, unsigned long val,
i7core_check_error(mci, mce);
/* Advise mcelog that the errors were handled */
- return NOTIFY_STOP;
+ mce->kflags |= MCE_HANDLED_EDAC;
+ return NOTIFY_OK;
}
static struct notifier_block i7_mce_dec = {
@@ -2159,9 +2164,13 @@ static int i7core_register_mci(struct i7core_dev *i7core_dev)
mci->edac_ctl_cap = EDAC_FLAG_NONE;
mci->edac_cap = EDAC_FLAG_NONE;
mci->mod_name = "i7core_edac.c";
- mci->mod_ver = I7CORE_REVISION;
- mci->ctl_name = kasprintf(GFP_KERNEL, "i7 core #%d",
- i7core_dev->socket);
+
+ mci->ctl_name = kasprintf(GFP_KERNEL, "i7 core #%d", i7core_dev->socket);
+ if (!mci->ctl_name) {
+ rc = -ENOMEM;
+ goto fail1;
+ }
+
mci->dev_name = pci_name(i7core_dev->pdev[0]);
mci->ctl_page_to_phys = NULL;
@@ -2215,6 +2224,8 @@ static int i7core_register_mci(struct i7core_dev *i7core_dev)
fail0:
kfree(mci->ctl_name);
+
+fail1:
edac_mc_free(mci);
i7core_dev->mci = NULL;
return rc;
@@ -2380,7 +2391,7 @@ module_exit(i7core_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Mauro Carvalho Chehab");
-MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
+MODULE_AUTHOR("Red Hat Inc. (https://www.redhat.com)");
MODULE_DESCRIPTION("MC Driver for Intel i7 Core memory controllers - "
I7CORE_REVISION);