All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mathieu Poirier <mathieu.poirier@linaro.org>
To: Mike Leach <mike.leach@linaro.org>
Cc: linux-arm-kernel@lists.infradead.org, coresight@lists.linaro.org,
	suzuki.poulose@arm.com, leo.yan@linaro.org
Subject: Re: [PATCH v2 1/6] coresight: configfs: Add in functionality for load via configfs
Date: Fri, 28 Jan 2022 11:08:52 -0700	[thread overview]
Message-ID: <20220128180852.GA2240873@p14s> (raw)
In-Reply-To: <20211130220100.25888-2-mike.leach@linaro.org>

Good morning Mike,

Please find below (and in upcoming emails) the rest or my comments for this set.

On Tue, Nov 30, 2021 at 10:00:55PM +0000, Mike Leach wrote:
> Add in functionality to allow load via configfs.
> 
> define a binary file format and provide a reader for that format
> that will create and populate configuration and feature structures
> use by the driver infrastructure.
> 
> Signed-off-by: Mike Leach <mike.leach@linaro.org>
> ---
>  drivers/hwtracing/coresight/Makefile          |   2 +-
>  .../coresight/coresight-config-file.c         | 432 ++++++++++++++++++
>  .../coresight/coresight-config-file.h         | 118 +++++
>  .../hwtracing/coresight/coresight-config.h    |  17 +
>  .../hwtracing/coresight/coresight-syscfg.h    |   1 +
>  5 files changed, 569 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/hwtracing/coresight/coresight-config-file.c
>  create mode 100644 drivers/hwtracing/coresight/coresight-config-file.h
> 
> diff --git a/drivers/hwtracing/coresight/Makefile b/drivers/hwtracing/coresight/Makefile
> index b6c4a48140ec..5de2bb79f4ac 100644
> --- a/drivers/hwtracing/coresight/Makefile
> +++ b/drivers/hwtracing/coresight/Makefile
> @@ -6,7 +6,7 @@ obj-$(CONFIG_CORESIGHT) += coresight.o
>  coresight-y := coresight-core.o  coresight-etm-perf.o coresight-platform.o \
>  		coresight-sysfs.o coresight-syscfg.o coresight-config.o \
>  		coresight-cfg-preload.o coresight-cfg-afdo.o \
> -		coresight-syscfg-configfs.o
> +		coresight-syscfg-configfs.o coresight-config-file.o
>  obj-$(CONFIG_CORESIGHT_LINK_AND_SINK_TMC) += coresight-tmc.o
>  coresight-tmc-y := coresight-tmc-core.o coresight-tmc-etf.o \
>  		      coresight-tmc-etr.o
> diff --git a/drivers/hwtracing/coresight/coresight-config-file.c b/drivers/hwtracing/coresight/coresight-config-file.c
> new file mode 100644
> index 000000000000..3fd001938324
> --- /dev/null
> +++ b/drivers/hwtracing/coresight/coresight-config-file.c
> @@ -0,0 +1,432 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2020 Linaro Limited, All rights reserved.
> + * Author: Mike Leach <mike.leach@linaro.org>
> + */
> +
> +#include "coresight-config.h"
> +#include "coresight-config-file.h"
> +#include "coresight-syscfg.h"
> +
> +#define cscfg_extract_u64(val64) {	\
> +	val64 = *(u64 *)(buffer + used); \
> +	used += sizeof(u64); \
> +	}
> +
> +#define cscfg_extract_u32(val32) { \
> +	val32 = *(u32 *)(buffer + used); \
> +	used += sizeof(u32); \
> +	}
> +
> +#define cscfg_extract_u16(val16) { \
> +	val16 = *(u16 *)(buffer + used); \
> +	used += sizeof(u16); \
> +	}
> +
> +#define cscfg_extract_u8(val8) {	\
> +	val8 = *(buffer + used); \
> +	used++; \
> +	}
> +
> +static int cscfg_file_read_hdr(const u8 *buffer, const int buflen, int *buf_used,
> +			       struct cscfg_file_header *hdr)
> +{
> +	/* file header always at the start of the buffer */
> +	int used = 0;
> +
> +	if (buflen < sizeof(struct cscfg_file_header))
> +		return -EINVAL;
> +
> +	cscfg_extract_u32(hdr->magic_version);
> +	if (hdr->magic_version != CSCFG_FILE_MAGIC_VERSION)
> +		return -EINVAL;
> +
> +	cscfg_extract_u16(hdr->length);
> +	if (hdr->length > buflen)
> +		return -EINVAL;
> +
> +	cscfg_extract_u16(hdr->nr_features);
> +
> +	*buf_used = used;
> +	return 0;
> +}
> +
> +static int cscfg_file_read_elem_hdr(const u8 *buffer, const int buflen, int *buf_used,
> +				    struct cscfg_file_elem_header *elem_hdr)
> +{
> +	int used = *buf_used;
> +
> +	if ((buflen - used) < (sizeof(u16) + sizeof(u8)))
> +		return -EINVAL;
> +
> +	/* read length and check enough buffer remains for this element */
> +	elem_hdr->elem_length = *(u16 *)(buffer + used);
> +	if ((buflen - used) < elem_hdr->elem_length)
> +		return -EINVAL;
> +	/* don't use extract fn as we update used _after_ the comparison */
> +	used += sizeof(u16);
> +
> +	/* read type and validate */
> +	cscfg_extract_u8(elem_hdr->elem_type);
> +	if ((elem_hdr->elem_type < CSCFG_FILE_ELEM_TYPE_FEAT) ||
> +	    (elem_hdr->elem_type > CSCFG_FILE_ELEM_TYPE_CFG))
> +		return -EINVAL;
> +
> +	*buf_used = used;
> +	return 0;
> +}
> +
> +static int cscfg_file_read_elem_str(const u8 *buffer, const int buflen, int *buf_used,
> +				    struct cscfg_file_elem_str *elem_str)
> +{
> +	int used = *buf_used;
> +
> +	if ((buflen - used) < sizeof(u16))
> +		return -EINVAL;
> +
> +	cscfg_extract_u16(elem_str->str_len);
> +
> +	if ((buflen - used) < elem_str->str_len)
> +		return -EINVAL;
> +
> +	/* check for 0 termination */
> +	if (buffer[elem_str->str_len - 1] != 0)
> +		return -EINVAL;
> +
> +	elem_str->str = devm_kstrdup(cscfg_device(), (char *)buffer, GFP_KERNEL);
> +	used += elem_str->str_len;
> +
> +	*buf_used = used;
> +	return 0;
> +}
> +
> +static int cscfg_file_alloc_desc_arrays(struct cscfg_fs_load_descs *desc_arrays,
> +					int nr_features)
> +{
> +	/* arrays are 0 terminated - max of 1 config & nr_features features */
> +	desc_arrays->config_descs = devm_kcalloc(cscfg_device(), 2,
> +						 sizeof(struct cscfg_config_desc *),
> +						 GFP_KERNEL);
> +	if (!desc_arrays->config_descs)
> +		return -ENOMEM;
> +	desc_arrays->feat_descs = devm_kcalloc(cscfg_device(), nr_features + 1,
> +					       sizeof(struct cscfg_feature_desc *),
> +					       GFP_KERNEL);
> +	if (!desc_arrays->feat_descs)
> +		return -ENOMEM;
> +	return 0;
> +}
> +
> +static int cscfg_file_read_elem_config(const u8 *buffer, const int buflen, int *buf_used,
> +				       struct cscfg_fs_load_descs *desc_arrays)
> +{
> +	struct cscfg_file_elem_header elem_hdr;
> +	struct cscfg_file_elem_str elem_str;
> +	struct cscfg_config_desc *config_desc;
> +	int used = *buf_used, nr_preset_vals, nr_preset_bytes, i;
> +	int err = 0;
> +	u64 *presets;
> +
> +	/*
> +	 * read the header - if not config, then don't update buf_used
> +	 * pointer on return
> +	 */
> +	err = cscfg_file_read_elem_hdr(buffer, buflen, &used, &elem_hdr);
> +	if (err)
> +		return err;
> +	if (elem_hdr.elem_type != CSCFG_FILE_ELEM_TYPE_CFG)
> +		return 0;
> +
> +	/* we have a config - allocate the descriptor */
> +	config_desc = devm_kzalloc(cscfg_device(), sizeof(struct cscfg_config_desc),
> +				   GFP_KERNEL);
> +	if (!config_desc)
> +		return -ENOMEM;
> +
> +	/* read the name string */
> +	err = cscfg_file_read_elem_str(buffer, buflen, &used, &elem_str);
> +	if (err)
> +		return err;
> +	config_desc->name = elem_str.str;
> +
> +	/* read the description string */
> +	err = cscfg_file_read_elem_str(buffer, buflen, &used, &elem_str);
> +	if (err)
> +		return err;
> +	config_desc->description = elem_str.str;
> +
> +	/* read in some values */
> +	if ((buflen - used) < sizeof(u64))
> +		return -EINVAL;
> +	cscfg_extract_u16(config_desc->nr_presets);
> +	cscfg_extract_u32(config_desc->nr_total_params);
> +	cscfg_extract_u16(config_desc->nr_feat_refs);
> +
> +	/* read the array of 64bit presets if present */
> +	nr_preset_vals = config_desc->nr_total_params * config_desc->nr_presets;
> +	if (nr_preset_vals) {
> +		presets = devm_kcalloc(cscfg_device(), nr_preset_vals,
> +				       sizeof(u64), GFP_KERNEL);
> +		if (!presets)
> +			return -ENOMEM;
> +
> +		nr_preset_bytes = sizeof(u64) * nr_preset_vals;
> +		if ((buflen - used) < nr_preset_bytes)
> +			return -EINVAL;
> +
> +		memcpy(presets, (buffer + used), nr_preset_bytes);
> +		config_desc->presets = presets;
> +		used += nr_preset_bytes;
> +	}
> +
> +	/* read the array of feature names referenced by the config */
> +	if (config_desc->nr_feat_refs) {
> +		config_desc->feat_ref_names = devm_kcalloc(cscfg_device(),
> +							   config_desc->nr_feat_refs,
> +							   sizeof(char *),
> +							   GFP_KERNEL);
> +		if (!config_desc->feat_ref_names)
> +			return -ENOMEM;
> +
> +		for (i = 0; i < config_desc->nr_feat_refs; i++) {
> +			err = cscfg_file_read_elem_str(buffer, buflen, &used, &elem_str);
> +			if (err)
> +				return err;
> +			config_desc->feat_ref_names[i] = elem_str.str;
> +		}
> +	}
> +
> +	desc_arrays->config_descs[0] = config_desc;
> +	*buf_used = used;
> +	return 0;
> +}
> +
> +/* just read the config name - if there is a config at this position */
> +static int cscfg_file_read_elem_config_name(const u8 *buffer, const int buflen, int *buf_used,
> +					    struct cscfg_file_elem_str *elem_str)
> +{
> +	struct cscfg_file_elem_header elem_hdr;
> +	int used = *buf_used;
> +	int err;
> +
> +	elem_str->str_len = 0;
> +	/*
> +	 * read the header - if not config, then don't update buf_used
> +	 * pointer on return
> +	 */
> +	err = cscfg_file_read_elem_hdr(buffer, buflen, &used, &elem_hdr);
> +	if (err)
> +		return err;
> +	if (elem_hdr.elem_type != CSCFG_FILE_ELEM_TYPE_CFG)
> +		return 0;
> +
> +	/* read the name string */
> +	err = cscfg_file_read_elem_str(buffer, buflen, &used, elem_str);
> +	if (err)
> +		return err;
> +	*buf_used = used;
> +
> +	return 0;
> +}
> +
> +static int cscfg_file_read_elem_param(const u8 *buffer, const int buflen, int *buf_used,
> +				      struct cscfg_parameter_desc *param_desc)
> +{
> +	struct cscfg_file_elem_str elem_str;
> +	int err = 0, used = *buf_used;
> +
> +	/* parameter name */
> +	err = cscfg_file_read_elem_str(buffer, buflen, &used, &elem_str);
> +	if (err)
> +		return err;
> +	param_desc->name = elem_str.str;
> +
> +	/* parameter value */
> +	if ((buflen - used) < sizeof(u64))
> +		return -EINVAL;
> +	cscfg_extract_u64(param_desc->value);
> +
> +	*buf_used = used;
> +	return err;
> +}
> +
> +static int cscfg_file_read_elem_feature(const u8 *buffer, const int buflen, int *buf_used,
> +					struct cscfg_fs_load_descs *desc_arrays,
> +					const int feat_idx)
> +{
> +	struct cscfg_file_elem_header elem_hdr;
> +	struct cscfg_file_elem_str elem_str;
> +	struct cscfg_feature_desc *feat_desc;
> +	struct cscfg_regval_desc *p_reg_desc;
> +	int used = *buf_used, err, i, nr_regs_bytes;
> +	u32 val32;
> +
> +	/* allocate the feature descriptor object */
> +	feat_desc = devm_kzalloc(cscfg_device(), sizeof(struct cscfg_feature_desc),
> +				 GFP_KERNEL);
> +	if (!feat_desc)
> +		return -ENOMEM;
> +
> +	/* read and check the element header */
> +	err = cscfg_file_read_elem_hdr(buffer, buflen, &used, &elem_hdr);
> +	if (err)
> +		return err;
> +
> +	if (elem_hdr.elem_type != CSCFG_FILE_ELEM_TYPE_FEAT)
> +		return -EINVAL;
> +
> +	/* read the feature name */
> +	err = cscfg_file_read_elem_str(buffer, buflen, &used, &elem_str);
> +	if (err)
> +		return err;
> +	feat_desc->name = elem_str.str;
> +
> +	/* read the description string */
> +	err = cscfg_file_read_elem_str(buffer, buflen, &used, &elem_str);
> +	if (err)
> +		return err;
> +	feat_desc->description = elem_str.str;
> +
> +	/*
> +	 * read in some values
> +	 * [u32 value: match_flags]
> +	 * [u16 value: nr_regs]	    - number of registers.
> +	 * [u16 value: nr_params]   - number of parameters.
> +	 */
> +	cscfg_extract_u32(feat_desc->match_flags);
> +	cscfg_extract_u16(feat_desc->nr_regs);
> +	cscfg_extract_u16(feat_desc->nr_params);
> +
> +	/* register descriptors  - 32 bit + 64 bit value */
> +	if (feat_desc->nr_regs) {
> +		nr_regs_bytes = ((sizeof(u32) + sizeof(u64)) * feat_desc->nr_regs);
> +		if ((buflen - used) < nr_regs_bytes)
> +			return -EINVAL;
> +		feat_desc->regs_desc = devm_kcalloc(cscfg_device(),
> +						    feat_desc->nr_regs,
> +						    sizeof(struct cscfg_regval_desc),
> +						    GFP_KERNEL);
> +		if (!feat_desc->regs_desc)
> +			return -ENOMEM;
> +
> +		for (i = 0; i < feat_desc->nr_regs; i++) {
> +			cscfg_extract_u32(val32);
> +			p_reg_desc = (struct cscfg_regval_desc *)&feat_desc->regs_desc[i];
> +			CSCFG_FILE_U32_TO_REG_DESC_INFO(val32, p_reg_desc);
> +			cscfg_extract_u64(feat_desc->regs_desc[i].val64);
> +		}
> +	}
> +
> +	/* parameter descriptors - string + 64 bit value */
> +	if (feat_desc->nr_params) {
> +		feat_desc->params_desc = devm_kcalloc(cscfg_device(),
> +						      feat_desc->nr_params,
> +						      sizeof(struct cscfg_parameter_desc),
> +						      GFP_KERNEL);
> +		if (!feat_desc->params_desc)
> +			return -ENOMEM;
> +		for (i = 0; i < feat_desc->nr_params; i++) {
> +			err = cscfg_file_read_elem_param(buffer, buflen, &used,
> +							 &feat_desc->params_desc[i]);
> +			if (err)
> +				return err;
> +		}
> +	}
> +
> +	desc_arrays->feat_descs[feat_idx] = feat_desc;
> +	*buf_used = used;
> +	return 0;
> +}
> +
> +/* just read the feature name - if there is a feature at this position */
> +static int cscfg_file_read_elem_feat_name(const u8 *buffer, const int buflen, int *buf_used,
> +					  struct cscfg_file_elem_str *elem_str)
> +{
> +	struct cscfg_file_elem_header elem_hdr;
> +	int used = *buf_used;
> +	int err;
> +
> +	elem_str->str_len = 0;
> +	/*
> +	 * read the header - if not config, then don't update buf_used
> +	 * pointer on return
> +	 */
> +	err = cscfg_file_read_elem_hdr(buffer, buflen, &used, &elem_hdr);
> +	if (err)
> +		return err;
> +	if (elem_hdr.elem_type != CSCFG_FILE_ELEM_TYPE_FEAT)
> +		return -EINVAL;
> +
> +	/* read the feature name */
> +	err = cscfg_file_read_elem_str(buffer, buflen, &used, elem_str);
> +	if (err)
> +		return err;
> +	*buf_used = used;
> +
> +	return 0;
> +}
> +
> +/*
> + * Read a buffer and create the configuration and feature
> + * descriptors to load into the cscfg system
> + */
> +int cscfg_file_read_buffer(const u8 *buffer, const int buflen,
> +			   struct cscfg_fs_load_descs *desc_arrays)
> +{
> +	struct cscfg_file_header hdr;
> +	int used = 0, err, i;
> +
> +	/* read in the file header */
> +	err = cscfg_file_read_hdr(buffer, buflen, &used, &hdr);
> +	if (err)
> +		return err;
> +
> +	/* allocate the memory for the descriptor pointer arrays */
> +	err = cscfg_file_alloc_desc_arrays(desc_arrays, hdr.nr_features);
> +	if (err)
> +		return err;
> +
> +	/* read elements */
> +
> +	/* first element could be a config so check */
> +	err = cscfg_file_read_elem_config(buffer, buflen, &used, desc_arrays);
> +	if (err)
> +		return err;
> +
> +	/* now read and populate all the feature descriptors */
> +	for (i = 0; i < hdr.nr_features; i++) {
> +		err = cscfg_file_read_elem_feature(buffer, buflen, &used, desc_arrays, i);
> +		if (err)
> +			return err;
> +	}
> +	return used;
> +}
> +
> +int cscfg_file_read_buffer_first_name(const u8 *buffer, const int buflen,
> +				      const char **name)
> +{
> +	struct cscfg_file_header hdr;
> +	struct cscfg_file_elem_str elem_str;
> +	int used = 0, err = 0;
> +
> +	*name = NULL;
> +
> +	/* read in the file header */
> +	err = cscfg_file_read_hdr(buffer, buflen, &used, &hdr);
> +	if (err)
> +		return err;
> +
> +	err = cscfg_file_read_elem_config_name(buffer, buflen, &used, &elem_str);
> +	if (err)
> +		return err;
> +
> +	/* no config string - get first feature name */
> +	if (!elem_str.str_len) {
> +		err = cscfg_file_read_elem_feat_name(buffer, buflen, &used, &elem_str);
> +		if (err)
> +			return err;
> +	}
> +	if (elem_str.str_len)
> +		*name = elem_str.str;
> +	return err;
> +}

I haven't found a problem or a bug in the above.

> diff --git a/drivers/hwtracing/coresight/coresight-config-file.h b/drivers/hwtracing/coresight/coresight-config-file.h
> new file mode 100644
> index 000000000000..6c8c5af0a614
> --- /dev/null
> +++ b/drivers/hwtracing/coresight/coresight-config-file.h
> @@ -0,0 +1,118 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (c) 2020 Linaro Limited, All rights reserved.
> + * Author: Mike Leach <mike.leach@linaro.org>
> + */
> +
> +#ifndef _CORESIGHT_CORESIGHT_CONFIG_FILE_H
> +#define _CORESIGHT_CORESIGHT_CONFIG_FILE_H
> +
> +/*
> + * Structures to represent configuration descriptors in a memory buffer
> + * to serialise to and from files
> + *
> + * File structure - for loading a configuration + features
> + * from configfs.
> + *
> + * [cscfg_file_header]	- mandatory
> + * [CONFIG_ELEM]	- optional - only one permitted,
> + * [FEATURE_ELEM] * [cscfg_file_header.nr_features]
> + *			- optional - file valid with config only.
> + *
> + * Invalid file if no config or features.
> + *
> + *
> + * File structure for [CONFIG_ELEM]:
> + *
> + * [cscfg_file_elem_header] - header length value to end of feature strings.
> + * [cscfg_file_elem_str]    - name of the configuration
> + * [cscfg_file_elem_str]    - description of configuration
> + * [u16 value - nr_presets]
> + * [u32 value - nr_total_params]
> + * [u16 value - nr_feat_refs]
> + * [u64 values] * (nr_presets * nr_total_params)
> + * [cscfg_file_elem_str] * nr_feat_refs
> + *
> + * Only one configuration per file.
> + *
> + * File structure for a [FEATURE_ELEM]
> + *
> + * [cscfg_file_elem_header] - header length is total bytes to end of param structures.
> + * [cscfg_file_elem_str]    - feature name.
> + * [cscfg_file_elem_str]    - feature description.
> + * [u32 value: match_flags]
> + * [u16 value: nr_regs]	    - number of registers.
> + * [u16 value: nr_params]   - number of parameters.
> + * [cscfg_regval_desc struct] * nr_regs
> + * [PARAM_ELEM] * nr_params
> + *
> + * File structure for [PARAM_ELEM]
> + *
> + * [cscfg_file_elem_str]    - parameter name.
> + * [u64 value: param_value] - initial value.
> + */
> +

The above is really really dry, even for someone that is acquainted with the CS
subsystem and the complex configuration feature.  I doubt someone looking to
start with the subsystem will be able to understand what is going on.  

> +/* major element types - configurations and features */
> +
> +#define CSCFG_FILE_ELEM_TYPE_FEAT	0x1
> +#define CSCFG_FILE_ELEM_TYPE_CFG	0x2
> +
> +#define CSCFG_FILE_MAGIC_VERSION	0xC5CF0001

I like that magic number.

> +
> +#define CSCFG_FILE_U32_TO_REG_DESC_INFO(val32, p_desc) \
> +	{ \
> +	p_desc->type = (val32 >> 24) & 0xFF; \
> +	p_desc->offset = (val32 >> 12) & 0xFFF; \
> +	p_desc->hw_info = val32 & 0xFFF; \
> +	}
> +
> +#define CSCFG_FILE_REG_DESC_INFO_TO_U32(val32, p_desc) \
> +	{ \
> +	val32 = p_desc->hw_info & 0xFFF; \
> +	val32 |= ((p_desc->offset & 0xFFF) << 12); \
> +	val32 |= ((p_desc->type & 0xFF) << 24); \
> +	}
> +
> +/* binary attributes in configfs need a max size - declare a value for this. */
> +#define CSCFG_FILE_MAXSIZE	16384
> +
> +/* limit string sizes */
> +#define CSCFG_FILE_STR_MAXSIZE	1024
> +
> +

Extra newline.

> +/**
> + * file header.
> + *
> + * @magic_version: magic number / version for file/buffer format.
> + * @length       : total length of all data in the buffer.
> + * @nr_features  : total number of features in the buffer.
> + */
> +struct cscfg_file_header {
> +	u32 magic_version;
> +	u16 length;
> +	u16 nr_features;
> +};
> +
> +/**
> + * element header
> + *
> + * @elem_length: total length of this element
> + * @elem_type  : type of this element - one of CSCFG_FILE_ELEM_TYPE.. defines.
> + */
> +struct cscfg_file_elem_header {
> +	u16 elem_length;
> +	u8 elem_type;
> +};
> +
> +/**
> + * string file element.
> + *
> + * @str_len: length of string buffer including 0 terminator
> + * @str    : string buffer - 0 terminated.
> + */
> +struct cscfg_file_elem_str {
> +	u16 str_len;
> +	char *str;
> +};
> +
> +#endif /* _CORESIGHT_CORESIGHT_CONFIG_FILE_H */
> diff --git a/drivers/hwtracing/coresight/coresight-config.h b/drivers/hwtracing/coresight/coresight-config.h
> index 9bd44b940add..770986316bc2 100644
> --- a/drivers/hwtracing/coresight/coresight-config.h
> +++ b/drivers/hwtracing/coresight/coresight-config.h
> @@ -150,6 +150,23 @@ struct cscfg_config_desc {
>  	struct config_group *fs_group;
>  };
>  
> +/**
> + * Dynamically loaded descriptor arrays loaded via configfs.
> + *
> + * For builtin or module loaded configurations / features these are
> + * statically defined at compile time. For configfs we create the arrays
> + * dynamically so need a structure to handle this.
> + *
> + * @owner_info:		associated owner info struct to add to load order list.
> + * @config_descs:	array of config descriptor pointers.
> + * @feat_descs:		array of feature descriptor pointers.
> + */
> +struct cscfg_fs_load_descs {
> +	void *owner_info;
> +	struct cscfg_config_desc **config_descs;
> +	struct cscfg_feature_desc **feat_descs;
> +};
> +
>  /**
>   * config register instance - part of a loaded feature.
>   *                            maps register values to csdev driver structures
> diff --git a/drivers/hwtracing/coresight/coresight-syscfg.h b/drivers/hwtracing/coresight/coresight-syscfg.h
> index 9106ffab4833..6a6e33585be9 100644
> --- a/drivers/hwtracing/coresight/coresight-syscfg.h
> +++ b/drivers/hwtracing/coresight/coresight-syscfg.h
> @@ -66,6 +66,7 @@ struct cscfg_registered_csdev {
>  enum cscfg_load_owner_type {
>  	CSCFG_OWNER_PRELOAD,
>  	CSCFG_OWNER_MODULE,
> +	CSCFG_OWNER_CONFIGFS,

Other than the above comments this patch works.

>  };
>  
>  /**
> -- 
> 2.17.1
> 

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  reply	other threads:[~2022-01-28 18:10 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-11-30 22:00 [PATCH v2 0/6] coresight: syscfg: Extend configfs for config load Mike Leach
2021-11-30 22:00 ` [PATCH v2 1/6] coresight: configfs: Add in functionality for load via configfs Mike Leach
2022-01-28 18:08   ` Mathieu Poirier [this message]
2022-02-02 20:40     ` Mike Leach
2021-11-30 22:00 ` [PATCH v2 2/6] coresight: configfs: Add in binary attributes to load files Mike Leach
2022-01-28 18:17   ` Mathieu Poirier
2022-02-02 20:33     ` Mike Leach
2022-02-02 22:33       ` Mathieu Poirier
2021-11-30 22:00 ` [PATCH v2 3/6] coresight: configfs: Modify config files to allow userspace use Mike Leach
2022-01-28 18:33   ` Mathieu Poirier
2022-02-02 20:48     ` Mike Leach
2021-11-30 22:00 ` [PATCH v2 4/6] coresight: samples: Add an example config writer for configfs load Mike Leach
2022-01-13 17:56   ` Mathieu Poirier
2022-01-18 16:38     ` Mike Leach
2022-01-28 18:43   ` Mathieu Poirier
2022-02-02 20:54     ` Mike Leach
2021-11-30 22:00 ` [PATCH v2 5/6] coresight: samples: Add coresight file reader sample program Mike Leach
2021-11-30 22:01 ` [PATCH v2 6/6] Documentation: coresight: docs for config load via configfs Mike Leach
2022-01-12 17:22   ` Mathieu Poirier
2022-01-12 18:43     ` Mathieu Poirier
2022-01-13 18:15   ` Mathieu Poirier
2022-01-18 16:41     ` Mike Leach
2022-01-10 18:58 ` [PATCH v2 0/6] coresight: syscfg: Extend configfs for config load Mathieu Poirier

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220128180852.GA2240873@p14s \
    --to=mathieu.poirier@linaro.org \
    --cc=coresight@lists.linaro.org \
    --cc=leo.yan@linaro.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=mike.leach@linaro.org \
    --cc=suzuki.poulose@arm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.