drivers: edac: Reinitialize errxctlr and overflow counter after PM_EXIT
In lower levels of LPMs, the errxctlr and errxmisc registers can be wiped
and lose their original value. Restore the errxctlr values and overflow
count on PM_EXIT. Also initialize L3/SCU registers on initial probe.
Change-Id: I19f68fd970b56719ad0cd9f3d247eac40eaa25af
Signed-off-by: Kyle Yan <kyan@codeaurora.org>
diff --git a/drivers/edac/kryo3xx_arm64_edac.c b/drivers/edac/kryo3xx_arm64_edac.c
index 5ca93a6..a300c7f 100644
--- a/drivers/edac/kryo3xx_arm64_edac.c
+++ b/drivers/edac/kryo3xx_arm64_edac.c
@@ -360,11 +360,34 @@
return IRQ_HANDLED;
}
+static void initialize_registers(void *info)
+{
+ set_errxctlr_el1();
+ set_errxmisc_overflow();
+}
+
+static void init_regs_on_cpu(bool all_cpus)
+{
+ int cpu;
+
+ write_errselr_el1(0);
+ if (all_cpus) {
+ for_each_possible_cpu(cpu)
+ smp_call_function_single(cpu, initialize_registers,
+ NULL, 1);
+ } else
+ initialize_registers(NULL);
+
+ write_errselr_el1(1);
+ initialize_registers(NULL);
+}
+
static int kryo3xx_pmu_cpu_pm_notify(struct notifier_block *self,
unsigned long action, void *v)
{
switch (action) {
case CPU_PM_EXIT:
+ init_regs_on_cpu(false);
kryo3xx_check_l3_scu_error(panic_handler_drvdata->edev_ctl);
kryo3xx_check_l1_l2_ecc(panic_handler_drvdata->edev_ctl);
break;
@@ -373,23 +396,14 @@
return NOTIFY_OK;
}
-static void initialize_registers(void *info)
-{
- set_errxctlr_el1();
- set_errxmisc_overflow();
-}
-
static int kryo3xx_cpu_erp_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct erp_drvdata *drv;
int rc = 0;
int fail = 0;
- int cpu;
- for_each_possible_cpu(cpu)
- smp_call_function_single(cpu, initialize_registers, NULL, 1);
-
+ init_regs_on_cpu(true);
drv = devm_kzalloc(dev, sizeof(*drv), GFP_KERNEL);