summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/edac/edac_core.h1
-rw-r--r--drivers/edac/edac_device.c11
-rw-r--r--drivers/edac/edac_device_sysfs.c26
3 files changed, 38 insertions, 0 deletions
diff --git a/drivers/edac/edac_core.h b/drivers/edac/edac_core.h
index 4861542163d7..67691a6d0708 100644
--- a/drivers/edac/edac_core.h
+++ b/drivers/edac/edac_core.h
@@ -223,6 +223,7 @@ struct edac_device_ctl_info {
/* Per instance controls for this edac_device */
int log_ue; /* boolean for logging UEs */
int log_ce; /* boolean for logging CEs */
+ int panic_on_ce; /* boolean for panic'ing on an CE */
int panic_on_ue; /* boolean for panic'ing on an UE */
unsigned poll_msec; /* number of milliseconds to poll interval */
unsigned long delay; /* number of jiffies for poll_msec */
diff --git a/drivers/edac/edac_device.c b/drivers/edac/edac_device.c
index 592af5f0cf39..dc786c26a1e4 100644
--- a/drivers/edac/edac_device.c
+++ b/drivers/edac/edac_device.c
@@ -611,6 +611,12 @@ static inline int edac_device_get_log_ue(struct edac_device_ctl_info *edac_dev)
return edac_dev->log_ue;
}
+static inline int edac_device_get_panic_on_ce(struct edac_device_ctl_info
+ *edac_dev)
+{
+ return edac_dev->panic_on_ce;
+}
+
static inline int edac_device_get_panic_on_ue(struct edac_device_ctl_info
*edac_dev)
{
@@ -660,6 +666,11 @@ void edac_device_handle_ce(struct edac_device_ctl_info *edac_dev,
"CE: %s instance: %s block: %s '%s'\n",
edac_dev->ctl_name, instance->name,
block ? block->name : "N/A", msg);
+
+ if (edac_device_get_panic_on_ce(edac_dev))
+ panic("EDAC %s: CE instance: %s block %s '%s'\n",
+ edac_dev->ctl_name, instance->name,
+ block ? block->name : "N/A", msg);
}
EXPORT_SYMBOL_GPL(edac_device_handle_ce);
diff --git a/drivers/edac/edac_device_sysfs.c b/drivers/edac/edac_device_sysfs.c
index fb68a06ad683..b8590a02b73d 100644
--- a/drivers/edac/edac_device_sysfs.c
+++ b/drivers/edac/edac_device_sysfs.c
@@ -62,6 +62,13 @@ static ssize_t edac_device_ctl_log_ce_store(struct edac_device_ctl_info
return count;
}
+/* 'panic_on_ce' */
+static ssize_t edac_device_ctl_panic_on_ce_show(struct edac_device_ctl_info
+ *ctl_info, char *data)
+{
+ return snprintf(data, PAGE_SIZE, "%u\n", ctl_info->panic_on_ce);
+}
+
/* 'panic_on_ue' */
static ssize_t edac_device_ctl_panic_on_ue_show(struct edac_device_ctl_info
*ctl_info, char *data)
@@ -69,6 +76,21 @@ static ssize_t edac_device_ctl_panic_on_ue_show(struct edac_device_ctl_info
return sprintf(data, "%u\n", ctl_info->panic_on_ue);
}
+static ssize_t edac_device_ctl_panic_on_ce_store(struct edac_device_ctl_info
+ *ctl_info, const char *data,
+ size_t count)
+{
+ unsigned long val;
+
+ /* if parameter is zero, turn off flag, if non-zero turn on flag */
+ if (kstrtoul(data, 0, &val) < 0)
+ return -EINVAL;
+
+ ctl_info->panic_on_ce = !!val;
+
+ return count;
+}
+
static ssize_t edac_device_ctl_panic_on_ue_store(struct edac_device_ctl_info
*ctl_info, const char *data,
size_t count)
@@ -156,6 +178,9 @@ CTL_INFO_ATTR(log_ue, S_IRUGO | S_IWUSR,
edac_device_ctl_log_ue_show, edac_device_ctl_log_ue_store);
CTL_INFO_ATTR(log_ce, S_IRUGO | S_IWUSR,
edac_device_ctl_log_ce_show, edac_device_ctl_log_ce_store);
+CTL_INFO_ATTR(panic_on_ce, S_IRUGO | S_IWUSR,
+ edac_device_ctl_panic_on_ce_show,
+ edac_device_ctl_panic_on_ce_store);
CTL_INFO_ATTR(panic_on_ue, S_IRUGO | S_IWUSR,
edac_device_ctl_panic_on_ue_show,
edac_device_ctl_panic_on_ue_store);
@@ -164,6 +189,7 @@ CTL_INFO_ATTR(poll_msec, S_IRUGO | S_IWUSR,
/* Base Attributes of the EDAC_DEVICE ECC object */
static struct ctl_info_attribute *device_ctrl_attr[] = {
+ &attr_ctl_info_panic_on_ce,
&attr_ctl_info_panic_on_ue,
&attr_ctl_info_log_ue,
&attr_ctl_info_log_ce,