1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (c) 2020 Linaro Limited, All rights reserved.
4 * Author: Mike Leach <mike.leach@linaro.org>
5 */
6
7#include <linux/platform_device.h>
8#include <linux/slab.h>
9
10#include "coresight-config.h"
11#include "coresight-etm-perf.h"
12#include "coresight-syscfg.h"
13#include "coresight-syscfg-configfs.h"
14
15/*
16 * cscfg_ API manages configurations and features for the entire coresight
17 * infrastructure.
18 *
19 * It allows the loading of configurations and features, and loads these into
20 * coresight devices as appropriate.
21 */
22
23/* protect the cscsg_data and device */
24static DEFINE_MUTEX(cscfg_mutex);
25
26/* only one of these */
27static struct cscfg_manager *cscfg_mgr;
28
29/* load features and configuations into the lists */
30
31/* get name feature instance from a coresight device list of features */
32static struct cscfg_feature_csdev *
33cscfg_get_feat_csdev(struct coresight_device *csdev, const char *name)
34{
35	struct cscfg_feature_csdev *feat_csdev = NULL;
36
37	list_for_each_entry(feat_csdev, &csdev->feature_csdev_list, node) {
38		if (strcmp(feat_csdev->feat_desc->name, name) == 0)
39			return feat_csdev;
40	}
41	return NULL;
42}
43
44/* allocate the device config instance - with max number of used features */
45static struct cscfg_config_csdev *
46cscfg_alloc_csdev_cfg(struct coresight_device *csdev, int nr_feats)
47{
48	struct cscfg_config_csdev *config_csdev = NULL;
49	struct device *dev = csdev->dev.parent;
50
51	/* this is being allocated using the devm for the coresight device */
52	config_csdev = devm_kzalloc(dev,
53				    offsetof(struct cscfg_config_csdev, feats_csdev[nr_feats]),
54				    GFP_KERNEL);
55	if (!config_csdev)
56		return NULL;
57
58	config_csdev->csdev = csdev;
59	return config_csdev;
60}
61
62/* Load a config into a device if there are any feature matches between config and device */
63static int cscfg_add_csdev_cfg(struct coresight_device *csdev,
64			       struct cscfg_config_desc *config_desc)
65{
66	struct cscfg_config_csdev *config_csdev = NULL;
67	struct cscfg_feature_csdev *feat_csdev;
68	unsigned long flags;
69	int i;
70
71	/* look at each required feature and see if it matches any feature on the device */
72	for (i = 0; i < config_desc->nr_feat_refs; i++) {
73		/* look for a matching name */
74		feat_csdev = cscfg_get_feat_csdev(csdev, config_desc->feat_ref_names[i]);
75		if (feat_csdev) {
76			/*
77			 * At least one feature on this device matches the config
78			 * add a config instance to the device and a reference to the feature.
79			 */
80			if (!config_csdev) {
81				config_csdev = cscfg_alloc_csdev_cfg(csdev,
82								     config_desc->nr_feat_refs);
83				if (!config_csdev)
84					return -ENOMEM;
85				config_csdev->config_desc = config_desc;
86			}
87			config_csdev->feats_csdev[config_csdev->nr_feat++] = feat_csdev;
88		}
89	}
90	/* if matched features, add config to device.*/
91	if (config_csdev) {
92		spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
93		list_add(&config_csdev->node, &csdev->config_csdev_list);
94		spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
95	}
96
97	return 0;
98}
99
100/*
101 * Add the config to the set of registered devices - call with mutex locked.
102 * Iterates through devices - any device that matches one or more of the
103 * configuration features will load it, the others will ignore it.
104 */
105static int cscfg_add_cfg_to_csdevs(struct cscfg_config_desc *config_desc)
106{
107	struct cscfg_registered_csdev *csdev_item;
108	int err;
109
110	list_for_each_entry(csdev_item, &cscfg_mgr->csdev_desc_list, item) {
111		err = cscfg_add_csdev_cfg(csdev_item->csdev, config_desc);
112		if (err)
113			return err;
114	}
115	return 0;
116}
117
118/*
119 * Allocate a feature object for load into a csdev.
120 * memory allocated using the csdev->dev object using devm managed allocator.
121 */
122static struct cscfg_feature_csdev *
123cscfg_alloc_csdev_feat(struct coresight_device *csdev, struct cscfg_feature_desc *feat_desc)
124{
125	struct cscfg_feature_csdev *feat_csdev = NULL;
126	struct device *dev = csdev->dev.parent;
127	int i;
128
129	feat_csdev = devm_kzalloc(dev, sizeof(struct cscfg_feature_csdev), GFP_KERNEL);
130	if (!feat_csdev)
131		return NULL;
132
133	/* parameters are optional - could be 0 */
134	feat_csdev->nr_params = feat_desc->nr_params;
135
136	/*
137	 * if we need parameters, zero alloc the space here, the load routine in
138	 * the csdev device driver will fill out some information according to
139	 * feature descriptor.
140	 */
141	if (feat_csdev->nr_params) {
142		feat_csdev->params_csdev = devm_kcalloc(dev, feat_csdev->nr_params,
143							sizeof(struct cscfg_parameter_csdev),
144							GFP_KERNEL);
145		if (!feat_csdev->params_csdev)
146			return NULL;
147
148		/*
149		 * fill in the feature reference in the param - other fields
150		 * handled by loader in csdev.
151		 */
152		for (i = 0; i < feat_csdev->nr_params; i++)
153			feat_csdev->params_csdev[i].feat_csdev = feat_csdev;
154	}
155
156	/*
157	 * Always have registers to program - again the load routine in csdev device
158	 * will fill out according to feature descriptor and device requirements.
159	 */
160	feat_csdev->nr_regs = feat_desc->nr_regs;
161	feat_csdev->regs_csdev = devm_kcalloc(dev, feat_csdev->nr_regs,
162					      sizeof(struct cscfg_regval_csdev),
163					      GFP_KERNEL);
164	if (!feat_csdev->regs_csdev)
165		return NULL;
166
167	/* load the feature default values */
168	feat_csdev->feat_desc = feat_desc;
169	feat_csdev->csdev = csdev;
170
171	return feat_csdev;
172}
173
174/* load one feature into one coresight device */
175static int cscfg_load_feat_csdev(struct coresight_device *csdev,
176				 struct cscfg_feature_desc *feat_desc,
177				 struct cscfg_csdev_feat_ops *ops)
178{
179	struct cscfg_feature_csdev *feat_csdev;
180	unsigned long flags;
181	int err;
182
183	if (!ops->load_feat)
184		return -EINVAL;
185
186	feat_csdev = cscfg_alloc_csdev_feat(csdev, feat_desc);
187	if (!feat_csdev)
188		return -ENOMEM;
189
190	/* load the feature into the device */
191	err = ops->load_feat(csdev, feat_csdev);
192	if (err)
193		return err;
194
195	/* add to internal csdev feature list & initialise using reset call */
196	cscfg_reset_feat(feat_csdev);
197	spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
198	list_add(&feat_csdev->node, &csdev->feature_csdev_list);
199	spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
200
201	return 0;
202}
203
204/*
205 * Add feature to any matching devices - call with mutex locked.
206 * Iterates through devices - any device that matches the feature will be
207 * called to load it.
208 */
209static int cscfg_add_feat_to_csdevs(struct cscfg_feature_desc *feat_desc)
210{
211	struct cscfg_registered_csdev *csdev_item;
212	int err;
213
214	list_for_each_entry(csdev_item, &cscfg_mgr->csdev_desc_list, item) {
215		if (csdev_item->match_flags & feat_desc->match_flags) {
216			err = cscfg_load_feat_csdev(csdev_item->csdev, feat_desc, &csdev_item->ops);
217			if (err)
218				return err;
219		}
220	}
221	return 0;
222}
223
224/* check feature list for a named feature - call with mutex locked. */
225static bool cscfg_match_list_feat(const char *name)
226{
227	struct cscfg_feature_desc *feat_desc;
228
229	list_for_each_entry(feat_desc, &cscfg_mgr->feat_desc_list, item) {
230		if (strcmp(feat_desc->name, name) == 0)
231			return true;
232	}
233	return false;
234}
235
236/* check all feat needed for cfg are in the list - call with mutex locked. */
237static int cscfg_check_feat_for_cfg(struct cscfg_config_desc *config_desc)
238{
239	int i;
240
241	for (i = 0; i < config_desc->nr_feat_refs; i++)
242		if (!cscfg_match_list_feat(config_desc->feat_ref_names[i]))
243			return -EINVAL;
244	return 0;
245}
246
247/*
248 * load feature - add to feature list.
249 */
250static int cscfg_load_feat(struct cscfg_feature_desc *feat_desc)
251{
252	int err;
253	struct cscfg_feature_desc *feat_desc_exist;
254
255	/* new feature must have unique name */
256	list_for_each_entry(feat_desc_exist, &cscfg_mgr->feat_desc_list, item) {
257		if (!strcmp(feat_desc_exist->name, feat_desc->name))
258			return -EEXIST;
259	}
260
261	/* add feature to any matching registered devices */
262	err = cscfg_add_feat_to_csdevs(feat_desc);
263	if (err)
264		return err;
265
266	list_add(&feat_desc->item, &cscfg_mgr->feat_desc_list);
267	return 0;
268}
269
270/*
271 * load config into the system - validate used features exist then add to
272 * config list.
273 */
274static int cscfg_load_config(struct cscfg_config_desc *config_desc)
275{
276	int err;
277	struct cscfg_config_desc *config_desc_exist;
278
279	/* new configuration must have a unique name */
280	list_for_each_entry(config_desc_exist, &cscfg_mgr->config_desc_list, item) {
281		if (!strcmp(config_desc_exist->name, config_desc->name))
282			return -EEXIST;
283	}
284
285	/* validate features are present */
286	err = cscfg_check_feat_for_cfg(config_desc);
287	if (err)
288		return err;
289
290	/* add config to any matching registered device */
291	err = cscfg_add_cfg_to_csdevs(config_desc);
292	if (err)
293		return err;
294
295	/* add config to perf fs to allow selection */
296	err = etm_perf_add_symlink_cscfg(cscfg_device(), config_desc);
297	if (err)
298		return err;
299
300	list_add(&config_desc->item, &cscfg_mgr->config_desc_list);
301	atomic_set(&config_desc->active_cnt, 0);
302	return 0;
303}
304
305/* get a feature descriptor by name */
306const struct cscfg_feature_desc *cscfg_get_named_feat_desc(const char *name)
307{
308	const struct cscfg_feature_desc *feat_desc = NULL, *feat_desc_item;
309
310	mutex_lock(&cscfg_mutex);
311
312	list_for_each_entry(feat_desc_item, &cscfg_mgr->feat_desc_list, item) {
313		if (strcmp(feat_desc_item->name, name) == 0) {
314			feat_desc = feat_desc_item;
315			break;
316		}
317	}
318
319	mutex_unlock(&cscfg_mutex);
320	return feat_desc;
321}
322
323/* called with cscfg_mutex held */
324static struct cscfg_feature_csdev *
325cscfg_csdev_get_feat_from_desc(struct coresight_device *csdev,
326			       struct cscfg_feature_desc *feat_desc)
327{
328	struct cscfg_feature_csdev *feat_csdev;
329
330	list_for_each_entry(feat_csdev, &csdev->feature_csdev_list, node) {
331		if (feat_csdev->feat_desc == feat_desc)
332			return feat_csdev;
333	}
334	return NULL;
335}
336
337int cscfg_update_feat_param_val(struct cscfg_feature_desc *feat_desc,
338				int param_idx, u64 value)
339{
340	int err = 0;
341	struct cscfg_feature_csdev *feat_csdev;
342	struct cscfg_registered_csdev *csdev_item;
343
344	mutex_lock(&cscfg_mutex);
345
346	/* check if any config active & return busy */
347	if (atomic_read(&cscfg_mgr->sys_active_cnt)) {
348		err = -EBUSY;
349		goto unlock_exit;
350	}
351
352	/* set the value */
353	if ((param_idx < 0) || (param_idx >= feat_desc->nr_params)) {
354		err = -EINVAL;
355		goto unlock_exit;
356	}
357	feat_desc->params_desc[param_idx].value = value;
358
359	/* update loaded instances.*/
360	list_for_each_entry(csdev_item, &cscfg_mgr->csdev_desc_list, item) {
361		feat_csdev = cscfg_csdev_get_feat_from_desc(csdev_item->csdev, feat_desc);
362		if (feat_csdev)
363			feat_csdev->params_csdev[param_idx].current_value = value;
364	}
365
366unlock_exit:
367	mutex_unlock(&cscfg_mutex);
368	return err;
369}
370
371/*
372 * Conditionally up reference count on owner to prevent unload.
373 *
374 * module loaded configs need to be locked in to prevent premature unload.
375 */
376static int cscfg_owner_get(struct cscfg_load_owner_info *owner_info)
377{
378	if ((owner_info->type == CSCFG_OWNER_MODULE) &&
379	    (!try_module_get(owner_info->owner_handle)))
380		return -EINVAL;
381	return 0;
382}
383
384/* conditionally lower ref count on an owner */
385static void cscfg_owner_put(struct cscfg_load_owner_info *owner_info)
386{
387	if (owner_info->type == CSCFG_OWNER_MODULE)
388		module_put(owner_info->owner_handle);
389}
390
391static void cscfg_remove_owned_csdev_configs(struct coresight_device *csdev, void *load_owner)
392{
393	struct cscfg_config_csdev *config_csdev, *tmp;
394
395	if (list_empty(&csdev->config_csdev_list))
396		return;
397
398	list_for_each_entry_safe(config_csdev, tmp, &csdev->config_csdev_list, node) {
399		if (config_csdev->config_desc->load_owner == load_owner)
400			list_del(&config_csdev->node);
401	}
402}
403
404static void cscfg_remove_owned_csdev_features(struct coresight_device *csdev, void *load_owner)
405{
406	struct cscfg_feature_csdev *feat_csdev, *tmp;
407
408	if (list_empty(&csdev->feature_csdev_list))
409		return;
410
411	list_for_each_entry_safe(feat_csdev, tmp, &csdev->feature_csdev_list, node) {
412		if (feat_csdev->feat_desc->load_owner == load_owner)
413			list_del(&feat_csdev->node);
414	}
415}
416
417/*
418 * Unregister all configuration and features from configfs owned by load_owner.
419 * Although this is called without the list mutex being held, it is in the
420 * context of an unload operation which are strictly serialised,
421 * so the lists cannot change during this call.
422 */
423static void cscfg_fs_unregister_cfgs_feats(void *load_owner)
424{
425	struct cscfg_config_desc *config_desc;
426	struct cscfg_feature_desc *feat_desc;
427
428	list_for_each_entry(config_desc, &cscfg_mgr->config_desc_list, item) {
429		if (config_desc->load_owner == load_owner)
430			cscfg_configfs_del_config(config_desc);
431	}
432	list_for_each_entry(feat_desc, &cscfg_mgr->feat_desc_list, item) {
433		if (feat_desc->load_owner == load_owner)
434			cscfg_configfs_del_feature(feat_desc);
435	}
436}
437
438/*
439 * removal is relatively easy - just remove from all lists, anything that
440 * matches the owner. Memory for the descriptors will be managed by the owner,
441 * memory for the csdev items is devm_ allocated with the individual csdev
442 * devices.
443 */
444static void cscfg_unload_owned_cfgs_feats(void *load_owner)
445{
446	struct cscfg_config_desc *config_desc, *cfg_tmp;
447	struct cscfg_feature_desc *feat_desc, *feat_tmp;
448	struct cscfg_registered_csdev *csdev_item;
449
450	lockdep_assert_held(&cscfg_mutex);
451
452	/* remove from each csdev instance feature and config lists */
453	list_for_each_entry(csdev_item, &cscfg_mgr->csdev_desc_list, item) {
454		/*
455		 * for each csdev, check the loaded lists and remove if
456		 * referenced descriptor is owned
457		 */
458		cscfg_remove_owned_csdev_configs(csdev_item->csdev, load_owner);
459		cscfg_remove_owned_csdev_features(csdev_item->csdev, load_owner);
460	}
461
462	/* remove from the config descriptor lists */
463	list_for_each_entry_safe(config_desc, cfg_tmp, &cscfg_mgr->config_desc_list, item) {
464		if (config_desc->load_owner == load_owner) {
465			etm_perf_del_symlink_cscfg(config_desc);
466			list_del(&config_desc->item);
467		}
468	}
469
470	/* remove from the feature descriptor lists */
471	list_for_each_entry_safe(feat_desc, feat_tmp, &cscfg_mgr->feat_desc_list, item) {
472		if (feat_desc->load_owner == load_owner) {
473			list_del(&feat_desc->item);
474		}
475	}
476}
477
478/*
479 * load the features and configs to the lists - called with list mutex held
480 */
481static int cscfg_load_owned_cfgs_feats(struct cscfg_config_desc **config_descs,
482				       struct cscfg_feature_desc **feat_descs,
483				       struct cscfg_load_owner_info *owner_info)
484{
485	int i, err;
486
487	lockdep_assert_held(&cscfg_mutex);
488
489	/* load features first */
490	if (feat_descs) {
491		for (i = 0; feat_descs[i]; i++) {
492			err = cscfg_load_feat(feat_descs[i]);
493			if (err) {
494				pr_err("coresight-syscfg: Failed to load feature %s\n",
495				       feat_descs[i]->name);
496				return err;
497			}
498			feat_descs[i]->load_owner = owner_info;
499		}
500	}
501
502	/* next any configurations to check feature dependencies */
503	if (config_descs) {
504		for (i = 0; config_descs[i]; i++) {
505			err = cscfg_load_config(config_descs[i]);
506			if (err) {
507				pr_err("coresight-syscfg: Failed to load configuration %s\n",
508				       config_descs[i]->name);
509				return err;
510			}
511			config_descs[i]->load_owner = owner_info;
512			config_descs[i]->available = false;
513		}
514	}
515	return 0;
516}
517
518/* set configurations as available to activate at the end of the load process */
519static void cscfg_set_configs_available(struct cscfg_config_desc **config_descs)
520{
521	int i;
522
523	lockdep_assert_held(&cscfg_mutex);
524
525	if (config_descs) {
526		for (i = 0; config_descs[i]; i++)
527			config_descs[i]->available = true;
528	}
529}
530
531/*
532 * Create and register each of the configurations and features with configfs.
533 * Called without mutex being held.
534 */
535static int cscfg_fs_register_cfgs_feats(struct cscfg_config_desc **config_descs,
536					struct cscfg_feature_desc **feat_descs)
537{
538	int i, err;
539
540	if (feat_descs) {
541		for (i = 0; feat_descs[i]; i++) {
542			err = cscfg_configfs_add_feature(feat_descs[i]);
543			if (err)
544				return err;
545		}
546	}
547	if (config_descs) {
548		for (i = 0; config_descs[i]; i++) {
549			err = cscfg_configfs_add_config(config_descs[i]);
550			if (err)
551				return err;
552		}
553	}
554	return 0;
555}
556
557/**
558 * cscfg_load_config_sets - API function to load feature and config sets.
559 *
560 * Take a 0 terminated array of feature descriptors and/or configuration
561 * descriptors and load into the system.
562 * Features are loaded first to ensure configuration dependencies can be met.
563 *
564 * To facilitate dynamic loading and unloading, features and configurations
565 * have a "load_owner", to allow later unload by the same owner. An owner may
566 * be a loadable module or configuration dynamically created via configfs.
567 * As later loaded configurations can use earlier loaded features, creating load
568 * dependencies, a load order list is maintained. Unload is strictly in the
569 * reverse order to load.
570 *
571 * @config_descs: 0 terminated array of configuration descriptors.
572 * @feat_descs:   0 terminated array of feature descriptors.
573 * @owner_info:	  Information on the owner of this set.
574 */
575int cscfg_load_config_sets(struct cscfg_config_desc **config_descs,
576			   struct cscfg_feature_desc **feat_descs,
577			   struct cscfg_load_owner_info *owner_info)
578{
579	int err = 0;
580
581	mutex_lock(&cscfg_mutex);
582	if (cscfg_mgr->load_state != CSCFG_NONE) {
583		mutex_unlock(&cscfg_mutex);
584		return -EBUSY;
585	}
586	cscfg_mgr->load_state = CSCFG_LOAD;
587
588	/* first load and add to the lists */
589	err = cscfg_load_owned_cfgs_feats(config_descs, feat_descs, owner_info);
590	if (err)
591		goto err_clean_load;
592
593	/* add the load owner to the load order list */
594	list_add_tail(&owner_info->item, &cscfg_mgr->load_order_list);
595	if (!list_is_singular(&cscfg_mgr->load_order_list)) {
596		/* lock previous item in load order list */
597		err = cscfg_owner_get(list_prev_entry(owner_info, item));
598		if (err)
599			goto err_clean_owner_list;
600	}
601
602	/*
603	 * make visible to configfs - configfs manipulation must occur outside
604	 * the list mutex lock to avoid circular lockdep issues with configfs
605	 * built in mutexes and semaphores. This is safe as it is not possible
606	 * to start a new load/unload operation till the current one is done.
607	 */
608	mutex_unlock(&cscfg_mutex);
609
610	/* create the configfs elements */
611	err = cscfg_fs_register_cfgs_feats(config_descs, feat_descs);
612	mutex_lock(&cscfg_mutex);
613
614	if (err)
615		goto err_clean_cfs;
616
617	/* mark any new configs as available for activation */
618	cscfg_set_configs_available(config_descs);
619	goto exit_unlock;
620
621err_clean_cfs:
622	/* cleanup after error registering with configfs */
623	cscfg_fs_unregister_cfgs_feats(owner_info);
624
625	if (!list_is_singular(&cscfg_mgr->load_order_list))
626		cscfg_owner_put(list_prev_entry(owner_info, item));
627
628err_clean_owner_list:
629	list_del(&owner_info->item);
630
631err_clean_load:
632	cscfg_unload_owned_cfgs_feats(owner_info);
633
634exit_unlock:
635	cscfg_mgr->load_state = CSCFG_NONE;
636	mutex_unlock(&cscfg_mutex);
637	return err;
638}
639EXPORT_SYMBOL_GPL(cscfg_load_config_sets);
640
641/**
642 * cscfg_unload_config_sets - unload a set of configurations by owner.
643 *
644 * Dynamic unload of configuration and feature sets is done on the basis of
645 * the load owner of that set. Later loaded configurations can depend on
646 * features loaded earlier.
647 *
648 * Therefore, unload is only possible if:-
649 * 1) no configurations are active.
650 * 2) the set being unloaded was the last to be loaded to maintain dependencies.
651 *
652 * Once the unload operation commences, we disallow any configuration being
653 * made active until it is complete.
654 *
655 * @owner_info:	Information on owner for set being unloaded.
656 */
657int cscfg_unload_config_sets(struct cscfg_load_owner_info *owner_info)
658{
659	int err = 0;
660	struct cscfg_load_owner_info *load_list_item = NULL;
661
662	mutex_lock(&cscfg_mutex);
663	if (cscfg_mgr->load_state != CSCFG_NONE) {
664		mutex_unlock(&cscfg_mutex);
665		return -EBUSY;
666	}
667
668	/* unload op in progress also prevents activation of any config */
669	cscfg_mgr->load_state = CSCFG_UNLOAD;
670
671	/* cannot unload if anything is active */
672	if (atomic_read(&cscfg_mgr->sys_active_cnt)) {
673		err = -EBUSY;
674		goto exit_unlock;
675	}
676
677	/* cannot unload if not last loaded in load order */
678	if (!list_empty(&cscfg_mgr->load_order_list)) {
679		load_list_item = list_last_entry(&cscfg_mgr->load_order_list,
680						 struct cscfg_load_owner_info, item);
681		if (load_list_item != owner_info)
682			load_list_item = NULL;
683	}
684
685	if (!load_list_item) {
686		err = -EINVAL;
687		goto exit_unlock;
688	}
689
690	/* remove from configfs - again outside the scope of the list mutex */
691	mutex_unlock(&cscfg_mutex);
692	cscfg_fs_unregister_cfgs_feats(owner_info);
693	mutex_lock(&cscfg_mutex);
694
695	/* unload everything from lists belonging to load_owner */
696	cscfg_unload_owned_cfgs_feats(owner_info);
697
698	/* remove from load order list */
699	if (!list_is_singular(&cscfg_mgr->load_order_list)) {
700		/* unlock previous item in load order list */
701		cscfg_owner_put(list_prev_entry(owner_info, item));
702	}
703	list_del(&owner_info->item);
704
705exit_unlock:
706	cscfg_mgr->load_state = CSCFG_NONE;
707	mutex_unlock(&cscfg_mutex);
708	return err;
709}
710EXPORT_SYMBOL_GPL(cscfg_unload_config_sets);
711
712/* Handle coresight device registration and add configs and features to devices */
713
714/* iterate through config lists and load matching configs to device */
715static int cscfg_add_cfgs_csdev(struct coresight_device *csdev)
716{
717	struct cscfg_config_desc *config_desc;
718	int err = 0;
719
720	list_for_each_entry(config_desc, &cscfg_mgr->config_desc_list, item) {
721		err = cscfg_add_csdev_cfg(csdev, config_desc);
722		if (err)
723			break;
724	}
725	return err;
726}
727
728/* iterate through feature lists and load matching features to device */
729static int cscfg_add_feats_csdev(struct coresight_device *csdev,
730				 u32 match_flags,
731				 struct cscfg_csdev_feat_ops *ops)
732{
733	struct cscfg_feature_desc *feat_desc;
734	int err = 0;
735
736	if (!ops->load_feat)
737		return -EINVAL;
738
739	list_for_each_entry(feat_desc, &cscfg_mgr->feat_desc_list, item) {
740		if (feat_desc->match_flags & match_flags) {
741			err = cscfg_load_feat_csdev(csdev, feat_desc, ops);
742			if (err)
743				break;
744		}
745	}
746	return err;
747}
748
749/* Add coresight device to list and copy its matching info */
750static int cscfg_list_add_csdev(struct coresight_device *csdev,
751				u32 match_flags,
752				struct cscfg_csdev_feat_ops *ops)
753{
754	struct cscfg_registered_csdev *csdev_item;
755
756	/* allocate the list entry structure */
757	csdev_item = kzalloc(sizeof(struct cscfg_registered_csdev), GFP_KERNEL);
758	if (!csdev_item)
759		return -ENOMEM;
760
761	csdev_item->csdev = csdev;
762	csdev_item->match_flags = match_flags;
763	csdev_item->ops.load_feat = ops->load_feat;
764	list_add(&csdev_item->item, &cscfg_mgr->csdev_desc_list);
765
766	INIT_LIST_HEAD(&csdev->feature_csdev_list);
767	INIT_LIST_HEAD(&csdev->config_csdev_list);
768	spin_lock_init(&csdev->cscfg_csdev_lock);
769
770	return 0;
771}
772
773/* remove a coresight device from the list and free data */
774static void cscfg_list_remove_csdev(struct coresight_device *csdev)
775{
776	struct cscfg_registered_csdev *csdev_item, *tmp;
777
778	list_for_each_entry_safe(csdev_item, tmp, &cscfg_mgr->csdev_desc_list, item) {
779		if (csdev_item->csdev == csdev) {
780			list_del(&csdev_item->item);
781			kfree(csdev_item);
782			break;
783		}
784	}
785}
786
787/**
788 * cscfg_register_csdev - register a coresight device with the syscfg manager.
789 *
790 * Registers the coresight device with the system. @match_flags used to check
791 * if the device is a match for registered features. Any currently registered
792 * configurations and features that match the device will be loaded onto it.
793 *
794 * @csdev:		The coresight device to register.
795 * @match_flags:	Matching information to load features.
796 * @ops:		Standard operations supported by the device.
797 */
798int cscfg_register_csdev(struct coresight_device *csdev,
799			 u32 match_flags,
800			 struct cscfg_csdev_feat_ops *ops)
801{
802	int ret = 0;
803
804	mutex_lock(&cscfg_mutex);
805
806	/* add device to list of registered devices  */
807	ret = cscfg_list_add_csdev(csdev, match_flags, ops);
808	if (ret)
809		goto reg_csdev_unlock;
810
811	/* now load any registered features and configs matching the device. */
812	ret = cscfg_add_feats_csdev(csdev, match_flags, ops);
813	if (ret) {
814		cscfg_list_remove_csdev(csdev);
815		goto reg_csdev_unlock;
816	}
817
818	ret = cscfg_add_cfgs_csdev(csdev);
819	if (ret) {
820		cscfg_list_remove_csdev(csdev);
821		goto reg_csdev_unlock;
822	}
823
824	pr_info("CSCFG registered %s", dev_name(&csdev->dev));
825
826reg_csdev_unlock:
827	mutex_unlock(&cscfg_mutex);
828	return ret;
829}
830EXPORT_SYMBOL_GPL(cscfg_register_csdev);
831
832/**
833 * cscfg_unregister_csdev - remove coresight device from syscfg manager.
834 *
835 * @csdev: Device to remove.
836 */
837void cscfg_unregister_csdev(struct coresight_device *csdev)
838{
839	mutex_lock(&cscfg_mutex);
840	cscfg_list_remove_csdev(csdev);
841	mutex_unlock(&cscfg_mutex);
842}
843EXPORT_SYMBOL_GPL(cscfg_unregister_csdev);
844
845/**
846 * cscfg_csdev_reset_feats - reset features for a CoreSight device.
847 *
848 * Resets all parameters and register values for any features loaded
849 * into @csdev to their default values.
850 *
851 * @csdev: The CoreSight device.
852 */
853void cscfg_csdev_reset_feats(struct coresight_device *csdev)
854{
855	struct cscfg_feature_csdev *feat_csdev;
856	unsigned long flags;
857
858	spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
859	if (list_empty(&csdev->feature_csdev_list))
860		goto unlock_exit;
861
862	list_for_each_entry(feat_csdev, &csdev->feature_csdev_list, node)
863		cscfg_reset_feat(feat_csdev);
864
865unlock_exit:
866	spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
867}
868EXPORT_SYMBOL_GPL(cscfg_csdev_reset_feats);
869
870/*
871 * This activate configuration for either perf or sysfs. Perf can have multiple
872 * active configs, selected per event, sysfs is limited to one.
873 *
874 * Increments the configuration descriptor active count and the global active
875 * count.
876 *
877 * @cfg_hash: Hash value of the selected configuration name.
878 */
879static int _cscfg_activate_config(unsigned long cfg_hash)
880{
881	struct cscfg_config_desc *config_desc;
882	int err = -EINVAL;
883
884	if (cscfg_mgr->load_state == CSCFG_UNLOAD)
885		return -EBUSY;
886
887	list_for_each_entry(config_desc, &cscfg_mgr->config_desc_list, item) {
888		if ((unsigned long)config_desc->event_ea->var == cfg_hash) {
889			/* if we happen upon a partly loaded config, can't use it */
890			if (config_desc->available == false)
891				return -EBUSY;
892
893			/* must ensure that config cannot be unloaded in use */
894			err = cscfg_owner_get(config_desc->load_owner);
895			if (err)
896				break;
897			/*
898			 * increment the global active count - control changes to
899			 * active configurations
900			 */
901			atomic_inc(&cscfg_mgr->sys_active_cnt);
902
903			/*
904			 * mark the descriptor as active so enable config on a
905			 * device instance will use it
906			 */
907			atomic_inc(&config_desc->active_cnt);
908
909			err = 0;
910			dev_dbg(cscfg_device(), "Activate config %s.\n", config_desc->name);
911			break;
912		}
913	}
914	return err;
915}
916
917static void _cscfg_deactivate_config(unsigned long cfg_hash)
918{
919	struct cscfg_config_desc *config_desc;
920
921	list_for_each_entry(config_desc, &cscfg_mgr->config_desc_list, item) {
922		if ((unsigned long)config_desc->event_ea->var == cfg_hash) {
923			atomic_dec(&config_desc->active_cnt);
924			atomic_dec(&cscfg_mgr->sys_active_cnt);
925			cscfg_owner_put(config_desc->load_owner);
926			dev_dbg(cscfg_device(), "Deactivate config %s.\n", config_desc->name);
927			break;
928		}
929	}
930}
931
932/*
933 * called from configfs to set/clear the active configuration for use when
934 * using sysfs to control trace.
935 */
936int cscfg_config_sysfs_activate(struct cscfg_config_desc *config_desc, bool activate)
937{
938	unsigned long cfg_hash;
939	int err = 0;
940
941	mutex_lock(&cscfg_mutex);
942
943	cfg_hash = (unsigned long)config_desc->event_ea->var;
944
945	if (activate) {
946		/* cannot be a current active value to activate this */
947		if (cscfg_mgr->sysfs_active_config) {
948			err = -EBUSY;
949			goto exit_unlock;
950		}
951		err = _cscfg_activate_config(cfg_hash);
952		if (!err)
953			cscfg_mgr->sysfs_active_config = cfg_hash;
954	} else {
955		/* disable if matching current value */
956		if (cscfg_mgr->sysfs_active_config == cfg_hash) {
957			_cscfg_deactivate_config(cfg_hash);
958			cscfg_mgr->sysfs_active_config = 0;
959		} else
960			err = -EINVAL;
961	}
962
963exit_unlock:
964	mutex_unlock(&cscfg_mutex);
965	return err;
966}
967
968/* set the sysfs preset value */
969void cscfg_config_sysfs_set_preset(int preset)
970{
971	mutex_lock(&cscfg_mutex);
972	cscfg_mgr->sysfs_active_preset = preset;
973	mutex_unlock(&cscfg_mutex);
974}
975
976/*
977 * Used by a device to get the config and preset selected as active in configfs,
978 * when using sysfs to control trace.
979 */
980void cscfg_config_sysfs_get_active_cfg(unsigned long *cfg_hash, int *preset)
981{
982	mutex_lock(&cscfg_mutex);
983	*preset = cscfg_mgr->sysfs_active_preset;
984	*cfg_hash = cscfg_mgr->sysfs_active_config;
985	mutex_unlock(&cscfg_mutex);
986}
987EXPORT_SYMBOL_GPL(cscfg_config_sysfs_get_active_cfg);
988
989/**
990 * cscfg_activate_config -  Mark a configuration descriptor as active.
991 *
992 * This will be seen when csdev devices are enabled in the system.
993 * Only activated configurations can be enabled on individual devices.
994 * Activation protects the configuration from alteration or removal while
995 * active.
996 *
997 * Selection by hash value - generated from the configuration name when it
998 * was loaded and added to the cs_etm/configurations file system for selection
999 * by perf.
1000 *
1001 * @cfg_hash: Hash value of the selected configuration name.
1002 */
1003int cscfg_activate_config(unsigned long cfg_hash)
1004{
1005	int err = 0;
1006
1007	mutex_lock(&cscfg_mutex);
1008	err = _cscfg_activate_config(cfg_hash);
1009	mutex_unlock(&cscfg_mutex);
1010
1011	return err;
1012}
1013EXPORT_SYMBOL_GPL(cscfg_activate_config);
1014
1015/**
1016 * cscfg_deactivate_config -  Mark a config descriptor as inactive.
1017 *
1018 * Decrement the configuration and global active counts.
1019 *
1020 * @cfg_hash: Hash value of the selected configuration name.
1021 */
1022void cscfg_deactivate_config(unsigned long cfg_hash)
1023{
1024	mutex_lock(&cscfg_mutex);
1025	_cscfg_deactivate_config(cfg_hash);
1026	mutex_unlock(&cscfg_mutex);
1027}
1028EXPORT_SYMBOL_GPL(cscfg_deactivate_config);
1029
1030/**
1031 * cscfg_csdev_enable_active_config - Enable matching active configuration for device.
1032 *
1033 * Enables the configuration selected by @cfg_hash if the configuration is supported
1034 * on the device and has been activated.
1035 *
1036 * If active and supported the CoreSight device @csdev will be programmed with the
1037 * configuration, using @preset parameters.
1038 *
1039 * Should be called before driver hardware enable for the requested device, prior to
1040 * programming and enabling the physical hardware.
1041 *
1042 * @csdev:	CoreSight device to program.
1043 * @cfg_hash:	Selector for the configuration.
1044 * @preset:	Preset parameter values to use, 0 for current / default values.
1045 */
1046int cscfg_csdev_enable_active_config(struct coresight_device *csdev,
1047				     unsigned long cfg_hash, int preset)
1048{
1049	struct cscfg_config_csdev *config_csdev_active = NULL, *config_csdev_item;
1050	const struct cscfg_config_desc *config_desc;
1051	unsigned long flags;
1052	int err = 0;
1053
1054	/* quickly check global count */
1055	if (!atomic_read(&cscfg_mgr->sys_active_cnt))
1056		return 0;
1057
1058	/*
1059	 * Look for matching configuration - set the active configuration
1060	 * context if found.
1061	 */
1062	spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
1063	list_for_each_entry(config_csdev_item, &csdev->config_csdev_list, node) {
1064		config_desc = config_csdev_item->config_desc;
1065		if ((atomic_read(&config_desc->active_cnt)) &&
1066		    ((unsigned long)config_desc->event_ea->var == cfg_hash)) {
1067			config_csdev_active = config_csdev_item;
1068			csdev->active_cscfg_ctxt = (void *)config_csdev_active;
1069			break;
1070		}
1071	}
1072	spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
1073
1074	/*
1075	 * If found, attempt to enable
1076	 */
1077	if (config_csdev_active) {
1078		/*
1079		 * Call the generic routine that will program up the internal
1080		 * driver structures prior to programming up the hardware.
1081		 * This routine takes the driver spinlock saved in the configs.
1082		 */
1083		err = cscfg_csdev_enable_config(config_csdev_active, preset);
1084		if (!err) {
1085			/*
1086			 * Successful programming. Check the active_cscfg_ctxt
1087			 * pointer to ensure no pre-emption disabled it via
1088			 * cscfg_csdev_disable_active_config() before
1089			 * we could start.
1090			 *
1091			 * Set enabled if OK, err if not.
1092			 */
1093			spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
1094			if (csdev->active_cscfg_ctxt)
1095				config_csdev_active->enabled = true;
1096			else
1097				err = -EBUSY;
1098			spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
1099		}
1100	}
1101	return err;
1102}
1103EXPORT_SYMBOL_GPL(cscfg_csdev_enable_active_config);
1104
1105/**
1106 * cscfg_csdev_disable_active_config - disable an active config on the device.
1107 *
1108 * Disables the active configuration on the CoreSight device @csdev.
1109 * Disable will save the values of any registers marked in the configurations
1110 * as save on disable.
1111 *
1112 * Should be called after driver hardware disable for the requested device,
1113 * after disabling the physical hardware and reading back registers.
1114 *
1115 * @csdev: The CoreSight device.
1116 */
1117void cscfg_csdev_disable_active_config(struct coresight_device *csdev)
1118{
1119	struct cscfg_config_csdev *config_csdev;
1120	unsigned long flags;
1121
1122	/*
1123	 * Check if we have an active config, and that it was successfully enabled.
1124	 * If it was not enabled, we have no work to do, otherwise mark as disabled.
1125	 * Clear the active config pointer.
1126	 */
1127	spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
1128	config_csdev = (struct cscfg_config_csdev *)csdev->active_cscfg_ctxt;
1129	if (config_csdev) {
1130		if (!config_csdev->enabled)
1131			config_csdev = NULL;
1132		else
1133			config_csdev->enabled = false;
1134	}
1135	csdev->active_cscfg_ctxt = NULL;
1136	spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
1137
1138	/* true if there was an enabled active config */
1139	if (config_csdev)
1140		cscfg_csdev_disable_config(config_csdev);
1141}
1142EXPORT_SYMBOL_GPL(cscfg_csdev_disable_active_config);
1143
1144/* Initialise system configuration management device. */
1145
1146struct device *cscfg_device(void)
1147{
1148	return cscfg_mgr ? &cscfg_mgr->dev : NULL;
1149}
1150
1151/* Must have a release function or the kernel will complain on module unload */
1152static void cscfg_dev_release(struct device *dev)
1153{
1154	mutex_lock(&cscfg_mutex);
1155	kfree(cscfg_mgr);
1156	cscfg_mgr = NULL;
1157	mutex_unlock(&cscfg_mutex);
1158}
1159
1160/* a device is needed to "own" some kernel elements such as sysfs entries.  */
1161static int cscfg_create_device(void)
1162{
1163	struct device *dev;
1164	int err = -ENOMEM;
1165
1166	mutex_lock(&cscfg_mutex);
1167	if (cscfg_mgr) {
1168		err = -EINVAL;
1169		goto create_dev_exit_unlock;
1170	}
1171
1172	cscfg_mgr = kzalloc(sizeof(struct cscfg_manager), GFP_KERNEL);
1173	if (!cscfg_mgr)
1174		goto create_dev_exit_unlock;
1175
1176	/* initialise the cscfg_mgr structure */
1177	INIT_LIST_HEAD(&cscfg_mgr->csdev_desc_list);
1178	INIT_LIST_HEAD(&cscfg_mgr->feat_desc_list);
1179	INIT_LIST_HEAD(&cscfg_mgr->config_desc_list);
1180	INIT_LIST_HEAD(&cscfg_mgr->load_order_list);
1181	atomic_set(&cscfg_mgr->sys_active_cnt, 0);
1182	cscfg_mgr->load_state = CSCFG_NONE;
1183
1184	/* setup the device */
1185	dev = cscfg_device();
1186	dev->release = cscfg_dev_release;
1187	dev->init_name = "cs_system_cfg";
1188
1189	err = device_register(dev);
1190	if (err)
1191		put_device(dev);
1192
1193create_dev_exit_unlock:
1194	mutex_unlock(&cscfg_mutex);
1195	return err;
1196}
1197
1198/*
1199 * Loading and unloading is generally on user discretion.
1200 * If exiting due to coresight module unload, we need to unload any configurations that remain,
1201 * before we unregister the configfs intrastructure.
1202 *
1203 * Do this by walking the load_owner list and taking appropriate action, depending on the load
1204 * owner type.
1205 */
1206static void cscfg_unload_cfgs_on_exit(void)
1207{
1208	struct cscfg_load_owner_info *owner_info = NULL;
1209
1210	/*
1211	 * grab the mutex - even though we are exiting, some configfs files
1212	 * may still be live till we dump them, so ensure list data is
1213	 * protected from a race condition.
1214	 */
1215	mutex_lock(&cscfg_mutex);
1216	while (!list_empty(&cscfg_mgr->load_order_list)) {
1217
1218		/* remove in reverse order of loading */
1219		owner_info = list_last_entry(&cscfg_mgr->load_order_list,
1220					     struct cscfg_load_owner_info, item);
1221
1222		/* action according to type */
1223		switch (owner_info->type) {
1224		case CSCFG_OWNER_PRELOAD:
1225			/*
1226			 * preloaded  descriptors are statically allocated in
1227			 * this module - just need to unload dynamic items from
1228			 * csdev lists, and remove from configfs directories.
1229			 */
1230			pr_info("cscfg: unloading preloaded configurations\n");
1231			break;
1232
1233		case  CSCFG_OWNER_MODULE:
1234			/*
1235			 * this is an error - the loadable module must have been unloaded prior
1236			 * to the coresight module unload. Therefore that module has not
1237			 * correctly unloaded configs in its own exit code.
1238			 * Nothing to do other than emit an error string as the static descriptor
1239			 * references we need to unload will have disappeared with the module.
1240			 */
1241			pr_err("cscfg: ERROR: prior module failed to unload configuration\n");
1242			goto list_remove;
1243		}
1244
1245		/* remove from configfs - outside the scope of the list mutex */
1246		mutex_unlock(&cscfg_mutex);
1247		cscfg_fs_unregister_cfgs_feats(owner_info);
1248		mutex_lock(&cscfg_mutex);
1249
1250		/* Next unload from csdev lists. */
1251		cscfg_unload_owned_cfgs_feats(owner_info);
1252
1253list_remove:
1254		/* remove from load order list */
1255		list_del(&owner_info->item);
1256	}
1257	mutex_unlock(&cscfg_mutex);
1258}
1259
1260static void cscfg_clear_device(void)
1261{
1262	cscfg_unload_cfgs_on_exit();
1263	cscfg_configfs_release(cscfg_mgr);
1264	device_unregister(cscfg_device());
1265}
1266
1267/* Initialise system config management API device  */
1268int __init cscfg_init(void)
1269{
1270	int err = 0;
1271
1272	/* create the device and init cscfg_mgr */
1273	err = cscfg_create_device();
1274	if (err)
1275		return err;
1276
1277	/* initialise configfs subsystem */
1278	err = cscfg_configfs_init(cscfg_mgr);
1279	if (err)
1280		goto exit_err;
1281
1282	/* preload built-in configurations */
1283	err = cscfg_preload(THIS_MODULE);
1284	if (err)
1285		goto exit_err;
1286
1287	dev_info(cscfg_device(), "CoreSight Configuration manager initialised");
1288	return 0;
1289
1290exit_err:
1291	cscfg_clear_device();
1292	return err;
1293}
1294
1295void cscfg_exit(void)
1296{
1297	cscfg_clear_device();
1298}
1299