Skip to content

Commit f8cce2f

Browse files
mikel-armbbgregkh
authored andcommitted
coresight: syscfg: Add API to activate and enable configurations
Configurations are first activated, then when any coresight device is enabled, the active configurations are checked and any matching one is enabled. This patch provides the activation / enable API. Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Mike Leach <[email protected]> Signed-off-by: Mathieu Poirier <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 94d2bac commit f8cce2f

File tree

4 files changed

+227
-0
lines changed

4 files changed

+227
-0
lines changed

drivers/hwtracing/coresight/coresight-config.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ struct cscfg_feature_desc {
127127
* @nr_total_params: Sum of all parameters declared by used features
128128
* @presets: Array of preset values.
129129
* @event_ea: Extended attribute for perf event value
130+
* @active_cnt: ref count for activate on this configuration.
130131
*
131132
*/
132133
struct cscfg_config_desc {
@@ -139,6 +140,7 @@ struct cscfg_config_desc {
139140
int nr_total_params;
140141
const u64 *presets; /* nr_presets * nr_total_params */
141142
struct dev_ext_attribute *event_ea;
143+
atomic_t active_cnt;
142144
};
143145

144146
/**

drivers/hwtracing/coresight/coresight-syscfg.c

Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,7 @@ static int cscfg_load_config(struct cscfg_config_desc *config_desc)
282282
return err;
283283

284284
list_add(&config_desc->item, &cscfg_mgr->config_desc_list);
285+
atomic_set(&config_desc->active_cnt, 0);
285286
return 0;
286287
}
287288

@@ -468,6 +469,219 @@ void cscfg_unregister_csdev(struct coresight_device *csdev)
468469
}
469470
EXPORT_SYMBOL_GPL(cscfg_unregister_csdev);
470471

472+
/**
473+
* cscfg_csdev_reset_feats - reset features for a CoreSight device.
474+
*
475+
* Resets all parameters and register values for any features loaded
476+
* into @csdev to their default values.
477+
*
478+
* @csdev: The CoreSight device.
479+
*/
480+
void cscfg_csdev_reset_feats(struct coresight_device *csdev)
481+
{
482+
struct cscfg_feature_csdev *feat_csdev;
483+
unsigned long flags;
484+
485+
spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
486+
if (list_empty(&csdev->feature_csdev_list))
487+
goto unlock_exit;
488+
489+
list_for_each_entry(feat_csdev, &csdev->feature_csdev_list, node)
490+
cscfg_reset_feat(feat_csdev);
491+
492+
unlock_exit:
493+
spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
494+
}
495+
EXPORT_SYMBOL_GPL(cscfg_csdev_reset_feats);
496+
497+
/**
498+
* cscfg_activate_config - Mark a configuration descriptor as active.
499+
*
500+
* This will be seen when csdev devices are enabled in the system.
501+
* Only activated configurations can be enabled on individual devices.
502+
* Activation protects the configuration from alteration or removal while
503+
* active.
504+
*
505+
* Selection by hash value - generated from the configuration name when it
506+
* was loaded and added to the cs_etm/configurations file system for selection
507+
* by perf.
508+
*
509+
* Increments the configuration descriptor active count and the global active
510+
* count.
511+
*
512+
* @cfg_hash: Hash value of the selected configuration name.
513+
*/
514+
int cscfg_activate_config(unsigned long cfg_hash)
515+
{
516+
struct cscfg_config_desc *config_desc;
517+
int err = -EINVAL;
518+
519+
mutex_lock(&cscfg_mutex);
520+
521+
list_for_each_entry(config_desc, &cscfg_mgr->config_desc_list, item) {
522+
if ((unsigned long)config_desc->event_ea->var == cfg_hash) {
523+
/*
524+
* increment the global active count - control changes to
525+
* active configurations
526+
*/
527+
atomic_inc(&cscfg_mgr->sys_active_cnt);
528+
529+
/*
530+
* mark the descriptor as active so enable config on a
531+
* device instance will use it
532+
*/
533+
atomic_inc(&config_desc->active_cnt);
534+
535+
err = 0;
536+
dev_dbg(cscfg_device(), "Activate config %s.\n", config_desc->name);
537+
break;
538+
}
539+
}
540+
mutex_unlock(&cscfg_mutex);
541+
542+
return err;
543+
}
544+
EXPORT_SYMBOL_GPL(cscfg_activate_config);
545+
546+
/**
547+
* cscfg_deactivate_config - Mark a config descriptor as inactive.
548+
*
549+
* Decrement the configuration and global active counts.
550+
*
551+
* @cfg_hash: Hash value of the selected configuration name.
552+
*/
553+
void cscfg_deactivate_config(unsigned long cfg_hash)
554+
{
555+
struct cscfg_config_desc *config_desc;
556+
557+
mutex_lock(&cscfg_mutex);
558+
559+
list_for_each_entry(config_desc, &cscfg_mgr->config_desc_list, item) {
560+
if ((unsigned long)config_desc->event_ea->var == cfg_hash) {
561+
atomic_dec(&config_desc->active_cnt);
562+
atomic_dec(&cscfg_mgr->sys_active_cnt);
563+
dev_dbg(cscfg_device(), "Deactivate config %s.\n", config_desc->name);
564+
break;
565+
}
566+
}
567+
mutex_unlock(&cscfg_mutex);
568+
}
569+
EXPORT_SYMBOL_GPL(cscfg_deactivate_config);
570+
571+
/**
572+
* cscfg_csdev_enable_active_config - Enable matching active configuration for device.
573+
*
574+
* Enables the configuration selected by @cfg_hash if the configuration is supported
575+
* on the device and has been activated.
576+
*
577+
* If active and supported the CoreSight device @csdev will be programmed with the
578+
* configuration, using @preset parameters.
579+
*
580+
* Should be called before driver hardware enable for the requested device, prior to
581+
* programming and enabling the physical hardware.
582+
*
583+
* @csdev: CoreSight device to program.
584+
* @cfg_hash: Selector for the configuration.
585+
* @preset: Preset parameter values to use, 0 for current / default values.
586+
*/
587+
int cscfg_csdev_enable_active_config(struct coresight_device *csdev,
588+
unsigned long cfg_hash, int preset)
589+
{
590+
struct cscfg_config_csdev *config_csdev_active = NULL, *config_csdev_item;
591+
const struct cscfg_config_desc *config_desc;
592+
unsigned long flags;
593+
int err = 0;
594+
595+
/* quickly check global count */
596+
if (!atomic_read(&cscfg_mgr->sys_active_cnt))
597+
return 0;
598+
599+
/*
600+
* Look for matching configuration - set the active configuration
601+
* context if found.
602+
*/
603+
spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
604+
list_for_each_entry(config_csdev_item, &csdev->config_csdev_list, node) {
605+
config_desc = config_csdev_item->config_desc;
606+
if ((atomic_read(&config_desc->active_cnt)) &&
607+
((unsigned long)config_desc->event_ea->var == cfg_hash)) {
608+
config_csdev_active = config_csdev_item;
609+
csdev->active_cscfg_ctxt = (void *)config_csdev_active;
610+
break;
611+
}
612+
}
613+
spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
614+
615+
/*
616+
* If found, attempt to enable
617+
*/
618+
if (config_csdev_active) {
619+
/*
620+
* Call the generic routine that will program up the internal
621+
* driver structures prior to programming up the hardware.
622+
* This routine takes the driver spinlock saved in the configs.
623+
*/
624+
err = cscfg_csdev_enable_config(config_csdev_active, preset);
625+
if (!err) {
626+
/*
627+
* Successful programming. Check the active_cscfg_ctxt
628+
* pointer to ensure no pre-emption disabled it via
629+
* cscfg_csdev_disable_active_config() before
630+
* we could start.
631+
*
632+
* Set enabled if OK, err if not.
633+
*/
634+
spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
635+
if (csdev->active_cscfg_ctxt)
636+
config_csdev_active->enabled = true;
637+
else
638+
err = -EBUSY;
639+
spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
640+
}
641+
}
642+
return err;
643+
}
644+
EXPORT_SYMBOL_GPL(cscfg_csdev_enable_active_config);
645+
646+
/**
647+
* cscfg_csdev_disable_active_config - disable an active config on the device.
648+
*
649+
* Disables the active configuration on the CoreSight device @csdev.
650+
* Disable will save the values of any registers marked in the configurations
651+
* as save on disable.
652+
*
653+
* Should be called after driver hardware disable for the requested device,
654+
* after disabling the physical hardware and reading back registers.
655+
*
656+
* @csdev: The CoreSight device.
657+
*/
658+
void cscfg_csdev_disable_active_config(struct coresight_device *csdev)
659+
{
660+
struct cscfg_config_csdev *config_csdev;
661+
unsigned long flags;
662+
663+
/*
664+
* Check if we have an active config, and that it was successfully enabled.
665+
* If it was not enabled, we have no work to do, otherwise mark as disabled.
666+
* Clear the active config pointer.
667+
*/
668+
spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
669+
config_csdev = (struct cscfg_config_csdev *)csdev->active_cscfg_ctxt;
670+
if (config_csdev) {
671+
if (!config_csdev->enabled)
672+
config_csdev = NULL;
673+
else
674+
config_csdev->enabled = false;
675+
}
676+
csdev->active_cscfg_ctxt = NULL;
677+
spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
678+
679+
/* true if there was an enabled active config */
680+
if (config_csdev)
681+
cscfg_csdev_disable_config(config_csdev);
682+
}
683+
EXPORT_SYMBOL_GPL(cscfg_csdev_disable_active_config);
684+
471685
/* Initialise system configuration management device. */
472686

473687
struct device *cscfg_device(void)
@@ -536,6 +750,7 @@ int __init cscfg_init(void)
536750
INIT_LIST_HEAD(&cscfg_mgr->csdev_desc_list);
537751
INIT_LIST_HEAD(&cscfg_mgr->feat_desc_list);
538752
INIT_LIST_HEAD(&cscfg_mgr->config_desc_list);
753+
atomic_set(&cscfg_mgr->sys_active_cnt, 0);
539754

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

drivers/hwtracing/coresight/coresight-syscfg.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,14 @@
2424
* @csdev_desc_list: List of coresight devices registered with the configuration manager.
2525
* @feat_desc_list: List of feature descriptors to load into registered devices.
2626
* @config_desc_list: List of system configuration descriptors to load into registered devices.
27+
* @sys_active_cnt: Total number of active config descriptor references.
2728
*/
2829
struct cscfg_manager {
2930
struct device dev;
3031
struct list_head csdev_desc_list;
3132
struct list_head feat_desc_list;
3233
struct list_head config_desc_list;
34+
atomic_t sys_active_cnt;
3335
};
3436

3537
/* get reference to dev in cscfg_manager */
@@ -61,5 +63,11 @@ int cscfg_load_config_sets(struct cscfg_config_desc **cfg_descs,
6163
int cscfg_register_csdev(struct coresight_device *csdev, u32 match_flags,
6264
struct cscfg_csdev_feat_ops *ops);
6365
void cscfg_unregister_csdev(struct coresight_device *csdev);
66+
int cscfg_activate_config(unsigned long cfg_hash);
67+
void cscfg_deactivate_config(unsigned long cfg_hash);
68+
void cscfg_csdev_reset_feats(struct coresight_device *csdev);
69+
int cscfg_csdev_enable_active_config(struct coresight_device *csdev,
70+
unsigned long cfg_hash, int preset);
71+
void cscfg_csdev_disable_active_config(struct coresight_device *csdev);
6472

6573
#endif /* CORESIGHT_SYSCFG_H */

include/linux/coresight.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,7 @@ struct coresight_sysfs_link {
223223
* @feature_csdev_list: List of complex feature programming added to the device.
224224
* @config_csdev_list: List of system configurations added to the device.
225225
* @cscfg_csdev_lock: Protect the lists of configurations and features.
226+
* @active_cscfg_ctxt: Context information for current active system configuration.
226227
*/
227228
struct coresight_device {
228229
struct coresight_platform_data *pdata;
@@ -248,6 +249,7 @@ struct coresight_device {
248249
struct list_head feature_csdev_list;
249250
struct list_head config_csdev_list;
250251
spinlock_t cscfg_csdev_lock;
252+
void *active_cscfg_ctxt;
251253
};
252254

253255
/*

0 commit comments

Comments
 (0)