Add a callback in the source device that returns a boolean indicating whether power management operations are required. The save and restore flow is skipped if the callback returns false.
The ETMv4 driver implements its own version's callback.
Signed-off-by: Leo Yan leo.yan@arm.com --- drivers/hwtracing/coresight/coresight-core.c | 9 ++++++++- drivers/hwtracing/coresight/coresight-etm4x-core.c | 16 ++++++++++++++++ include/linux/coresight.h | 1 + 3 files changed, 25 insertions(+), 1 deletion(-)
diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c index f642190740b93555084584abbc1d9426cc87ec7c..0d4e935094297023b8a7786ff4b1b3783164016b 100644 --- a/drivers/hwtracing/coresight/coresight-core.c +++ b/drivers/hwtracing/coresight/coresight-core.c @@ -1586,7 +1586,14 @@ static bool coresight_pm_is_needed(struct coresight_device *csdev) !coresight_ops(csdev)->pm_restore_enable) return false;
- return true; + /* + * PM callbacks are provided but pm_is_neended() is absent, it means + * no extra check is needed. + */ + if (!coresight_ops(csdev)->pm_is_needed) + return true; + + return coresight_ops(csdev)->pm_is_needed(csdev); }
static int coresight_pm_save(struct coresight_device *csdev) diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c index adb5c6b12c6f3113747f1f455087b1ab497a53f6..da135849c70833366aa1089a0752bc7844c0d96d 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c @@ -1838,6 +1838,21 @@ static int etm4_dying_cpu(unsigned int cpu) return 0; }
+static bool etm4_need_save_restore_context(struct coresight_device *csdev) +{ + if (pm_save_enable != PARAM_PM_SAVE_SELF_HOSTED) + return false; + + /* + * Save and restore the ETM Trace registers only if + * the ETM is active. + */ + if (coresight_get_mode(csdev)) + return true; + + return false; +} + static int __etm4_cpu_save(struct etmv4_drvdata *drvdata) { int ret = 0; @@ -1929,6 +1944,7 @@ static const struct coresight_ops etm4_cs_ops = { .trace_id = coresight_etm_get_trace_id, .pm_save_disable = etm4_cpu_save, .pm_restore_enable = etm4_cpu_restore, + .pm_is_needed = etm4_need_save_restore_context, .source_ops = &etm4_source_ops, };
diff --git a/include/linux/coresight.h b/include/linux/coresight.h index b10ef4fa17a76b4d11223cc8fd43e5544b6ea8b9..3d59be214dd25dfa7ad9148a6688628e0d1a98dd 100644 --- a/include/linux/coresight.h +++ b/include/linux/coresight.h @@ -441,6 +441,7 @@ struct coresight_ops { struct coresight_device *sink); int (*pm_save_disable)(struct coresight_device *csdev); void (*pm_restore_enable)(struct coresight_device *csdev); + bool (*pm_is_needed)(struct coresight_device *csdev); const struct coresight_ops_sink *sink_ops; const struct coresight_ops_link *link_ops; const struct coresight_ops_source *source_ops;