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);