mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-22 03:27:30 -04:00
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 <james.clark@linaro.org> Tested-by: James Clark <james.clark@linaro.org> Reviewed-by: Yeoreum Yun <yeoreum.yun@arm.com> Tested-by: Jie Gan <jie.gan@oss.qualcomm.com> Signed-off-by: Leo Yan <leo.yan@arm.com> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> Link: https://lore.kernel.org/r/20260515-arm_coresight_path_power_management_improvement-v14-12-f88c4a3ecfe9@arm.com
This commit is contained in:
committed by
Suzuki K Poulose
parent
4d8dd98ee5
commit
0f5e588c70
@@ -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 @@ static int __etm4_cpu_save(struct etmv4_drvdata *drvdata)
|
||||
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();
|
||||
static const struct coresight_ops etm4_cs_ops = {
|
||||
.trace_id = coresight_etm_get_trace_id,
|
||||
.source_ops = &etm4_source_ops,
|
||||
};
|
||||
|
||||
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 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;
|
||||
|
||||
Reference in New Issue
Block a user