On Fri, Aug 02, 2019 at 11:54:12AM +0100, Suzuki K Poulose wrote:
On 30/07/2019 13:51, Andrew Murray wrote:
Some hardware will ignore bit TRCPDCR.PU which is used to signal to hardware that power should not be removed from the trace unit. Let's mitigate against this by conditionally saving and restoring the trace unit state when the CPU enters low power states.
This patchset introduces a firmware property named 'arm,coresight-needs-save-restore' - when this is present the hardware state will be conditionally saved and restored.
A module parameter 'pm_save_enable' is also introduced which can be configured to override the firmware property. This can be set to never allow save/restore, to conditionally allow it, or to do as the firmware indicates (default).
We avoid saving the hardware state when coresight isn't in use to reduce PM latency - we can't determine this by reading the claim tags (TRCCLAIMCLR) as these are 'trace' registers which need power and clocking, something we can't easily provide in the PM context. Therefore we rely on the existing drvdata->mode internal state that is set when self-hosted coresight is used (and powered).
As we do not have a simple way of determining if an external agent is using coresight, we don't save/restore for this use case.
Signed-off-by: Andrew Murray andrew.murray@arm.com
drivers/hwtracing/coresight/coresight-etm4x.c | 322 ++++++++++++++++++ drivers/hwtracing/coresight/coresight-etm4x.h | 64 ++++ 2 files changed, 386 insertions(+)
diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c index a128b5063f46..30f118792289 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x.c +++ b/drivers/hwtracing/coresight/coresight-etm4x.c
+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 0;
- drvdata = etmdrvdata[cpu];
- if (!drvdata->save_state)
return NOTIFY_OK;
- if (WARN_ON_ONCE(drvdata->cpu != smp_processor_id()))
return NOTIFY_BAD;
minor nit: you may skip the second call to smp_processor_id() as this is called on from non-preemptible context.
- switch (cmd) {
- case CPU_PM_ENTER:
/* save the state if self-hosted coresight is in use */
if (local_read(&drvdata->mode))
if (etm4_cpu_save(drvdata))
return NOTIFY_BAD;
break;
- case CPU_PM_EXIT:
- case CPU_PM_ENTER_FAILED:
/* trcclaimset is set when there is state to restore */
if (drvdata->state_needs_restore)
etm4_cpu_restore(drvdata);
break;
- default:
return NOTIFY_DONE;
- }
- return NOTIFY_OK;
+}
+static void etm4_cpu_pm_unregister(void) +{
- cpu_pm_unregister_notifier(&etm4_cpu_pm_nb);
+} +#else +static int etm4_cpu_pm_register(void) { return 0; } +static void etm4_cpu_pm_unregister(void) { } +#endif
+static inline bool etm4_needs_save_restore(struct device *dev) +{
- return fwnode_property_present(dev->fwnode,
nit: It may be safe to use dev_fwnode(dev), instead of dev->fwnode. But I see a lot of existing users of dev->fwnode. Not sure it does have an impact.
Looks fine to me ,
Reviewed-by: Suzuki K Poulose suzuki.poulose@arm.com
Thanks - I'll make these changes.
Andrew Murray
linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel