diff --git a/drivers/edac/kryo_arm64_edac.c b/drivers/edac/kryo_arm64_edac.c index 52ac9cacb0a9..991d983a6e02 100644 --- a/drivers/edac/kryo_arm64_edac.c +++ b/drivers/edac/kryo_arm64_edac.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. */ #include @@ -58,6 +58,8 @@ #define KRYO_ERRXMISC_LVL_GOLD(a) (a & 0xF) #define KRYO_ERRXMISC_WAY(a) ((a >> 28) & 0xF) +static enum cpuhp_state edac_online; + static inline void set_errxctlr_el1(void) { u64 val = 0x10f; @@ -203,7 +205,6 @@ static int request_erp_irq(struct platform_device *pdev, const char *propname, } drv->ppi = r->start; - on_each_cpu(l1_l2_irq_enable, &(r->start), 1); } return 0; @@ -491,6 +492,23 @@ static int kryo_pmu_cpu_pm_notify(struct notifier_block *self, return NOTIFY_OK; } +static int kryo_cpu_edac_online(unsigned int cpu) +{ + write_errselr_el1(0); + initialize_registers(NULL); + + l1_l2_irq_enable(&(panic_handler_drvdata->ppi)); + + return 0; +} + +static int kryo_cpu_edac_offline(unsigned int cpu) +{ + l1_l2_irq_disable(&(panic_handler_drvdata->ppi)); + + return 0; +} + static int kryo_cpu_erp_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -565,6 +583,16 @@ static int kryo_cpu_erp_probe(struct platform_device *pdev) goto out_dev; } + rc = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, + "edac/kryo_cpu_cache_erp:online", + kryo_cpu_edac_online, + kryo_cpu_edac_offline); + if (rc < 0) { + pr_err("KRYO ERP: Could not request cpuhp setup\n"); + goto out_dev; + } + + edac_online = rc; cpu_pm_register_notifier(&(drv->nb_pm)); return 0; @@ -588,6 +616,7 @@ static int kryo_cpu_erp_remove(struct platform_device *pdev) free_percpu(drv->erp_cpu_drvdata); } + cpuhp_remove_state(edac_online); cpu_pm_unregister_notifier(&(drv->nb_pm)); edac_device_del_device(edac_ctl->dev); edac_device_free_ctl_info(edac_ctl);