On Tue, 11 Mar 2025 at 17:05, Leo Yan <leo.yan@xxxxxxx> wrote: > > Add callbacks for pausing and resuming the tracer. > > A "paused" flag in the driver data indicates whether the tracer is > paused. If the flag is set, the driver will skip starting the hardware > trace. The flag is always set to false for the sysfs mode, meaning the > tracer will never be paused in the case. > > Signed-off-by: Leo Yan <leo.yan@xxxxxxx> > --- > .../coresight/coresight-etm4x-core.c | 42 ++++++++++++++++++- > drivers/hwtracing/coresight/coresight-etm4x.h | 2 + > 2 files changed, 43 insertions(+), 1 deletion(-) > > diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c > index 53cb0569dbbf..5b69446db947 100644 > --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c > +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c > @@ -577,7 +577,8 @@ static int etm4_enable_hw(struct etmv4_drvdata *drvdata) > etm4x_relaxed_write32(csa, trcpdcr | TRCPDCR_PU, TRCPDCR); > } > > - rc = etm4_enable_trace_unit(drvdata); > + if (!drvdata->paused) > + rc = etm4_enable_trace_unit(drvdata); > done: > etm4_cs_lock(drvdata, csa); > > @@ -820,6 +821,9 @@ static int etm4_enable_perf(struct coresight_device *csdev, > > drvdata->trcid = path->trace_id; > > + /* Populate pause state */ > + drvdata->paused = !!READ_ONCE(event->hw.aux_paused); > + > /* And enable it */ > ret = etm4_enable_hw(drvdata); > > @@ -846,6 +850,9 @@ static int etm4_enable_sysfs(struct coresight_device *csdev, struct coresight_pa > > drvdata->trcid = path->trace_id; > > + /* Tracer will never be paused in sysfs mode */ > + drvdata->paused = false; > + > /* > * Executing etm4_enable_hw on the cpu whose ETM is being enabled > * ensures that register writes occur when cpu is powered. > @@ -1080,10 +1087,43 @@ static void etm4_disable(struct coresight_device *csdev, > coresight_set_mode(csdev, CS_MODE_DISABLED); > } > > +static int etm4_resume_perf(struct coresight_device *csdev) > +{ > + struct etmv4_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); > + struct csdev_access *csa = &csdev->access; > + > + if (coresight_get_mode(csdev) != CS_MODE_PERF) > + return -EINVAL; > + > + etm4_cs_unlock(drvdata, csa); > + etm4_enable_trace_unit(drvdata); > + etm4_cs_lock(drvdata, csa); > + > + drvdata->paused = false; > + return 0; > +} > + > +static void etm4_pause_perf(struct coresight_device *csdev) > +{ > + struct etmv4_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); > + struct csdev_access *csa = &csdev->access; > + > + if (coresight_get_mode(csdev) != CS_MODE_PERF) > + return; > + > + etm4_cs_unlock(drvdata, csa); > + etm4_disable_trace_unit(drvdata); > + etm4_cs_lock(drvdata, csa); > + > + drvdata->paused = true; > +} > + > static const struct coresight_ops_source etm4_source_ops = { > .cpu_id = etm4_cpu_id, > .enable = etm4_enable, > .disable = etm4_disable, > + .resume_perf = etm4_resume_perf, > + .pause_perf = etm4_pause_perf, > }; > > static const struct coresight_ops etm4_cs_ops = { > diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h > index bd7db36ba197..ac649515054d 100644 > --- a/drivers/hwtracing/coresight/coresight-etm4x.h > +++ b/drivers/hwtracing/coresight/coresight-etm4x.h > @@ -983,6 +983,7 @@ struct etmv4_save_state { > * @state_needs_restore: True when there is context to restore after PM exit > * @skip_power_up: Indicates if an implementation can skip powering up > * the trace unit. > + * @paused: Indicates if the trace unit is paused. > * @arch_features: Bitmap of arch features of etmv4 devices. > */ > struct etmv4_drvdata { > @@ -1036,6 +1037,7 @@ struct etmv4_drvdata { > struct etmv4_save_state *save_state; > bool state_needs_restore; > bool skip_power_up; > + bool paused; > DECLARE_BITMAP(arch_features, ETM4_IMPDEF_FEATURE_MAX); > }; > > -- > 2.34.1 > Reviewed-by: Mike Leach <mike.leach@xxxxxxxxxx> -- Mike Leach Principal Engineer, ARM Ltd. Manchester Design Centre. UK