// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (c) 2020 Linaro Limited, All rights reserved.
 * Author: Mike Leach <mike.leach@linaro.org>
 */

#include <linux/platform_device.h>
#include <linux/slab.h>

#include "coresight-config.h"
#include "coresight-etm-perf.h"
#include "coresight-syscfg.h"
#include "coresight-syscfg-configfs.h"

/*
 * cscfg_ API manages configurations and features for the entire coresight
 * infrastructure.
 *
 * It allows the loading of configurations and features, and loads these into
 * coresight devices as appropriate.
 */

/* protect the cscsg_data and device */
static DEFINE_MUTEX(cscfg_mutex);

/* only one of these */
static struct cscfg_manager *cscfg_mgr;

/* load features and configuations into the lists */

/* get name feature instance from a coresight device list of features */
static struct cscfg_feature_csdev *
cscfg_get_feat_csdev(struct coresight_device *csdev, const char *name)
{
	struct cscfg_feature_csdev *feat_csdev = NULL;

	list_for_each_entry(feat_csdev, &csdev->feature_csdev_list, node) {
		if (strcmp(feat_csdev->feat_desc->name, name) == 0)
			return feat_csdev;
	}
	return NULL;
}

/* allocate the device config instance - with max number of used features */
static struct cscfg_config_csdev *
cscfg_alloc_csdev_cfg(struct coresight_device *csdev, int nr_feats)
{
	struct cscfg_config_csdev *config_csdev = NULL;
	struct device *dev = csdev->dev.parent;

	/* this is being allocated using the devm for the coresight device */
	config_csdev = devm_kzalloc(dev,
				    offsetof(struct cscfg_config_csdev, feats_csdev[nr_feats]),
				    GFP_KERNEL);
	if (!config_csdev)
		return NULL;

	config_csdev->csdev = csdev;
	return config_csdev;
}

/* Load a config into a device if there are any feature matches between config and device */
static int cscfg_add_csdev_cfg(struct coresight_device *csdev,
			       struct cscfg_config_desc *config_desc)
{
	struct cscfg_config_csdev *config_csdev = NULL;
	struct cscfg_feature_csdev *feat_csdev;
	unsigned long flags;
	int i;

	/* look at each required feature and see if it matches any feature on the device */
	for (i = 0; i < config_desc->nr_feat_refs; i++) {
		/* look for a matching name */
		feat_csdev = cscfg_get_feat_csdev(csdev, config_desc->feat_ref_names[i]);
		if (feat_csdev) {
			/*
			 * At least one feature on this device matches the config
			 * add a config instance to the device and a reference to the feature.
			 */
			if (!config_csdev) {
				config_csdev = cscfg_alloc_csdev_cfg(csdev,
								     config_desc->nr_feat_refs);
				if (!config_csdev)
					return -ENOMEM;
				config_csdev->config_desc = config_desc;
			}
			config_csdev->feats_csdev[config_csdev->nr_feat++] = feat_csdev;
		}
	}
	/* if matched features, add config to device.*/
	if (config_csdev) {
		spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
		list_add(&config_csdev->node, &csdev->config_csdev_list);
		spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
	}

	return 0;
}

/*
 * Add the config to the set of registered devices - call with mutex locked.
 * Iterates through devices - any device that matches one or more of the
 * configuration features will load it, the others will ignore it.
 */
static int cscfg_add_cfg_to_csdevs(struct cscfg_config_desc *config_desc)
{
	struct cscfg_registered_csdev *csdev_item;
	int err;

	list_for_each_entry(csdev_item, &cscfg_mgr->csdev_desc_list, item) {
		err = cscfg_add_csdev_cfg(csdev_item->csdev, config_desc);
		if (err)
			return err;
	}
	return 0;
}

/*
 * Allocate a feature object for load into a csdev.
 * memory allocated using the csdev->dev object using devm managed allocator.
 */
static struct cscfg_feature_csdev *
cscfg_alloc_csdev_feat(struct coresight_device *csdev, struct cscfg_feature_desc *feat_desc)
{
	struct cscfg_feature_csdev *feat_csdev = NULL;
	struct device *dev = csdev->dev.parent;
	int i;

	feat_csdev = devm_kzalloc(dev, sizeof(struct cscfg_feature_csdev), GFP_KERNEL);
	if (!feat_csdev)
		return NULL;

	/* parameters are optional - could be 0 */
	feat_csdev->nr_params = feat_desc->nr_params;

	/*
	 * if we need parameters, zero alloc the space here, the load routine in
	 * the csdev device driver will fill out some information according to
	 * feature descriptor.
	 */
	if (feat_csdev->nr_params) {
		feat_csdev->params_csdev = devm_kcalloc(dev, feat_csdev->nr_params,
							sizeof(struct cscfg_parameter_csdev),
							GFP_KERNEL);
		if (!feat_csdev->params_csdev)
			return NULL;

		/*
		 * fill in the feature reference in the param - other fields
		 * handled by loader in csdev.
		 */
		for (i = 0; i < feat_csdev->nr_params; i++)
			feat_csdev->params_csdev[i].feat_csdev = feat_csdev;
	}

	/*
	 * Always have registers to program - again the load routine in csdev device
	 * will fill out according to feature descriptor and device requirements.
	 */
	feat_csdev->nr_regs = feat_desc->nr_regs;
	feat_csdev->regs_csdev = devm_kcalloc(dev, feat_csdev->nr_regs,
					      sizeof(struct cscfg_regval_csdev),
					      GFP_KERNEL);
	if (!feat_csdev->regs_csdev)
		return NULL;

	/* load the feature default values */
	feat_csdev->feat_desc = feat_desc;
	feat_csdev->csdev = csdev;

	return feat_csdev;
}

/* load one feature into one coresight device */
static int cscfg_load_feat_csdev(struct coresight_device *csdev,
				 struct cscfg_feature_desc *feat_desc,
				 struct cscfg_csdev_feat_ops *ops)
{
	struct cscfg_feature_csdev *feat_csdev;
	unsigned long flags;
	int err;

	if (!ops->load_feat)
		return -EINVAL;

	feat_csdev = cscfg_alloc_csdev_feat(csdev, feat_desc);
	if (!feat_csdev)
		return -ENOMEM;

	/* load the feature into the device */
	err = ops->load_feat(csdev, feat_csdev);
	if (err)
		return err;

	/* add to internal csdev feature list & initialise using reset call */
	cscfg_reset_feat(feat_csdev);
	spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
	list_add(&feat_csdev->node, &csdev->feature_csdev_list);
	spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);

	return 0;
}

/*
 * Add feature to any matching devices - call with mutex locked.
 * Iterates through devices - any device that matches the feature will be
 * called to load it.
 */
static int cscfg_add_feat_to_csdevs(struct cscfg_feature_desc *feat_desc)
{
	struct cscfg_registered_csdev *csdev_item;
	int err;

	list_for_each_entry(csdev_item, &cscfg_mgr->csdev_desc_list, item) {
		if (csdev_item->match_flags & feat_desc->match_flags) {
			err = cscfg_load_feat_csdev(csdev_item->csdev, feat_desc, &csdev_item->ops);
			if (err)
				return err;
		}
	}
	return 0;
}

/* check feature list for a named feature - call with mutex locked. */
static bool cscfg_match_list_feat(const char *name)
{
	struct cscfg_feature_desc *feat_desc;

	list_for_each_entry(feat_desc, &cscfg_mgr->feat_desc_list, item) {
		if (strcmp(feat_desc->name, name) == 0)
			return true;
	}
	return false;
}

/* check all feat needed for cfg are in the list - call with mutex locked. */
static int cscfg_check_feat_for_cfg(struct cscfg_config_desc *config_desc)
{
	int i;

	for (i = 0; i < config_desc->nr_feat_refs; i++)
		if (!cscfg_match_list_feat(config_desc->feat_ref_names[i]))
			return -EINVAL;
	return 0;
}

/*
 * load feature - add to feature list.
 */
static int cscfg_load_feat(struct cscfg_feature_desc *feat_desc)
{
	int err;
	struct cscfg_feature_desc *feat_desc_exist;

	/* new feature must have unique name */
	list_for_each_entry(feat_desc_exist, &cscfg_mgr->feat_desc_list, item) {
		if (!strcmp(feat_desc_exist->name, feat_desc->name))
			return -EEXIST;
	}

	/* add feature to any matching registered devices */
	err = cscfg_add_feat_to_csdevs(feat_desc);
	if (err)
		return err;

	list_add(&feat_desc->item, &cscfg_mgr->feat_desc_list);
	return 0;
}

/*
 * load config into the system - validate used features exist then add to
 * config list.
 */
static int cscfg_load_config(struct cscfg_config_desc *config_desc)
{
	int err;
	struct cscfg_config_desc *config_desc_exist;

	/* new configuration must have a unique name */
	list_for_each_entry(config_desc_exist, &cscfg_mgr->config_desc_list, item) {
		if (!strcmp(config_desc_exist->name, config_desc->name))
			return -EEXIST;
	}

	/* validate features are present */
	err = cscfg_check_feat_for_cfg(config_desc);
	if (err)
		return err;

	/* add config to any matching registered device */
	err = cscfg_add_cfg_to_csdevs(config_desc);
	if (err)
		return err;

	/* add config to perf fs to allow selection */
	err = etm_perf_add_symlink_cscfg(cscfg_device(), config_desc);
	if (err)
		return err;

	list_add(&config_desc->item, &cscfg_mgr->config_desc_list);
	atomic_set(&config_desc->active_cnt, 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;
}

/*
 * Conditionally up reference count on owner to prevent unload.
 *
 * module loaded configs need to be locked in to prevent premature unload.
 */
static int cscfg_owner_get(struct cscfg_load_owner_info *owner_info)
{
	if ((owner_info->type == CSCFG_OWNER_MODULE) &&
	    (!try_module_get(owner_info->owner_handle)))
		return -EINVAL;
	return 0;
}

/* conditionally lower ref count on an owner */
static void cscfg_owner_put(struct cscfg_load_owner_info *owner_info)
{
	if (owner_info->type == CSCFG_OWNER_MODULE)
		module_put(owner_info->owner_handle);
}

static void cscfg_remove_owned_csdev_configs(struct coresight_device *csdev, void *load_owner)
{
	struct cscfg_config_csdev *config_csdev, *tmp;

	if (list_empty(&csdev->config_csdev_list))
		return;

	list_for_each_entry_safe(config_csdev, tmp, &csdev->config_csdev_list, node) {
		if (config_csdev->config_desc->load_owner == load_owner)
			list_del(&config_csdev->node);
	}
}

static void cscfg_remove_owned_csdev_features(struct coresight_device *csdev, void *load_owner)
{
	struct cscfg_feature_csdev *feat_csdev, *tmp;

	if (list_empty(&csdev->feature_csdev_list))
		return;

	list_for_each_entry_safe(feat_csdev, tmp, &csdev->feature_csdev_list, node) {
		if (feat_csdev->feat_desc->load_owner == load_owner)
			list_del(&feat_csdev->node);
	}
}

/*
 * Unregister all configuration and features from configfs owned by load_owner.
 * Although this is called without the list mutex being held, it is in the
 * context of an unload operation which are strictly serialised,
 * so the lists cannot change during this call.
 */
static void cscfg_fs_unregister_cfgs_feats(void *load_owner)
{
	struct cscfg_config_desc *config_desc;
	struct cscfg_feature_desc *feat_desc;

	list_for_each_entry(config_desc, &cscfg_mgr->config_desc_list, item) {
		if (config_desc->load_owner == load_owner)
			cscfg_configfs_del_config(config_desc);
	}
	list_for_each_entry(feat_desc, &cscfg_mgr->feat_desc_list, item) {
		if (feat_desc->load_owner == load_owner)
			cscfg_configfs_del_feature(feat_desc);
	}
}

/*
 * removal is relatively easy - just remove from all lists, anything that
 * matches the owner. Memory for the descriptors will be managed by the owner,
 * memory for the csdev items is devm_ allocated with the individual csdev
 * devices.
 */
static void cscfg_unload_owned_cfgs_feats(void *load_owner)
{
	struct cscfg_config_desc *config_desc, *cfg_tmp;
	struct cscfg_feature_desc *feat_desc, *feat_tmp;
	struct cscfg_registered_csdev *csdev_item;

	lockdep_assert_held(&cscfg_mutex);

	/* remove from each csdev instance feature and config lists */
	list_for_each_entry(csdev_item, &cscfg_mgr->csdev_desc_list, item) {
		/*
		 * for each csdev, check the loaded lists and remove if
		 * referenced descriptor is owned
		 */
		cscfg_remove_owned_csdev_configs(csdev_item->csdev, load_owner);
		cscfg_remove_owned_csdev_features(csdev_item->csdev, load_owner);
	}

	/* remove from the config descriptor lists */
	list_for_each_entry_safe(config_desc, cfg_tmp, &cscfg_mgr->config_desc_list, item) {
		if (config_desc->load_owner == load_owner) {
			etm_perf_del_symlink_cscfg(config_desc);
			list_del(&config_desc->item);
		}
	}

	/* remove from the feature descriptor lists */
	list_for_each_entry_safe(feat_desc, feat_tmp, &cscfg_mgr->feat_desc_list, item) {
		if (feat_desc->load_owner == load_owner) {
			list_del(&feat_desc->item);
		}
	}
}

/*
 * load the features and configs to the lists - called with list mutex held
 */
static int cscfg_load_owned_cfgs_feats(struct cscfg_config_desc **config_descs,
				       struct cscfg_feature_desc **feat_descs,
				       struct cscfg_load_owner_info *owner_info)
{
	int i, err;

	lockdep_assert_held(&cscfg_mutex);

	/* load features first */
	if (feat_descs) {
		for (i = 0; feat_descs[i]; i++) {
			err = cscfg_load_feat(feat_descs[i]);
			if (err) {
				pr_err("coresight-syscfg: Failed to load feature %s\n",
				       feat_descs[i]->name);
				return err;
			}
			feat_descs[i]->load_owner = owner_info;
		}
	}

	/* next any configurations to check feature dependencies */
	if (config_descs) {
		for (i = 0; config_descs[i]; i++) {
			err = cscfg_load_config(config_descs[i]);
			if (err) {
				pr_err("coresight-syscfg: Failed to load configuration %s\n",
				       config_descs[i]->name);
				return err;
			}
			config_descs[i]->load_owner = owner_info;
			config_descs[i]->available = false;
		}
	}
	return 0;
}

/* set configurations as available to activate at the end of the load process */
static void cscfg_set_configs_available(struct cscfg_config_desc **config_descs)
{
	int i;

	lockdep_assert_held(&cscfg_mutex);

	if (config_descs) {
		for (i = 0; config_descs[i]; i++)
			config_descs[i]->available = true;
	}
}

/*
 * Create and register each of the configurations and features with configfs.
 * Called without mutex being held.
 */
static int cscfg_fs_register_cfgs_feats(struct cscfg_config_desc **config_descs,
					struct cscfg_feature_desc **feat_descs)
{
	int i, err;

	if (feat_descs) {
		for (i = 0; feat_descs[i]; i++) {
			err = cscfg_configfs_add_feature(feat_descs[i]);
			if (err)
				return err;
		}
	}
	if (config_descs) {
		for (i = 0; config_descs[i]; i++) {
			err = cscfg_configfs_add_config(config_descs[i]);
			if (err)
				return err;
		}
	}
	return 0;
}

/**
 * cscfg_load_config_sets - API function to load feature and config sets.
 *
 * Take a 0 terminated array of feature descriptors and/or configuration
 * descriptors and load into the system.
 * Features are loaded first to ensure configuration dependencies can be met.
 *
 * To facilitate dynamic loading and unloading, features and configurations
 * have a "load_owner", to allow later unload by the same owner. An owner may
 * be a loadable module or configuration dynamically created via configfs.
 * As later loaded configurations can use earlier loaded features, creating load
 * dependencies, a load order list is maintained. Unload is strictly in the
 * reverse order to load.
 *
 * @config_descs: 0 terminated array of configuration descriptors.
 * @feat_descs:   0 terminated array of feature descriptors.
 * @owner_info:	  Information on the owner of this set.
 */
int cscfg_load_config_sets(struct cscfg_config_desc **config_descs,
			   struct cscfg_feature_desc **feat_descs,
			   struct cscfg_load_owner_info *owner_info)
{
	int err = 0;

	mutex_lock(&cscfg_mutex);
	if (cscfg_mgr->load_state != CSCFG_NONE) {
		mutex_unlock(&cscfg_mutex);
		return -EBUSY;
	}
	cscfg_mgr->load_state = CSCFG_LOAD;

	/* first load and add to the lists */
	err = cscfg_load_owned_cfgs_feats(config_descs, feat_descs, owner_info);
	if (err)
		goto err_clean_load;

	/* add the load owner to the load order list */
	list_add_tail(&owner_info->item, &cscfg_mgr->load_order_list);
	if (!list_is_singular(&cscfg_mgr->load_order_list)) {
		/* lock previous item in load order list */
		err = cscfg_owner_get(list_prev_entry(owner_info, item));
		if (err)
			goto err_clean_owner_list;
	}

	/*
	 * make visible to configfs - configfs manipulation must occur outside
	 * the list mutex lock to avoid circular lockdep issues with configfs
	 * built in mutexes and semaphores. This is safe as it is not possible
	 * to start a new load/unload operation till the current one is done.
	 */
	mutex_unlock(&cscfg_mutex);

	/* create the configfs elements */
	err = cscfg_fs_register_cfgs_feats(config_descs, feat_descs);
	mutex_lock(&cscfg_mutex);

	if (err)
		goto err_clean_cfs;

	/* mark any new configs as available for activation */
	cscfg_set_configs_available(config_descs);
	goto exit_unlock;

err_clean_cfs:
	/* cleanup after error registering with configfs */
	cscfg_fs_unregister_cfgs_feats(owner_info);

	if (!list_is_singular(&cscfg_mgr->load_order_list))
		cscfg_owner_put(list_prev_entry(owner_info, item));

err_clean_owner_list:
	list_del(&owner_info->item);

err_clean_load:
	cscfg_unload_owned_cfgs_feats(owner_info);

exit_unlock:
	cscfg_mgr->load_state = CSCFG_NONE;
	mutex_unlock(&cscfg_mutex);
	return err;
}
EXPORT_SYMBOL_GPL(cscfg_load_config_sets);

/**
 * cscfg_unload_config_sets - unload a set of configurations by owner.
 *
 * Dynamic unload of configuration and feature sets is done on the basis of
 * the load owner of that set. Later loaded configurations can depend on
 * features loaded earlier.
 *
 * Therefore, unload is only possible if:-
 * 1) no configurations are active.
 * 2) the set being unloaded was the last to be loaded to maintain dependencies.
 *
 * Once the unload operation commences, we disallow any configuration being
 * made active until it is complete.
 *
 * @owner_info:	Information on owner for set being unloaded.
 */
int cscfg_unload_config_sets(struct cscfg_load_owner_info *owner_info)
{
	int err = 0;
	struct cscfg_load_owner_info *load_list_item = NULL;

	mutex_lock(&cscfg_mutex);
	if (cscfg_mgr->load_state != CSCFG_NONE) {
		mutex_unlock(&cscfg_mutex);
		return -EBUSY;
	}

	/* unload op in progress also prevents activation of any config */
	cscfg_mgr->load_state = CSCFG_UNLOAD;

	/* cannot unload if anything is active */
	if (atomic_read(&cscfg_mgr->sys_active_cnt)) {
		err = -EBUSY;
		goto exit_unlock;
	}

	/* cannot unload if not last loaded in load order */
	if (!list_empty(&cscfg_mgr->load_order_list)) {
		load_list_item = list_last_entry(&cscfg_mgr->load_order_list,
						 struct cscfg_load_owner_info, item);
		if (load_list_item != owner_info)
			load_list_item = NULL;
	}

	if (!load_list_item) {
		err = -EINVAL;
		goto exit_unlock;
	}

	/* remove from configfs - again outside the scope of the list mutex */
	mutex_unlock(&cscfg_mutex);
	cscfg_fs_unregister_cfgs_feats(owner_info);
	mutex_lock(&cscfg_mutex);

	/* unload everything from lists belonging to load_owner */
	cscfg_unload_owned_cfgs_feats(owner_info);

	/* remove from load order list */
	if (!list_is_singular(&cscfg_mgr->load_order_list)) {
		/* unlock previous item in load order list */
		cscfg_owner_put(list_prev_entry(owner_info, item));
	}
	list_del(&owner_info->item);

exit_unlock:
	cscfg_mgr->load_state = CSCFG_NONE;
	mutex_unlock(&cscfg_mutex);
	return err;
}
EXPORT_SYMBOL_GPL(cscfg_unload_config_sets);

/* Handle coresight device registration and add configs and features to devices */

/* iterate through config lists and load matching configs to device */
static int cscfg_add_cfgs_csdev(struct coresight_device *csdev)
{
	struct cscfg_config_desc *config_desc;
	int err = 0;

	list_for_each_entry(config_desc, &cscfg_mgr->config_desc_list, item) {
		err = cscfg_add_csdev_cfg(csdev, config_desc);
		if (err)
			break;
	}
	return err;
}

/* iterate through feature lists and load matching features to device */
static int cscfg_add_feats_csdev(struct coresight_device *csdev,
				 u32 match_flags,
				 struct cscfg_csdev_feat_ops *ops)
{
	struct cscfg_feature_desc *feat_desc;
	int err = 0;

	if (!ops->load_feat)
		return -EINVAL;

	list_for_each_entry(feat_desc, &cscfg_mgr->feat_desc_list, item) {
		if (feat_desc->match_flags & match_flags) {
			err = cscfg_load_feat_csdev(csdev, feat_desc, ops);
			if (err)
				break;
		}
	}
	return err;
}

/* Add coresight device to list and copy its matching info */
static int cscfg_list_add_csdev(struct coresight_device *csdev,
				u32 match_flags,
				struct cscfg_csdev_feat_ops *ops)
{
	struct cscfg_registered_csdev *csdev_item;

	/* allocate the list entry structure */
	csdev_item = kzalloc(sizeof(struct cscfg_registered_csdev), GFP_KERNEL);
	if (!csdev_item)
		return -ENOMEM;

	csdev_item->csdev = csdev;
	csdev_item->match_flags = match_flags;
	csdev_item->ops.load_feat = ops->load_feat;
	list_add(&csdev_item->item, &cscfg_mgr->csdev_desc_list);

	INIT_LIST_HEAD(&csdev->feature_csdev_list);
	INIT_LIST_HEAD(&csdev->config_csdev_list);
	spin_lock_init(&csdev->cscfg_csdev_lock);

	return 0;
}

/* remove a coresight device from the list and free data */
static void cscfg_list_remove_csdev(struct coresight_device *csdev)
{
	struct cscfg_registered_csdev *csdev_item, *tmp;

	list_for_each_entry_safe(csdev_item, tmp, &cscfg_mgr->csdev_desc_list, item) {
		if (csdev_item->csdev == csdev) {
			list_del(&csdev_item->item);
			kfree(csdev_item);
			break;
		}
	}
}

/**
 * cscfg_register_csdev - register a coresight device with the syscfg manager.
 *
 * Registers the coresight device with the system. @match_flags used to check
 * if the device is a match for registered features. Any currently registered
 * configurations and features that match the device will be loaded onto it.
 *
 * @csdev:		The coresight device to register.
 * @match_flags:	Matching information to load features.
 * @ops:		Standard operations supported by the device.
 */
int cscfg_register_csdev(struct coresight_device *csdev,
			 u32 match_flags,
			 struct cscfg_csdev_feat_ops *ops)
{
	int ret = 0;

	mutex_lock(&cscfg_mutex);

	/* add device to list of registered devices  */
	ret = cscfg_list_add_csdev(csdev, match_flags, ops);
	if (ret)
		goto reg_csdev_unlock;

	/* now load any registered features and configs matching the device. */
	ret = cscfg_add_feats_csdev(csdev, match_flags, ops);
	if (ret) {
		cscfg_list_remove_csdev(csdev);
		goto reg_csdev_unlock;
	}

	ret = cscfg_add_cfgs_csdev(csdev);
	if (ret) {
		cscfg_list_remove_csdev(csdev);
		goto reg_csdev_unlock;
	}

	pr_info("CSCFG registered %s", dev_name(&csdev->dev));

reg_csdev_unlock:
	mutex_unlock(&cscfg_mutex);
	return ret;
}
EXPORT_SYMBOL_GPL(cscfg_register_csdev);

/**
 * cscfg_unregister_csdev - remove coresight device from syscfg manager.
 *
 * @csdev: Device to remove.
 */
void cscfg_unregister_csdev(struct coresight_device *csdev)
{
	mutex_lock(&cscfg_mutex);
	cscfg_list_remove_csdev(csdev);
	mutex_unlock(&cscfg_mutex);
}
EXPORT_SYMBOL_GPL(cscfg_unregister_csdev);

/**
 * cscfg_csdev_reset_feats - reset features for a CoreSight device.
 *
 * Resets all parameters and register values for any features loaded
 * into @csdev to their default values.
 *
 * @csdev: The CoreSight device.
 */
void cscfg_csdev_reset_feats(struct coresight_device *csdev)
{
	struct cscfg_feature_csdev *feat_csdev;
	unsigned long flags;

	spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
	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:
	spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
}
EXPORT_SYMBOL_GPL(cscfg_csdev_reset_feats);

/*
 * This activate configuration for either perf or sysfs. Perf can have multiple
 * active configs, selected per event, sysfs is limited to one.
 *
 * Increments the configuration descriptor active count and the global active
 * count.
 *
 * @cfg_hash: Hash value of the selected configuration name.
 */
static int _cscfg_activate_config(unsigned long cfg_hash)
{
	struct cscfg_config_desc *config_desc;
	int err = -EINVAL;

	if (cscfg_mgr->load_state == CSCFG_UNLOAD)
		return -EBUSY;

	list_for_each_entry(config_desc, &cscfg_mgr->config_desc_list, item) {
		if ((unsigned long)config_desc->event_ea->var == cfg_hash) {
			/* if we happen upon a partly loaded config, can't use it */
			if (config_desc->available == false)
				return -EBUSY;

			/* must ensure that config cannot be unloaded in use */
			err = cscfg_owner_get(config_desc->load_owner);
			if (err)
				break;
			/*
			 * 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;
		}
	}
	return err;
}

static void _cscfg_deactivate_config(unsigned long cfg_hash)
{
	struct cscfg_config_desc *config_desc;

	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);
			cscfg_owner_put(config_desc->load_owner);
			dev_dbg(cscfg_device(), "Deactivate config %s.\n", config_desc->name);
			break;
		}
	}
}

/*
 * called from configfs to set/clear the active configuration for use when
 * using sysfs to control trace.
 */
int cscfg_config_sysfs_activate(struct cscfg_config_desc *config_desc, bool activate)
{
	unsigned long cfg_hash;
	int err = 0;

	mutex_lock(&cscfg_mutex);

	cfg_hash = (unsigned long)config_desc->event_ea->var;

	if (activate) {
		/* cannot be a current active value to activate this */
		if (cscfg_mgr->sysfs_active_config) {
			err = -EBUSY;
			goto exit_unlock;
		}
		err = _cscfg_activate_config(cfg_hash);
		if (!err)
			cscfg_mgr->sysfs_active_config = cfg_hash;
	} else {
		/* disable if matching current value */
		if (cscfg_mgr->sysfs_active_config == cfg_hash) {
			_cscfg_deactivate_config(cfg_hash);
			cscfg_mgr->sysfs_active_config = 0;
		} else
			err = -EINVAL;
	}

exit_unlock:
	mutex_unlock(&cscfg_mutex);
	return err;
}

/* set the sysfs preset value */
void cscfg_config_sysfs_set_preset(int preset)
{
	mutex_lock(&cscfg_mutex);
	cscfg_mgr->sysfs_active_preset = preset;
	mutex_unlock(&cscfg_mutex);
}

/*
 * Used by a device to get the config and preset selected as active in configfs,
 * when using sysfs to control trace.
 */
void cscfg_config_sysfs_get_active_cfg(unsigned long *cfg_hash, int *preset)
{
	mutex_lock(&cscfg_mutex);
	*preset = cscfg_mgr->sysfs_active_preset;
	*cfg_hash = cscfg_mgr->sysfs_active_config;
	mutex_unlock(&cscfg_mutex);
}
EXPORT_SYMBOL_GPL(cscfg_config_sysfs_get_active_cfg);

/**
 * cscfg_activate_config -  Mark a configuration descriptor as active.
 *
 * This will be seen when csdev devices are enabled in the system.
 * Only activated configurations can be enabled on individual devices.
 * Activation protects the configuration from alteration or removal while
 * active.
 *
 * 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)
{
	int err = 0;

	mutex_lock(&cscfg_mutex);
	err = _cscfg_activate_config(cfg_hash);
	mutex_unlock(&cscfg_mutex);

	return err;
}
EXPORT_SYMBOL_GPL(cscfg_activate_config);

/**
 * cscfg_deactivate_config -  Mark a config descriptor as inactive.
 *
 * Decrement the configuration and global active counts.
 *
 * @cfg_hash: Hash value of the selected configuration name.
 */
void cscfg_deactivate_config(unsigned long cfg_hash)
{
	mutex_lock(&cscfg_mutex);
	_cscfg_deactivate_config(cfg_hash);
	mutex_unlock(&cscfg_mutex);
}
EXPORT_SYMBOL_GPL(cscfg_deactivate_config);

/**
 * cscfg_csdev_enable_active_config - Enable matching active configuration for device.
 *
 * Enables the configuration selected by @cfg_hash if the configuration is supported
 * on the device and has been activated.
 *
 * If active and supported the CoreSight device @csdev will be programmed with the
 * configuration, using @preset parameters.
 *
 * Should be called before driver hardware enable for the requested device, prior to
 * programming and enabling the physical hardware.
 *
 * @csdev:	CoreSight device to program.
 * @cfg_hash:	Selector for the configuration.
 * @preset:	Preset parameter values to use, 0 for current / default values.
 */
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;
	unsigned long flags;
	int err = 0;

	/* quickly check global count */
	if (!atomic_read(&cscfg_mgr->sys_active_cnt))
		return 0;

	/*
	 * Look for matching configuration - set the active configuration
	 * context if found.
	 */
	spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
	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;
			csdev->active_cscfg_ctxt = (void *)config_csdev_active;
			break;
		}
	}
	spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);

	/*
	 * If found, attempt to enable
	 */
	if (config_csdev_active) {
		/*
		 * Call the generic routine that will program up the internal
		 * driver structures prior to programming up the hardware.
		 * This routine takes the driver spinlock saved in the configs.
		 */
		err = cscfg_csdev_enable_config(config_csdev_active, preset);
		if (!err) {
			/*
			 * Successful programming. Check the active_cscfg_ctxt
			 * pointer to ensure no pre-emption disabled it via
			 * cscfg_csdev_disable_active_config() before
			 * we could start.
			 *
			 * Set enabled if OK, err if not.
			 */
			spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
			if (csdev->active_cscfg_ctxt)
				config_csdev_active->enabled = true;
			else
				err = -EBUSY;
			spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
		}
	}
	return err;
}
EXPORT_SYMBOL_GPL(cscfg_csdev_enable_active_config);

/**
 * cscfg_csdev_disable_active_config - disable an active config on the device.
 *
 * Disables the active configuration on the CoreSight device @csdev.
 * Disable will save the values of any registers marked in the configurations
 * as save on disable.
 *
 * Should be called after driver hardware disable for the requested device,
 * after disabling the physical hardware and reading back registers.
 *
 * @csdev: The CoreSight device.
 */
void cscfg_csdev_disable_active_config(struct coresight_device *csdev)
{
	struct cscfg_config_csdev *config_csdev;
	unsigned long flags;

	/*
	 * Check if we have an active config, and that it was successfully enabled.
	 * If it was not enabled, we have no work to do, otherwise mark as disabled.
	 * Clear the active config pointer.
	 */
	spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
	config_csdev = (struct cscfg_config_csdev *)csdev->active_cscfg_ctxt;
	if (config_csdev) {
		if (!config_csdev->enabled)
			config_csdev = NULL;
		else
			config_csdev->enabled = false;
	}
	csdev->active_cscfg_ctxt = NULL;
	spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);

	/* true if there was an enabled active config */
	if (config_csdev)
		cscfg_csdev_disable_config(config_csdev);
}
EXPORT_SYMBOL_GPL(cscfg_csdev_disable_active_config);

/* Initialise system configuration management device. */

struct device *cscfg_device(void)
{
	return cscfg_mgr ? &cscfg_mgr->dev : NULL;
}

/* Must have a release function or the kernel will complain on module unload */
static void cscfg_dev_release(struct device *dev)
{
	mutex_lock(&cscfg_mutex);
	kfree(cscfg_mgr);
	cscfg_mgr = NULL;
	mutex_unlock(&cscfg_mutex);
}

/* a device is needed to "own" some kernel elements such as sysfs entries.  */
static int cscfg_create_device(void)
{
	struct device *dev;
	int err = -ENOMEM;

	mutex_lock(&cscfg_mutex);
	if (cscfg_mgr) {
		err = -EINVAL;
		goto create_dev_exit_unlock;
	}

	cscfg_mgr = kzalloc(sizeof(struct cscfg_manager), GFP_KERNEL);
	if (!cscfg_mgr)
		goto create_dev_exit_unlock;

	/* initialise the cscfg_mgr structure */
	INIT_LIST_HEAD(&cscfg_mgr->csdev_desc_list);
	INIT_LIST_HEAD(&cscfg_mgr->feat_desc_list);
	INIT_LIST_HEAD(&cscfg_mgr->config_desc_list);
	INIT_LIST_HEAD(&cscfg_mgr->load_order_list);
	atomic_set(&cscfg_mgr->sys_active_cnt, 0);
	cscfg_mgr->load_state = CSCFG_NONE;

	/* setup the device */
	dev = cscfg_device();
	dev->release = cscfg_dev_release;
	dev->init_name = "cs_system_cfg";

	err = device_register(dev);
	if (err)
		put_device(dev);

create_dev_exit_unlock:
	mutex_unlock(&cscfg_mutex);
	return err;
}

/*
 * Loading and unloading is generally on user discretion.
 * If exiting due to coresight module unload, we need to unload any configurations that remain,
 * before we unregister the configfs intrastructure.
 *
 * Do this by walking the load_owner list and taking appropriate action, depending on the load
 * owner type.
 */
static void cscfg_unload_cfgs_on_exit(void)
{
	struct cscfg_load_owner_info *owner_info = NULL;

	/*
	 * grab the mutex - even though we are exiting, some configfs files
	 * may still be live till we dump them, so ensure list data is
	 * protected from a race condition.
	 */
	mutex_lock(&cscfg_mutex);
	while (!list_empty(&cscfg_mgr->load_order_list)) {

		/* remove in reverse order of loading */
		owner_info = list_last_entry(&cscfg_mgr->load_order_list,
					     struct cscfg_load_owner_info, item);

		/* action according to type */
		switch (owner_info->type) {
		case CSCFG_OWNER_PRELOAD:
			/*
			 * preloaded  descriptors are statically allocated in
			 * this module - just need to unload dynamic items from
			 * csdev lists, and remove from configfs directories.
			 */
			pr_info("cscfg: unloading preloaded configurations\n");
			break;

		case  CSCFG_OWNER_MODULE:
			/*
			 * this is an error - the loadable module must have been unloaded prior
			 * to the coresight module unload. Therefore that module has not
			 * correctly unloaded configs in its own exit code.
			 * Nothing to do other than emit an error string as the static descriptor
			 * references we need to unload will have disappeared with the module.
			 */
			pr_err("cscfg: ERROR: prior module failed to unload configuration\n");
			goto list_remove;
		}

		/* remove from configfs - outside the scope of the list mutex */
		mutex_unlock(&cscfg_mutex);
		cscfg_fs_unregister_cfgs_feats(owner_info);
		mutex_lock(&cscfg_mutex);

		/* Next unload from csdev lists. */
		cscfg_unload_owned_cfgs_feats(owner_info);

list_remove:
		/* remove from load order list */
		list_del(&owner_info->item);
	}
	mutex_unlock(&cscfg_mutex);
}

static void cscfg_clear_device(void)
{
	cscfg_unload_cfgs_on_exit();
	cscfg_configfs_release(cscfg_mgr);
	device_unregister(cscfg_device());
}

/* Initialise system config management API device  */
int __init cscfg_init(void)
{
	int err = 0;

	/* create the device and init cscfg_mgr */
	err = cscfg_create_device();
	if (err)
		return err;

	/* initialise configfs subsystem */
	err = cscfg_configfs_init(cscfg_mgr);
	if (err)
		goto exit_err;

	/* preload built-in configurations */
	err = cscfg_preload(THIS_MODULE);
	if (err)
		goto exit_err;

	dev_info(cscfg_device(), "CoreSight Configuration manager initialised");
	return 0;

exit_err:
	cscfg_clear_device();
	return err;
}

void cscfg_exit(void)
{
	cscfg_clear_device();
}
