[linux-yocto] [PATCH 2/5] driver/edac: Added new kernel cmdline parameter.
Daniel Dragomir
daniel.dragomir at windriver.com
Tue May 14 06:23:56 PDT 2019
From: Marek Majtyka <marekx.majtyka at intel.com>
Added 'l3_polling_mode' boot parameter for forcing usage of polling mode
instead of interrupt for edac L3 cache driver.
Signed-off-by: Marek Majtyka <marekx.majtyka at intel.com>
---
drivers/edac/axxia_edac-l3_56xx.c | 56 +++++++++++++++++++++++++++++----------
1 file changed, 42 insertions(+), 14 deletions(-)
diff --git a/drivers/edac/axxia_edac-l3_56xx.c b/drivers/edac/axxia_edac-l3_56xx.c
index ed8c1d3..ff13b71 100644
--- a/drivers/edac/axxia_edac-l3_56xx.c
+++ b/drivers/edac/axxia_edac-l3_56xx.c
@@ -12,6 +12,7 @@
#define CREATE_TRACE_POINTS
#include <linux/module.h>
+#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/io.h>
@@ -80,6 +81,7 @@
#define CCN_NODE_ERR_SYND_CLR 0x480
static cpumask_t only_cpu_0 = { CPU_BITS_CPU0};
+static int l3_pmode;
union dickens_hnf_err_syndrome_reg0 {
struct __packed {
@@ -174,6 +176,20 @@ struct intel_edac_dev_info {
void (*check)(struct edac_device_ctl_info *edac_dev);
};
+
+static int __init l3_polling_mode(char *str)
+{
+ int polling_mode;
+
+ if (get_option(&str, &polling_mode)) {
+ l3_pmode = polling_mode;
+ return 0;
+ }
+ return -EINVAL;
+}
+
+early_param("l3_polling_mode", l3_polling_mode);
+
static void clear_node_error(void __iomem *addr)
{
union dickens_hnf_err_syndrome_clr err_syndrome_clr;
@@ -305,7 +321,8 @@ static irqreturn_t collect_and_clean(struct intel_edac_dev_info *dev_info,
err_synd_reg1);
dev_info->data_hni[i].err_synd_reg0 = err_synd_reg0;
dev_info->data_hni[i].err_synd_reg1 = err_synd_reg1;
- dev_info->data_hni[i].idx = 0;
+ dev_info->data_hni[i].idx = CCN_HNF_NODES +
+ CCN_XP_NODES + i;
clear_node_error(ccn_base + CCN_HNI_NODE_BASE_ADDR(i) +
CCN_NODE_ERR_SYND_CLR);
@@ -345,6 +362,7 @@ static irqreturn_t collect_and_clean(struct intel_edac_dev_info *dev_info,
dev_info->data_xp[i].err_synd_reg0 = err_synd_reg0;
dev_info->data_xp[i].err_synd_reg1 = 0;
+ dev_info->data_xp[i].idx = CCN_HNF_NODES + i;
trace_edacl3_syndromes(err_synd_reg0,
err_synd_reg1);
@@ -414,7 +432,8 @@ static void intel_l3_error_check(struct edac_device_ctl_info *edac_dev)
count = err_syndrome_reg0.reg0.err_count;
if (count)
edac_device_handle_multi_ce(edac_dev, 0,
- instance, count, edac_dev->ctl_name);
+ dev_info->data[instance].idx, count,
+ edac_dev->ctl_name);
/* clear the valid bit */
clear_node_error(addr + CCN_NODE_ERR_SYND_CLR);
@@ -459,10 +478,11 @@ static int intel_edac_l3_probe(struct platform_device *pdev)
np->name);
goto err1;
}
+ /* for the moment only HNF errors are reported via sysfs */
dev_info->edac_dev =
edac_device_alloc_ctl_info(0, dev_info->ctl_name,
1, dev_info->blk_name,
- CCN_HNI_NODES, 0, NULL, 0,
+ CCN_HNF_NODES, 0, NULL, 0,
dev_info->edac_idx);
if (!dev_info->edac_dev) {
pr_info("No memory for edac device\n");
@@ -481,20 +501,26 @@ static int intel_edac_l3_probe(struct platform_device *pdev)
* Once -1 return, it means old uboot without ccn service.
* Then only polling mechanism is allowed, as it was before.
*/
- __arm_smccc_smc(0xc4000027, CCN_MN_ERRINT_STATUS__PMU_EVENTS__DISABLE,
- 0, 0, &ret);
- trace_edacl3_smc_results(&ret);
-
- if (ret.a0 != ARM_SMCCC_UNKNOWN) {
- irqreturn_t res;
- dev_info->irq_used = 1;
- /* clear all error from earlier boot stage */
- res = collect_and_clean(dev_info, 0);
+ if (l3_pmode) {
+ dev_info->irq_used = 0;
+ } else {
__arm_smccc_smc(0xc4000027,
- CCN_MN_ERRINT_STATUS__INTREQ__DESSERT,
- 0, 0, &ret);
+ CCN_MN_ERRINT_STATUS__PMU_EVENTS__DISABLE,
+ 0, 0, &ret);
trace_edacl3_smc_results(&ret);
+
+ if (ret.a0 != ARM_SMCCC_UNKNOWN) {
+ irqreturn_t res;
+
+ dev_info->irq_used = 1;
+ /* clear all error from earlier boot stage */
+ res = collect_and_clean(dev_info, 0);
+ __arm_smccc_smc(0xc4000027,
+ CCN_MN_ERRINT_STATUS__INTREQ__DESSERT,
+ 0, 0, &ret);
+ trace_edacl3_smc_results(&ret);
+ }
}
dev_info->edac_dev->pvt_info = dev_info;
@@ -506,9 +532,11 @@ static int intel_edac_l3_probe(struct platform_device *pdev)
if (dev_info->irq_used) {
edac_op_state = EDAC_OPSTATE_INT;
dev_info->edac_dev->edac_check = NULL;
+ pr_info("L3 cache EDAC - interrupt mode.\n");
} else {
edac_op_state = EDAC_OPSTATE_POLL;
dev_info->edac_dev->edac_check = intel_l3_error_check;
+ pr_info("L3 cache EDAC - polling mode.\n");
}
if (edac_device_add_device(dev_info->edac_dev) != 0) {
--
2.7.4
More information about the linux-yocto
mailing list