From 2cfb211c8355873d67a7be5b16c412bbace82833 Mon Sep 17 00:00:00 2001 From: Shashank Mittal Date: Fri, 6 May 2016 13:25:24 -0700 Subject: [PATCH] coresight-etm4x: separate cpu dying notifier Use separate notifier for cpu dying callback. This way we can give higher priority to this notifier. That will make sure that etm disable code gets executed before etm save register code during cpu power collapse and etm's registers restore code gets executed before etm enable code while cpu is coming back online. Change-Id: Ibebda314eebd71945e9eae8aa2339fc79c475556 Signed-off-by: Shashank Mittal --- drivers/hwtracing/coresight/coresight-etm4x.c | 49 ++++++++++++++----- 1 file changed, 38 insertions(+), 11 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c index 617c766f032e..5697ad3b1d13 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x.c +++ b/drivers/hwtracing/coresight/coresight-etm4x.c @@ -42,6 +42,7 @@ module_param_named(boot_enable, boot_enable, int, S_IRUGO); static int etm4_count; static struct etmv4_drvdata *etmdrvdata[NR_CPUS]; static struct notifier_block etm4_cpu_notifier; +static struct notifier_block etm4_cpu_dying_notifier; static void etm4_os_unlock(void *info) { @@ -2682,20 +2683,15 @@ static int etm4_cpu_callback(struct notifier_block *nfb, unsigned long action, clk_disable[cpu] = false; } break; - - case CPU_DYING: - spin_lock(&etmdrvdata[cpu]->spinlock); - if (etmdrvdata[cpu]->enable) - etm4_disable_hw(etmdrvdata[cpu]); - spin_unlock(&etmdrvdata[cpu]->spinlock); - break; } out: return NOTIFY_OK; err_init: - if (--etm4_count == 0) + if (--etm4_count == 0) { unregister_hotcpu_notifier(&etm4_cpu_notifier); + unregister_hotcpu_notifier(&etm4_cpu_dying_notifier); + } if (clk_disable[cpu]) { pm_runtime_put(etmdrvdata[cpu]->dev); @@ -2715,6 +2711,31 @@ static struct notifier_block etm4_cpu_notifier = { .notifier_call = etm4_cpu_callback, }; +static int etm4_cpu_dying_callback(struct notifier_block *nfb, + unsigned long action, void *hcpu) +{ + unsigned int cpu = (unsigned long)hcpu; + + if (!etmdrvdata[cpu]) + goto out; + + switch (action & (~CPU_TASKS_FROZEN)) { + case CPU_DYING: + spin_lock(&etmdrvdata[cpu]->spinlock); + if (etmdrvdata[cpu]->enable) + etm4_disable_hw(etmdrvdata[cpu]); + spin_unlock(&etmdrvdata[cpu]->spinlock); + break; + } +out: + return NOTIFY_OK; +} + +static struct notifier_block etm4_cpu_dying_notifier = { + .notifier_call = etm4_cpu_dying_callback, + .priority = 1, +}; + static int etm4_probe(struct amba_device *adev, const struct amba_id *id) { int ret; @@ -2773,8 +2794,10 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id) etmdrvdata[drvdata->cpu] = drvdata; - if (!etm4_count++) + if (!etm4_count++) { register_hotcpu_notifier(&etm4_cpu_notifier); + register_hotcpu_notifier(&etm4_cpu_dying_notifier); + } put_online_cpus(); @@ -2793,8 +2816,10 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id) return 0; err_late_init: - if (--etm4_count == 0) + if (--etm4_count == 0) { unregister_hotcpu_notifier(&etm4_cpu_notifier); + unregister_hotcpu_notifier(&etm4_cpu_dying_notifier); + } return ret; } @@ -2803,8 +2828,10 @@ static int etm4_remove(struct amba_device *adev) struct etmv4_drvdata *drvdata = amba_get_drvdata(adev); coresight_unregister(drvdata->csdev); - if (--etm4_count == 0) + if (--etm4_count == 0) { unregister_hotcpu_notifier(&etm4_cpu_notifier); + unregister_hotcpu_notifier(&etm4_cpu_dying_notifier); + } return 0; }