From: Leo Yan Date: Fri, 15 May 2026 20:08:19 +0000 (+0100) Subject: coresight: etm4x: Hook CPU PM callbacks X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=0f5e588c70a868c475cef22193f12bed678e1461;p=thirdparty%2Fkernel%2Fstable.git coresight: etm4x: Hook CPU PM callbacks Add a helper etm4_pm_save_needed() to detect if need save context for self-hosted PM mode and hook pm_save_disable() and pm_restore_enable() callbacks through etm4_cs_pm_ops structure. With this, ETMv4 PM save/restore is integrated into the core layer's CPU PM. Organize etm4_cs_ops and etm4_cs_pm_ops together for more readable. The CPU PM notifier in the ETMv4 driver is no longer needed, remove it along with its registration and unregistration code. Reviewed-by: James Clark Tested-by: James Clark Reviewed-by: Yeoreum Yun Tested-by: Jie Gan Signed-off-by: Leo Yan Signed-off-by: Suzuki K Poulose Link: https://lore.kernel.org/r/20260515-arm_coresight_path_power_management_improvement-v14-12-f88c4a3ecfe9@arm.com --- diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c index 7011a20d2004..5cd70f0f3710 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c @@ -1195,11 +1195,6 @@ static const struct coresight_ops_source etm4_source_ops = { .pause_perf = etm4_pause_perf, }; -static const struct coresight_ops etm4_cs_ops = { - .trace_id = coresight_etm_get_trace_id, - .source_ops = &etm4_source_ops, -}; - static bool cpu_supports_sysreg_trace(void) { u64 dfr0 = read_sysreg_s(SYS_ID_AA64DFR0_EL1); @@ -1853,6 +1848,11 @@ static int etm4_dying_cpu(unsigned int cpu) return 0; } +static inline bool etm4_pm_save_needed(struct etmv4_drvdata *drvdata) +{ + return !!drvdata->save_state; +} + static int __etm4_cpu_save(struct etmv4_drvdata *drvdata) { int i, ret = 0; @@ -1995,11 +1995,12 @@ out: return ret; } -static int etm4_cpu_save(struct etmv4_drvdata *drvdata) +static int etm4_cpu_save(struct coresight_device *csdev) { + struct etmv4_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); int ret = 0; - if (!drvdata->save_state) + if (!etm4_pm_save_needed(drvdata)) return 0; /* @@ -2112,47 +2113,27 @@ static void __etm4_cpu_restore(struct etmv4_drvdata *drvdata) etm4_cs_lock(drvdata, csa); } -static void etm4_cpu_restore(struct etmv4_drvdata *drvdata) +static void etm4_cpu_restore(struct coresight_device *csdev) { - if (!drvdata->save_state) + struct etmv4_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); + + if (!etm4_pm_save_needed(drvdata)) return; if (coresight_get_mode(drvdata->csdev)) __etm4_cpu_restore(drvdata); } -static int etm4_cpu_pm_notify(struct notifier_block *nb, unsigned long cmd, - void *v) -{ - struct etmv4_drvdata *drvdata; - unsigned int cpu = smp_processor_id(); - - if (!etmdrvdata[cpu]) - return NOTIFY_OK; - - drvdata = etmdrvdata[cpu]; - - if (WARN_ON_ONCE(drvdata->cpu != cpu)) - return NOTIFY_BAD; - - switch (cmd) { - case CPU_PM_ENTER: - if (etm4_cpu_save(drvdata)) - return NOTIFY_BAD; - break; - case CPU_PM_EXIT: - case CPU_PM_ENTER_FAILED: - etm4_cpu_restore(drvdata); - break; - default: - return NOTIFY_DONE; - } - - return NOTIFY_OK; -} +static const struct coresight_ops etm4_cs_ops = { + .trace_id = coresight_etm_get_trace_id, + .source_ops = &etm4_source_ops, +}; -static struct notifier_block etm4_cpu_pm_nb = { - .notifier_call = etm4_cpu_pm_notify, +static const struct coresight_ops etm4_cs_pm_ops = { + .trace_id = coresight_etm_get_trace_id, + .source_ops = &etm4_source_ops, + .pm_save_disable = etm4_cpu_save, + .pm_restore_enable = etm4_cpu_restore, }; /* Setup PM. Deals with error conditions and counts */ @@ -2160,16 +2141,12 @@ static int __init etm4_pm_setup(void) { int ret; - ret = cpu_pm_register_notifier(&etm4_cpu_pm_nb); - if (ret) - return ret; - ret = cpuhp_setup_state_nocalls(CPUHP_AP_ARM_CORESIGHT_STARTING, "arm/coresight4:starting", etm4_starting_cpu, etm4_dying_cpu); if (ret) - goto unregister_notifier; + return ret; ret = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, "arm/coresight4:online", @@ -2183,15 +2160,11 @@ static int __init etm4_pm_setup(void) /* failed dyn state - remove others */ cpuhp_remove_state_nocalls(CPUHP_AP_ARM_CORESIGHT_STARTING); - -unregister_notifier: - cpu_pm_unregister_notifier(&etm4_cpu_pm_nb); return ret; } static void etm4_pm_clear(void) { - cpu_pm_unregister_notifier(&etm4_cpu_pm_nb); cpuhp_remove_state_nocalls(CPUHP_AP_ARM_CORESIGHT_STARTING); if (hp_online) { cpuhp_remove_state_nocalls(hp_online); @@ -2270,7 +2243,7 @@ static int etm4_add_coresight_dev(struct etm4_init_arg *init_arg) desc.type = CORESIGHT_DEV_TYPE_SOURCE; desc.subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_PROC; - desc.ops = &etm4_cs_ops; + desc.ops = etm4_pm_save_needed(drvdata) ? &etm4_cs_pm_ops : &etm4_cs_ops; desc.pdata = pdata; desc.dev = dev; desc.groups = coresight_etmv4_groups;