coresight: Add generic sysfs link creation functions
To allow the connections between coresight components to be represented in sysfs, generic methods for creating sysfs links between two coresight devices are added. Signed-off-by: Mike Leach <mike.leach@linaro.org> Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com> Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org> Link: https://lore.kernel.org/r/20200518180242.7916-4-mathieu.poirier@linaro.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
68a5d5fccb
commit
8096152588
|
@ -2,7 +2,8 @@
|
|||
#
|
||||
# Makefile for CoreSight drivers.
|
||||
#
|
||||
obj-$(CONFIG_CORESIGHT) += coresight.o coresight-etm-perf.o coresight-platform.o
|
||||
obj-$(CONFIG_CORESIGHT) += coresight.o coresight-etm-perf.o \
|
||||
coresight-platform.o coresight-sysfs.o
|
||||
obj-$(CONFIG_CORESIGHT_LINK_AND_SINK_TMC) += coresight-tmc.o \
|
||||
coresight-tmc-etf.o \
|
||||
coresight-tmc-etr.o
|
||||
|
|
|
@ -153,6 +153,10 @@ struct coresight_device *coresight_get_sink_by_id(u32 id);
|
|||
struct list_head *coresight_build_path(struct coresight_device *csdev,
|
||||
struct coresight_device *sink);
|
||||
void coresight_release_path(struct list_head *path);
|
||||
int coresight_add_sysfs_link(struct coresight_sysfs_link *info);
|
||||
void coresight_remove_sysfs_link(struct coresight_sysfs_link *info);
|
||||
int coresight_create_conns_sysfs_group(struct coresight_device *csdev);
|
||||
void coresight_remove_conns_sysfs_group(struct coresight_device *csdev);
|
||||
|
||||
#ifdef CONFIG_CORESIGHT_SOURCE_ETM3X
|
||||
extern int etm_readl_cp14(u32 off, unsigned int *val);
|
||||
|
|
124
drivers/hwtracing/coresight/coresight-sysfs.c
Normal file
124
drivers/hwtracing/coresight/coresight-sysfs.c
Normal file
|
@ -0,0 +1,124 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (c) 2019, Linaro Limited, All rights reserved.
|
||||
* Author: Mike Leach <mike.leach@linaro.org>
|
||||
*/
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/kernel.h>
|
||||
|
||||
#include "coresight-priv.h"
|
||||
|
||||
/*
|
||||
* Connections group - links attribute.
|
||||
* Count of created links between coresight components in the group.
|
||||
*/
|
||||
static ssize_t nr_links_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct coresight_device *csdev = to_coresight_device(dev);
|
||||
|
||||
return sprintf(buf, "%d\n", csdev->nr_links);
|
||||
}
|
||||
static DEVICE_ATTR_RO(nr_links);
|
||||
|
||||
static struct attribute *coresight_conns_attrs[] = {
|
||||
&dev_attr_nr_links.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct attribute_group coresight_conns_group = {
|
||||
.attrs = coresight_conns_attrs,
|
||||
.name = "connections",
|
||||
};
|
||||
|
||||
/*
|
||||
* Create connections group for CoreSight devices.
|
||||
* This group will then be used to collate the sysfs links between
|
||||
* devices.
|
||||
*/
|
||||
int coresight_create_conns_sysfs_group(struct coresight_device *csdev)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (!csdev)
|
||||
return -EINVAL;
|
||||
|
||||
ret = sysfs_create_group(&csdev->dev.kobj, &coresight_conns_group);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
csdev->has_conns_grp = true;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void coresight_remove_conns_sysfs_group(struct coresight_device *csdev)
|
||||
{
|
||||
if (!csdev)
|
||||
return;
|
||||
|
||||
if (csdev->has_conns_grp) {
|
||||
sysfs_remove_group(&csdev->dev.kobj, &coresight_conns_group);
|
||||
csdev->has_conns_grp = false;
|
||||
}
|
||||
}
|
||||
|
||||
int coresight_add_sysfs_link(struct coresight_sysfs_link *info)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (!info)
|
||||
return -EINVAL;
|
||||
if (!info->orig || !info->target ||
|
||||
!info->orig_name || !info->target_name)
|
||||
return -EINVAL;
|
||||
if (!info->orig->has_conns_grp || !info->target->has_conns_grp)
|
||||
return -EINVAL;
|
||||
|
||||
/* first link orig->target */
|
||||
ret = sysfs_add_link_to_group(&info->orig->dev.kobj,
|
||||
coresight_conns_group.name,
|
||||
&info->target->dev.kobj,
|
||||
info->orig_name);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* second link target->orig */
|
||||
ret = sysfs_add_link_to_group(&info->target->dev.kobj,
|
||||
coresight_conns_group.name,
|
||||
&info->orig->dev.kobj,
|
||||
info->target_name);
|
||||
|
||||
/* error in second link - remove first - otherwise inc counts */
|
||||
if (ret) {
|
||||
sysfs_remove_link_from_group(&info->orig->dev.kobj,
|
||||
coresight_conns_group.name,
|
||||
info->orig_name);
|
||||
} else {
|
||||
info->orig->nr_links++;
|
||||
info->target->nr_links++;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void coresight_remove_sysfs_link(struct coresight_sysfs_link *info)
|
||||
{
|
||||
if (!info)
|
||||
return;
|
||||
if (!info->orig || !info->target ||
|
||||
!info->orig_name || !info->target_name)
|
||||
return;
|
||||
|
||||
sysfs_remove_link_from_group(&info->orig->dev.kobj,
|
||||
coresight_conns_group.name,
|
||||
info->orig_name);
|
||||
|
||||
sysfs_remove_link_from_group(&info->target->dev.kobj,
|
||||
coresight_conns_group.name,
|
||||
info->target_name);
|
||||
|
||||
info->orig->nr_links--;
|
||||
info->target->nr_links--;
|
||||
}
|
|
@ -148,6 +148,20 @@ struct coresight_connection {
|
|||
struct coresight_device *child_dev;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct coresight_sysfs_link - representation of a connection in sysfs.
|
||||
* @orig: Originating (master) coresight device for the link.
|
||||
* @orig_name: Name to use for the link orig->target.
|
||||
* @target: Target (slave) coresight device for the link.
|
||||
* @target_name: Name to use for the link target->orig.
|
||||
*/
|
||||
struct coresight_sysfs_link {
|
||||
struct coresight_device *orig;
|
||||
const char *orig_name;
|
||||
struct coresight_device *target;
|
||||
const char *target_name;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct coresight_device - representation of a device as used by the framework
|
||||
* @pdata: Platform data with device connections associated to this device.
|
||||
|
@ -165,6 +179,9 @@ struct coresight_connection {
|
|||
* @ea: Device attribute for sink representation under PMU directory.
|
||||
* @ect_dev: Associated cross trigger device. Not part of the trace data
|
||||
* path or connections.
|
||||
* @nr_links: number of sysfs links created to other components from this
|
||||
* device. These will appear in the "connections" group.
|
||||
* @has_conns_grp: Have added a "connections" group for sysfs links.
|
||||
*/
|
||||
struct coresight_device {
|
||||
struct coresight_platform_data *pdata;
|
||||
|
@ -180,6 +197,9 @@ struct coresight_device {
|
|||
struct dev_ext_attribute *ea;
|
||||
/* cross trigger handling */
|
||||
struct coresight_device *ect_dev;
|
||||
/* sysfs links between components */
|
||||
int nr_links;
|
||||
bool has_conns_grp;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in a new issue