Commit a13d5a24 authored by Mike Leach's avatar Mike Leach Committed by Greg Kroah-Hartman

coresight: syscfg: Add initial configfs support

Adds configfs subsystem and attributes to the configuration manager
to enable the listing of loaded configurations and features.

The default values of feature parameters can be accessed and altered
from these attributes to affect all installed devices using the feature.

Link: https://lore.kernel.org/r/20210723165444.1048-10-mike.leach@linaro.orgSigned-off-by: default avatarMike Leach <mike.leach@linaro.org>
Signed-off-by: default avatarMathieu Poirier <mathieu.poirier@linaro.org>
Link: https://lore.kernel.org/r/20210818194022.379573-10-mathieu.poirier@linaro.orgSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 7fdc9bb2
...@@ -8,6 +8,7 @@ menuconfig CORESIGHT ...@@ -8,6 +8,7 @@ menuconfig CORESIGHT
depends on OF || ACPI depends on OF || ACPI
select ARM_AMBA select ARM_AMBA
select PERF_EVENTS select PERF_EVENTS
select CONFIGFS_FS
help help
This framework provides a kernel interface for the CoreSight debug This framework provides a kernel interface for the CoreSight debug
and trace drivers to register themselves with. It's intended to build and trace drivers to register themselves with. It's intended to build
......
...@@ -5,7 +5,8 @@ ...@@ -5,7 +5,8 @@
obj-$(CONFIG_CORESIGHT) += coresight.o obj-$(CONFIG_CORESIGHT) += coresight.o
coresight-y := coresight-core.o coresight-etm-perf.o coresight-platform.o \ coresight-y := coresight-core.o coresight-etm-perf.o coresight-platform.o \
coresight-sysfs.o coresight-syscfg.o coresight-config.o \ coresight-sysfs.o coresight-syscfg.o coresight-config.o \
coresight-cfg-preload.o coresight-cfg-afdo.o coresight-cfg-preload.o coresight-cfg-afdo.o \
coresight-syscfg-configfs.o
obj-$(CONFIG_CORESIGHT_LINK_AND_SINK_TMC) += coresight-tmc.o obj-$(CONFIG_CORESIGHT_LINK_AND_SINK_TMC) += coresight-tmc.o
coresight-tmc-y := coresight-tmc-core.o coresight-tmc-etf.o \ coresight-tmc-y := coresight-tmc-core.o coresight-tmc-etf.o \
coresight-tmc-etr.o coresight-tmc-etr.o
......
This diff is collapsed.
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Coresight system configuration driver - support for configfs.
*/
#ifndef CORESIGHT_SYSCFG_CONFIGFS_H
#define CORESIGHT_SYSCFG_CONFIGFS_H
#include <linux/configfs.h>
#include "coresight-syscfg.h"
#define CSCFG_FS_SUBSYS_NAME "cs-syscfg"
/* container for configuration view */
struct cscfg_fs_config {
struct cscfg_config_desc *config_desc;
struct config_group group;
};
/* container for feature view */
struct cscfg_fs_feature {
struct cscfg_feature_desc *feat_desc;
struct config_group group;
};
/* container for parameter view */
struct cscfg_fs_param {
int param_idx;
struct cscfg_feature_desc *feat_desc;
struct config_group group;
};
/* container for preset view */
struct cscfg_fs_preset {
int preset_num;
struct cscfg_config_desc *config_desc;
struct config_group group;
};
int cscfg_configfs_init(struct cscfg_manager *cscfg_mgr);
void cscfg_configfs_release(struct cscfg_manager *cscfg_mgr);
int cscfg_configfs_add_config(struct cscfg_config_desc *config_desc);
int cscfg_configfs_add_feature(struct cscfg_feature_desc *feat_desc);
#endif /* CORESIGHT_SYSCFG_CONFIGFS_H */
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "coresight-config.h" #include "coresight-config.h"
#include "coresight-etm-perf.h" #include "coresight-etm-perf.h"
#include "coresight-syscfg.h" #include "coresight-syscfg.h"
#include "coresight-syscfg-configfs.h"
/* /*
* cscfg_ API manages configurations and features for the entire coresight * cscfg_ API manages configurations and features for the entire coresight
...@@ -286,6 +287,72 @@ static int cscfg_load_config(struct cscfg_config_desc *config_desc) ...@@ -286,6 +287,72 @@ static int cscfg_load_config(struct cscfg_config_desc *config_desc)
return 0; return 0;
} }
/* get a feature descriptor by name */
const struct cscfg_feature_desc *cscfg_get_named_feat_desc(const char *name)
{
const struct cscfg_feature_desc *feat_desc = NULL, *feat_desc_item;
mutex_lock(&cscfg_mutex);
list_for_each_entry(feat_desc_item, &cscfg_mgr->feat_desc_list, item) {
if (strcmp(feat_desc_item->name, name) == 0) {
feat_desc = feat_desc_item;
break;
}
}
mutex_unlock(&cscfg_mutex);
return feat_desc;
}
/* called with cscfg_mutex held */
static struct cscfg_feature_csdev *
cscfg_csdev_get_feat_from_desc(struct coresight_device *csdev,
struct cscfg_feature_desc *feat_desc)
{
struct cscfg_feature_csdev *feat_csdev;
list_for_each_entry(feat_csdev, &csdev->feature_csdev_list, node) {
if (feat_csdev->feat_desc == feat_desc)
return feat_csdev;
}
return NULL;
}
int cscfg_update_feat_param_val(struct cscfg_feature_desc *feat_desc,
int param_idx, u64 value)
{
int err = 0;
struct cscfg_feature_csdev *feat_csdev;
struct cscfg_registered_csdev *csdev_item;
mutex_lock(&cscfg_mutex);
/* check if any config active & return busy */
if (atomic_read(&cscfg_mgr->sys_active_cnt)) {
err = -EBUSY;
goto unlock_exit;
}
/* set the value */
if ((param_idx < 0) || (param_idx >= feat_desc->nr_params)) {
err = -EINVAL;
goto unlock_exit;
}
feat_desc->params_desc[param_idx].value = value;
/* update loaded instances.*/
list_for_each_entry(csdev_item, &cscfg_mgr->csdev_desc_list, item) {
feat_csdev = cscfg_csdev_get_feat_from_desc(csdev_item->csdev, feat_desc);
if (feat_csdev)
feat_csdev->params_csdev[param_idx].current_value = value;
}
unlock_exit:
mutex_unlock(&cscfg_mutex);
return err;
}
/** /**
* cscfg_load_config_sets - API function to load feature and config sets. * cscfg_load_config_sets - API function to load feature and config sets.
* *
...@@ -307,6 +374,8 @@ int cscfg_load_config_sets(struct cscfg_config_desc **config_descs, ...@@ -307,6 +374,8 @@ int cscfg_load_config_sets(struct cscfg_config_desc **config_descs,
if (feat_descs) { if (feat_descs) {
while (feat_descs[i]) { while (feat_descs[i]) {
err = cscfg_load_feat(feat_descs[i]); err = cscfg_load_feat(feat_descs[i]);
if (!err)
err = cscfg_configfs_add_feature(feat_descs[i]);
if (err) { if (err) {
pr_err("coresight-syscfg: Failed to load feature %s\n", pr_err("coresight-syscfg: Failed to load feature %s\n",
feat_descs[i]->name); feat_descs[i]->name);
...@@ -321,6 +390,8 @@ int cscfg_load_config_sets(struct cscfg_config_desc **config_descs, ...@@ -321,6 +390,8 @@ int cscfg_load_config_sets(struct cscfg_config_desc **config_descs,
if (config_descs) { if (config_descs) {
while (config_descs[i]) { while (config_descs[i]) {
err = cscfg_load_config(config_descs[i]); err = cscfg_load_config(config_descs[i]);
if (!err)
err = cscfg_configfs_add_config(config_descs[i]);
if (err) { if (err) {
pr_err("coresight-syscfg: Failed to load configuration %s\n", pr_err("coresight-syscfg: Failed to load configuration %s\n",
config_descs[i]->name); config_descs[i]->name);
...@@ -734,6 +805,7 @@ static void cscfg_clear_device(void) ...@@ -734,6 +805,7 @@ static void cscfg_clear_device(void)
list_for_each_entry(cfg_desc, &cscfg_mgr->config_desc_list, item) { list_for_each_entry(cfg_desc, &cscfg_mgr->config_desc_list, item) {
etm_perf_del_symlink_cscfg(cfg_desc); etm_perf_del_symlink_cscfg(cfg_desc);
} }
cscfg_configfs_release(cscfg_mgr);
device_unregister(cscfg_device()); device_unregister(cscfg_device());
mutex_unlock(&cscfg_mutex); mutex_unlock(&cscfg_mutex);
} }
...@@ -747,6 +819,10 @@ int __init cscfg_init(void) ...@@ -747,6 +819,10 @@ int __init cscfg_init(void)
if (err) if (err)
return err; return err;
err = cscfg_configfs_init(cscfg_mgr);
if (err)
goto exit_err;
INIT_LIST_HEAD(&cscfg_mgr->csdev_desc_list); INIT_LIST_HEAD(&cscfg_mgr->csdev_desc_list);
INIT_LIST_HEAD(&cscfg_mgr->feat_desc_list); INIT_LIST_HEAD(&cscfg_mgr->feat_desc_list);
INIT_LIST_HEAD(&cscfg_mgr->config_desc_list); INIT_LIST_HEAD(&cscfg_mgr->config_desc_list);
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#ifndef CORESIGHT_SYSCFG_H #ifndef CORESIGHT_SYSCFG_H
#define CORESIGHT_SYSCFG_H #define CORESIGHT_SYSCFG_H
#include <linux/configfs.h>
#include <linux/coresight.h> #include <linux/coresight.h>
#include <linux/device.h> #include <linux/device.h>
...@@ -25,6 +26,7 @@ ...@@ -25,6 +26,7 @@
* @feat_desc_list: List of feature descriptors to load into registered devices. * @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. * @config_desc_list: List of system configuration descriptors to load into registered devices.
* @sys_active_cnt: Total number of active config descriptor references. * @sys_active_cnt: Total number of active config descriptor references.
* @cfgfs_subsys: configfs subsystem used to manage configurations.
*/ */
struct cscfg_manager { struct cscfg_manager {
struct device dev; struct device dev;
...@@ -32,6 +34,7 @@ struct cscfg_manager { ...@@ -32,6 +34,7 @@ struct cscfg_manager {
struct list_head feat_desc_list; struct list_head feat_desc_list;
struct list_head config_desc_list; struct list_head config_desc_list;
atomic_t sys_active_cnt; atomic_t sys_active_cnt;
struct configfs_subsystem cfgfs_subsys;
}; };
/* get reference to dev in cscfg_manager */ /* get reference to dev in cscfg_manager */
...@@ -57,6 +60,10 @@ struct cscfg_registered_csdev { ...@@ -57,6 +60,10 @@ struct cscfg_registered_csdev {
int __init cscfg_init(void); int __init cscfg_init(void);
void cscfg_exit(void); void cscfg_exit(void);
int cscfg_preload(void); int cscfg_preload(void);
const struct cscfg_feature_desc *cscfg_get_named_feat_desc(const char *name);
int cscfg_update_feat_param_val(struct cscfg_feature_desc *feat_desc,
int param_idx, u64 value);
/* syscfg manager external API */ /* syscfg manager external API */
int cscfg_load_config_sets(struct cscfg_config_desc **cfg_descs, int cscfg_load_config_sets(struct cscfg_config_desc **cfg_descs,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment