On 31/05/2024 05:27, Linu Cherian wrote: > Panic callback handlers allows coresight device drivers to sync > relevant trace data and trace metadata to reserved memory > regions so that they can be retrieved later in the subsequent > boot or in the crashdump kernel. > > Signed-off-by: Linu Cherian <lcherian@xxxxxxxxxxx> > --- Reviewed-by: James Clark <james.clark@xxxxxxx> > drivers/hwtracing/coresight/coresight-core.c | 37 ++++++++++++++++++++ > include/linux/coresight.h | 12 +++++++ > 2 files changed, 49 insertions(+) > > diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c > index b83613e34289..61d75aad476b 100644 > --- a/drivers/hwtracing/coresight/coresight-core.c > +++ b/drivers/hwtracing/coresight/coresight-core.c > @@ -19,6 +19,7 @@ > #include <linux/property.h> > #include <linux/delay.h> > #include <linux/pm_runtime.h> > +#include <linux/panic_notifier.h> > > #include "coresight-etm-perf.h" > #include "coresight-priv.h" > @@ -1365,6 +1366,36 @@ const struct bus_type coresight_bustype = { > .name = "coresight", > }; > > +static int coresight_panic_sync(struct device *dev, void *data) > +{ > + int mode; > + struct coresight_device *csdev; > + > + /* Run through panic sync handlers for all enabled devices */ > + csdev = container_of(dev, struct coresight_device, dev); > + mode = coresight_get_mode(csdev); > + > + if ((mode == CS_MODE_SYSFS) || (mode == CS_MODE_PERF)) { > + if (panic_ops(csdev)) > + panic_ops(csdev)->sync(csdev); > + } > + > + return 0; > +} > + > +static int coresight_panic_cb(struct notifier_block *self, > + unsigned long v, void *p) > +{ > + bus_for_each_dev(&coresight_bustype, NULL, NULL, > + coresight_panic_sync); > + > + return 0; > +} > + > +static struct notifier_block coresight_notifier = { > + .notifier_call = coresight_panic_cb, > +}; > + > static int __init coresight_init(void) > { > int ret; > @@ -1377,6 +1408,10 @@ static int __init coresight_init(void) > if (ret) > goto exit_bus_unregister; > > + /* Register function to be called for panic */ > + ret = atomic_notifier_chain_register(&panic_notifier_list, > + &coresight_notifier); > + > /* initialise the coresight syscfg API */ > ret = cscfg_init(); > if (!ret) > @@ -1391,6 +1426,8 @@ static int __init coresight_init(void) > static void __exit coresight_exit(void) > { > cscfg_exit(); > + atomic_notifier_chain_unregister(&panic_notifier_list, > + &coresight_notifier); > etm_perf_exit(); > bus_unregister(&coresight_bustype); > } > diff --git a/include/linux/coresight.h b/include/linux/coresight.h > index 5f288d475490..b156467c9baa 100644 > --- a/include/linux/coresight.h > +++ b/include/linux/coresight.h > @@ -315,6 +315,7 @@ enum cs_mode { > #define link_ops(csdev) csdev->ops->link_ops > #define helper_ops(csdev) csdev->ops->helper_ops > #define ect_ops(csdev) csdev->ops->ect_ops > +#define panic_ops(csdev) csdev->ops->panic_ops > > /** > * struct coresight_ops_sink - basic operations for a sink > @@ -384,11 +385,22 @@ struct coresight_ops_helper { > int (*disable)(struct coresight_device *csdev, void *data); > }; > > + > +/** > + * struct coresight_ops_panic - Generic device ops for panic handing > + * > + * @sync : Sync the device register state/trace data > + */ > +struct coresight_ops_panic { > + int (*sync)(struct coresight_device *csdev); > +}; > + > struct coresight_ops { > const struct coresight_ops_sink *sink_ops; > const struct coresight_ops_link *link_ops; > const struct coresight_ops_source *source_ops; > const struct coresight_ops_helper *helper_ops; > + const struct coresight_ops_panic *panic_ops; > }; > > static inline u32 csdev_access_relaxed_read32(struct csdev_access *csa,