[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20210316180400.7184-6-mike.leach@linaro.org>
Date: Tue, 16 Mar 2021 18:03:55 +0000
From: Mike Leach <mike.leach@...aro.org>
To: linux-arm-kernel@...ts.infradead.org, coresight@...ts.linaro.org,
mathieu.poirier@...aro.org, linux-doc@...r.kernel.org,
suzuki.poulose@....com
Cc: yabinc@...gle.com, corbet@....net, leo.yan@...aro.org,
alexander.shishkin@...ux.intel.com, tingwei@...eaurora.org,
gregkh@...uxfoundation.org, linux-kernel@...r.kernel.org,
Mike Leach <mike.leach@...aro.org>
Subject: [PATCH v5 05/10] coresight: syscfg: Add API to activate and enable configurations
Configurations are first activated, then when any coresight device is
enabled, the active configurations are checked and any matching
one is enabled.
This patch provides the activation / enable API.
Signed-off-by: Mike Leach <mike.leach@...aro.org>
---
.../hwtracing/coresight/coresight-config.h | 2 +
.../hwtracing/coresight/coresight-syscfg.c | 122 ++++++++++++++++++
.../hwtracing/coresight/coresight-syscfg.h | 8 ++
include/linux/coresight.h | 2 +
4 files changed, 134 insertions(+)
diff --git a/drivers/hwtracing/coresight/coresight-config.h b/drivers/hwtracing/coresight/coresight-config.h
index 38fd1c71eb05..f1a5957a25c9 100644
--- a/drivers/hwtracing/coresight/coresight-config.h
+++ b/drivers/hwtracing/coresight/coresight-config.h
@@ -127,6 +127,7 @@ struct cscfg_feature_desc {
* @nr_total_params: Sum of all parameters declared by used features
* @presets: Array of preset values.
* @event_ea: Extended attribute for perf event value
+ * @active_cnt: ref count for activate on this configuration.
*
*/
struct cscfg_config_desc {
@@ -139,6 +140,7 @@ struct cscfg_config_desc {
int nr_total_params;
const u64 *presets; /* nr_presets * nr_total_params */
struct dev_ext_attribute *event_ea;
+ atomic_t active_cnt;
};
/**
diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c
index 03014a2142c1..c44746d6cd6d 100644
--- a/drivers/hwtracing/coresight/coresight-syscfg.c
+++ b/drivers/hwtracing/coresight/coresight-syscfg.c
@@ -284,6 +284,7 @@ static int cscfg_load_config(struct cscfg_config_desc *config_desc)
return err;
list_add(&config_desc->item, &cscfg_mgr->config_desc_list);
+ atomic_set(&config_desc->active_cnt, 0);
return 0;
}
@@ -451,6 +452,126 @@ void cscfg_unregister_csdev(struct coresight_device *csdev)
}
EXPORT_SYMBOL_GPL(cscfg_unregister_csdev);
+void cscfg_csdev_reset_feats(struct coresight_device *csdev)
+{
+ struct cscfg_feature_csdev *feat_csdev;
+
+ mutex_lock(&cscfg_csdev_mutex);
+ if (list_empty(&csdev->feature_csdev_list))
+ goto unlock_exit;
+
+ list_for_each_entry(feat_csdev, &csdev->feature_csdev_list, node)
+ cscfg_reset_feat(feat_csdev);
+
+unlock_exit:
+ mutex_unlock(&cscfg_csdev_mutex);
+}
+EXPORT_SYMBOL_GPL(cscfg_csdev_reset_feats);
+
+/**
+ * Mark a config descriptor as active.
+ * This will be seen when csdev devices are activated in the system.
+ *
+ * Selection by hash value - generated from the configuration name when it
+ * was loaded and added to the cs_etm/configurations file system for selection
+ * by perf.
+ *
+ * @cfg_hash: Hash value of the selected configuration name.
+ */
+int cscfg_activate_config(unsigned long cfg_hash)
+{
+ struct cscfg_config_desc *config_desc;
+ int err = -EINVAL;
+
+ mutex_lock(&cscfg_mutex);
+
+ list_for_each_entry(config_desc, &cscfg_mgr->config_desc_list, item) {
+ if ((unsigned long)config_desc->event_ea->var == cfg_hash) {
+ /*
+ * increment the global active count - control changes to
+ * active configurations
+ */
+ atomic_inc(&cscfg_mgr->sys_active_cnt);
+
+ /*
+ * mark the descriptor as active so enable config on a
+ * device instance will use it
+ */
+ atomic_inc(&config_desc->active_cnt);
+
+ err = 0;
+ dev_dbg(cscfg_device(), "Activate config %s.\n", config_desc->name);
+ break;
+ }
+ }
+ mutex_unlock(&cscfg_mutex);
+
+ return err;
+}
+EXPORT_SYMBOL_GPL(cscfg_activate_config);
+
+void cscfg_deactivate_config(unsigned long cfg_hash)
+{
+ struct cscfg_config_desc *config_desc;
+
+ mutex_lock(&cscfg_mutex);
+
+ list_for_each_entry(config_desc, &cscfg_mgr->config_desc_list, item) {
+ if ((unsigned long)config_desc->event_ea->var == cfg_hash) {
+ atomic_dec(&config_desc->active_cnt);
+ atomic_dec(&cscfg_mgr->sys_active_cnt);
+ dev_dbg(cscfg_device(), "Deactivate config %s.\n", config_desc->name);
+ break;
+ }
+ }
+ mutex_unlock(&cscfg_mutex);
+}
+EXPORT_SYMBOL_GPL(cscfg_deactivate_config);
+
+/* Find and program any active config for the supplied device.*/
+int cscfg_csdev_enable_active_config(struct coresight_device *csdev,
+ unsigned long cfg_hash, int preset)
+{
+ struct cscfg_config_csdev *config_csdev_active = NULL, *config_csdev_item;
+ const struct cscfg_config_desc *config_desc;
+ int err = 0;
+
+ /* quickly check global count */
+ if (!atomic_read(&cscfg_mgr->sys_active_cnt))
+ return 0;
+
+ mutex_lock(&cscfg_csdev_mutex);
+ list_for_each_entry(config_csdev_item, &csdev->config_csdev_list, node) {
+ config_desc = config_csdev_item->config_desc;
+ if ((atomic_read(&config_desc->active_cnt)) &&
+ ((unsigned long)config_desc->event_ea->var == cfg_hash)) {
+ config_csdev_active = config_csdev_item;
+ break;
+ }
+ }
+ if (config_csdev_active) {
+ err = cscfg_csdev_enable_config(config_csdev_active, preset);
+ if (!err)
+ csdev->active_cscfg_ctxt = (void *)config_csdev_active;
+ }
+ mutex_unlock(&cscfg_csdev_mutex);
+ return err;
+}
+EXPORT_SYMBOL_GPL(cscfg_csdev_enable_active_config);
+
+/* save and disable the active config for the device */
+void cscfg_csdev_disable_active_config(struct coresight_device *csdev)
+{
+ struct cscfg_config_csdev *config_csdev;
+
+ mutex_lock(&cscfg_csdev_mutex);
+ config_csdev = (struct cscfg_config_csdev *)csdev->active_cscfg_ctxt;
+ if (config_csdev)
+ cscfg_csdev_disable_config(config_csdev);
+ mutex_unlock(&cscfg_csdev_mutex);
+}
+EXPORT_SYMBOL_GPL(cscfg_csdev_disable_active_config);
+
/* Initialise system configuration management device. */
struct device *cscfg_device(void)
@@ -519,6 +640,7 @@ int __init cscfg_init(void)
INIT_LIST_HEAD(&cscfg_mgr->csdev_desc_list);
INIT_LIST_HEAD(&cscfg_mgr->feat_desc_list);
INIT_LIST_HEAD(&cscfg_mgr->config_desc_list);
+ atomic_set(&cscfg_mgr->sys_active_cnt, 0);
dev_info(cscfg_device(), "CoreSight Configuration manager initialised");
return 0;
diff --git a/drivers/hwtracing/coresight/coresight-syscfg.h b/drivers/hwtracing/coresight/coresight-syscfg.h
index 5bcae3b374c6..a52775890670 100644
--- a/drivers/hwtracing/coresight/coresight-syscfg.h
+++ b/drivers/hwtracing/coresight/coresight-syscfg.h
@@ -24,12 +24,14 @@
* @csdev_desc_list: List of coresight devices registered with the configuration manager.
* @feat_desc_list: List of feature descriptors to load into registered devices.
* @config_desc_list: List of system configuration descriptors to load into registered devices.
+ * @sys_active_cnt: Total number of active config descriptor references.
*/
struct cscfg_manager {
struct device dev;
struct list_head csdev_desc_list;
struct list_head feat_desc_list;
struct list_head config_desc_list;
+ atomic_t sys_active_cnt;
};
/* get reference to dev in cscfg_manager */
@@ -61,5 +63,11 @@ int cscfg_load_config_sets(struct cscfg_config_desc **cfg_descs,
int cscfg_register_csdev(struct coresight_device *csdev, u32 match_flags,
struct cscfg_csdev_feat_ops *ops);
void cscfg_unregister_csdev(struct coresight_device *csdev);
+int cscfg_activate_config(unsigned long cfg_hash);
+void cscfg_deactivate_config(unsigned long cfg_hash);
+void cscfg_csdev_reset_feats(struct coresight_device *csdev);
+int cscfg_csdev_enable_active_config(struct coresight_device *csdev,
+ unsigned long cfg_hash, int preset);
+void cscfg_csdev_disable_active_config(struct coresight_device *csdev);
#endif /* CORESIGHT_SYSCFG_H */
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index d0126ed326a6..a3b39ce2d6ef 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -221,6 +221,7 @@ struct coresight_sysfs_link {
* @has_conns_grp: Have added a "connections" group for sysfs links.
* @feature_csdev_list: List of complex feature programming added to the device.
* @config_csdev_list: List of system configurations added to the device.
+ * @active_cscfg_ctxt: Context information for current active system configuration.
*/
struct coresight_device {
struct coresight_platform_data *pdata;
@@ -245,6 +246,7 @@ struct coresight_device {
/* system configuration and feature lists */
struct list_head feature_csdev_list;
struct list_head config_csdev_list;
+ void *active_cscfg_ctxt;
};
/*
--
2.17.1
Powered by blists - more mailing lists