// 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;

	/* 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;

	/* 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;
}

/**
 * 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.
 *
 * @config_descs: 0 terminated array of configuration descriptors.
 * @feat_descs:   0 terminated array of feature descriptors.
 */
int cscfg_load_config_sets(struct cscfg_config_desc **config_descs,
			   struct cscfg_feature_desc **feat_descs)
{
	int err, i = 0;

	mutex_lock(&cscfg_mutex);

	/* load features first */
	if (feat_descs) {
		while (feat_descs[i]) {
			err = cscfg_load_feat(feat_descs[i]);
			if (!err)
				err = cscfg_configfs_add_feature(feat_descs[i]);
			if (err) {
				pr_err("coresight-syscfg: Failed to load feature %s\n",
				       feat_descs[i]->name);
				goto exit_unlock;
			}
			i++;
		}
	}

	/* next any configurations to check feature dependencies */
	i = 0;
	if (config_descs) {
		while (config_descs[i]) {
			err = cscfg_load_config(config_descs[i]);
			if (!err)
				err = cscfg_configfs_add_config(config_descs[i]);
			if (err) {
				pr_err("coresight-syscfg: Failed to load configuration %s\n",
				       config_descs[i]->name);
				goto exit_unlock;
			}
			i++;
		}
	}

exit_unlock:
	mutex_unlock(&cscfg_mutex);
	return err;
}
EXPORT_SYMBOL_GPL(cscfg_load_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);

/**
 * 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.
 *
 * Increments the configuration descriptor active count and the global active
 * count.
 *
 * @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);

/**
 * 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)
{
	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);

/**
 * 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)
{
	kfree(cscfg_mgr);
	cscfg_mgr = NULL;
}

/* 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;

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

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

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

static void cscfg_clear_device(void)
{
	struct cscfg_config_desc *cfg_desc;

	mutex_lock(&cscfg_mutex);
	list_for_each_entry(cfg_desc, &cscfg_mgr->config_desc_list, item) {
		etm_perf_del_symlink_cscfg(cfg_desc);
	}
	cscfg_configfs_release(cscfg_mgr);
	device_unregister(cscfg_device());
	mutex_unlock(&cscfg_mutex);
}

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

	err = cscfg_create_device();
	if (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->feat_desc_list);
	INIT_LIST_HEAD(&cscfg_mgr->config_desc_list);
	atomic_set(&cscfg_mgr->sys_active_cnt, 0);

	/* preload built-in configurations */
	err = cscfg_preload();
	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();
}
