edac: arm64: Enable cti pmu workaround on CPUs onlined post-boot
The CTI PMU workaround for the EDAC interrupt is enabled at probe only on the CPUs that are online during boot-up. Some of the CPUs can be onlined at a later point from userspace. Ensure that the workaround is enabled on those CPUs as well. Change-Id: I551b228d3df3f7ed7d935a55aec6474339d569a6 Signed-off-by: Rohit Vaswani <rvaswani@codeaurora.org>
This commit is contained in:
parent
7dd146b7f3
commit
8a138da0fc
|
@ -111,7 +111,9 @@ struct erp_drvdata {
|
|||
struct edac_device_ctl_info *edev_ctl;
|
||||
void __iomem *cci_base;
|
||||
u32 mem_perf_counter;
|
||||
struct notifier_block nb;
|
||||
struct notifier_block nb_pm;
|
||||
struct notifier_block nb_cpu;
|
||||
struct work_struct work;
|
||||
};
|
||||
|
||||
static struct erp_drvdata *abort_handler_drvdata;
|
||||
|
@ -754,7 +756,7 @@ static void check_sbe_event(struct erp_drvdata *drv)
|
|||
static int arm64_pmu_cpu_pm_notify(struct notifier_block *self,
|
||||
unsigned long action, void *v)
|
||||
{
|
||||
struct erp_drvdata *drv = container_of(self, struct erp_drvdata, nb);
|
||||
struct erp_drvdata *drv = container_of(self, struct erp_drvdata, nb_pm);
|
||||
|
||||
switch (action) {
|
||||
case CPU_PM_EXIT:
|
||||
|
@ -766,6 +768,20 @@ static int arm64_pmu_cpu_pm_notify(struct notifier_block *self,
|
|||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
static int msm_cti_pmu_wa_cpu_notify(struct notifier_block *self,
|
||||
unsigned long action, void *hcpu)
|
||||
{
|
||||
struct erp_drvdata *drv = container_of(self, struct erp_drvdata,
|
||||
nb_cpu);
|
||||
switch (action) {
|
||||
case CPU_ONLINE:
|
||||
schedule_work_on((unsigned long)hcpu, &drv->work);
|
||||
break;
|
||||
};
|
||||
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
static int arm64_cpu_erp_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
|
@ -852,11 +868,14 @@ static int arm64_cpu_erp_probe(struct platform_device *pdev)
|
|||
goto out_irq;
|
||||
}
|
||||
|
||||
drv->nb.notifier_call = arm64_pmu_cpu_pm_notify;
|
||||
drv->nb_pm.notifier_call = arm64_pmu_cpu_pm_notify;
|
||||
drv->mem_perf_counter = arm64_pmu_get_last_counter();
|
||||
cpu_pm_register_notifier(&(drv->nb));
|
||||
cpu_pm_register_notifier(&(drv->nb_pm));
|
||||
drv->nb_cpu.notifier_call = msm_cti_pmu_wa_cpu_notify;
|
||||
register_cpu_notifier(&drv->nb_cpu);
|
||||
arm64_pmu_irq_handled_externally();
|
||||
schedule_on_each_cpu(msm_enable_cti_pmu_workaround);
|
||||
INIT_WORK(&drv->work, msm_enable_cti_pmu_workaround);
|
||||
on_each_cpu(sbe_enable_event, drv, 1);
|
||||
on_each_cpu(arm64_enable_pmu_irq, &sbe_irq, 1);
|
||||
|
||||
|
|
|
@ -13,9 +13,11 @@
|
|||
#include <linux/coresight-cti.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/percpu.h>
|
||||
#include <linux/smp.h>
|
||||
#include <soc/qcom/cti-pmu-irq.h>
|
||||
|
||||
static DEFINE_PER_CPU(int, msm_cti_pmu_wa_done);
|
||||
static struct coresight_cti *msm_cti_cpux[NR_CPUS];
|
||||
static const char * const coresight_cpu_name[] = {
|
||||
"coresight-cti-cpu0",
|
||||
|
@ -47,9 +49,12 @@ void msm_enable_cti_pmu_workaround(struct work_struct *work)
|
|||
int trigin = 1;
|
||||
int trigout = 2;
|
||||
int ch = 2;
|
||||
int cpu = smp_processor_id();
|
||||
int cpu = raw_smp_processor_id();
|
||||
int ret;
|
||||
|
||||
if (per_cpu(msm_cti_pmu_wa_done, cpu) == true)
|
||||
return;
|
||||
|
||||
cti_cpux = coresight_cti_get(coresight_cpu_name[cpu]);
|
||||
if (IS_ERR(cti_cpux))
|
||||
goto err;
|
||||
|
@ -63,6 +68,7 @@ void msm_enable_cti_pmu_workaround(struct work_struct *work)
|
|||
if (ret)
|
||||
goto err_out;
|
||||
coresight_cti_enable_gate(cti_cpux, ch);
|
||||
per_cpu(msm_cti_pmu_wa_done, cpu) = true;
|
||||
pr_info("%s for CPU %d\n", __func__, cpu);
|
||||
|
||||
return;
|
||||
|
|
Loading…
Reference in New Issue