mirror of
https://github.com/torvalds/linux.git
synced 2026-07-31 11:37:06 +02:00
coresight: funnel: add support for multiple output ports
Funnel devices are now capable of supporting multiple-inputs and multiple-outputs configuration with in built hardware filtering for TPDM devices. Add software support to this function. Output ports is selected according to the source of the trace path. Change-Id: I491293e0b1948f3747d34eb79e7845617ace4244 Signed-off-by: Tingwei Zhang <tingwei@codeaurora.org> Signed-off-by: Mao Jinlong <jinlmao@codeaurora.org> Signed-off-by: Tao Zhang <taozha@codeaurora.org> Signed-off-by: Mao Jinlong <quic_jinlmao@quicinc.com>
This commit is contained in:
parent
03de227439
commit
9f74beac0a
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (c) 2012, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2012, 2020-2021 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
|
|
@ -60,6 +60,8 @@ static LIST_HEAD(cs_active_paths);
|
|||
const u32 coresight_barrier_pkt[4] = {0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff};
|
||||
EXPORT_SYMBOL_GPL(coresight_barrier_pkt);
|
||||
|
||||
static struct coresight_device *coresight_get_source(struct list_head *path);
|
||||
|
||||
static const struct cti_assoc_op *cti_assoc_ops;
|
||||
|
||||
static const struct csr_set_atid_op *csr_set_atid_ops;
|
||||
|
|
@ -139,6 +141,31 @@ static int coresight_source_is_unique(struct coresight_device *csdev)
|
|||
csdev, coresight_id_match);
|
||||
}
|
||||
|
||||
/**
|
||||
* coresight_source_filter - checks whether the connection matches the source
|
||||
* of path if connection is binded to specific source.
|
||||
* @path: The list of devices
|
||||
* @conn: The connection of one outport
|
||||
*
|
||||
* Return zero if the connection doesn't have a source binded or source of the
|
||||
* path matches the source binds to connection.
|
||||
*/
|
||||
static int coresight_source_filter(struct list_head *path,
|
||||
struct coresight_connection *conn)
|
||||
{
|
||||
int ret = 0;
|
||||
struct coresight_device *source = NULL;
|
||||
|
||||
if (conn->source_name == NULL)
|
||||
return ret;
|
||||
|
||||
source = coresight_get_source(path);
|
||||
if (source == NULL)
|
||||
return ret;
|
||||
|
||||
return strcmp(conn->source_name, dev_name(&source->dev));
|
||||
}
|
||||
|
||||
static int coresight_reset_sink(struct device *dev, void *data)
|
||||
{
|
||||
struct coresight_device *csdev = to_coresight_device(dev);
|
||||
|
|
@ -157,13 +184,16 @@ static void coresight_reset_all_sink(void)
|
|||
}
|
||||
|
||||
static int coresight_find_link_inport(struct coresight_device *csdev,
|
||||
struct coresight_device *parent)
|
||||
struct coresight_device *parent,
|
||||
struct list_head *path)
|
||||
{
|
||||
int i;
|
||||
struct coresight_connection *conn;
|
||||
|
||||
for (i = 0; i < parent->pdata->nr_outport; i++) {
|
||||
conn = &parent->pdata->conns[i];
|
||||
if (coresight_source_filter(path, conn))
|
||||
continue;
|
||||
if (conn->child_dev == csdev)
|
||||
return conn->child_port;
|
||||
}
|
||||
|
|
@ -175,13 +205,16 @@ static int coresight_find_link_inport(struct coresight_device *csdev,
|
|||
}
|
||||
|
||||
static int coresight_find_link_outport(struct coresight_device *csdev,
|
||||
struct coresight_device *child)
|
||||
struct coresight_device *child,
|
||||
struct list_head *path)
|
||||
{
|
||||
int i;
|
||||
struct coresight_connection *conn;
|
||||
|
||||
for (i = 0; i < csdev->pdata->nr_outport; i++) {
|
||||
conn = &csdev->pdata->conns[i];
|
||||
if (coresight_source_filter(path, conn))
|
||||
continue;
|
||||
if (conn->child_dev == child)
|
||||
return conn->outport;
|
||||
}
|
||||
|
|
@ -393,7 +426,8 @@ static void coresight_disable_sink(struct coresight_device *csdev)
|
|||
|
||||
static int coresight_enable_link(struct coresight_device *csdev,
|
||||
struct coresight_device *parent,
|
||||
struct coresight_device *child)
|
||||
struct coresight_device *child,
|
||||
struct list_head *path)
|
||||
{
|
||||
int ret = 0;
|
||||
int link_subtype;
|
||||
|
|
@ -402,8 +436,8 @@ static int coresight_enable_link(struct coresight_device *csdev,
|
|||
if (!parent || !child)
|
||||
return -EINVAL;
|
||||
|
||||
inport = coresight_find_link_inport(csdev, parent);
|
||||
outport = coresight_find_link_outport(csdev, child);
|
||||
inport = coresight_find_link_inport(csdev, parent, path);
|
||||
outport = coresight_find_link_outport(csdev, child, path);
|
||||
link_subtype = csdev->subtype.link_subtype;
|
||||
|
||||
if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_MERG && inport < 0)
|
||||
|
|
@ -428,7 +462,8 @@ static int coresight_enable_link(struct coresight_device *csdev,
|
|||
|
||||
static void coresight_disable_link(struct coresight_device *csdev,
|
||||
struct coresight_device *parent,
|
||||
struct coresight_device *child)
|
||||
struct coresight_device *child,
|
||||
struct list_head *path)
|
||||
{
|
||||
int i, nr_conns;
|
||||
int link_subtype;
|
||||
|
|
@ -437,8 +472,8 @@ static void coresight_disable_link(struct coresight_device *csdev,
|
|||
if (!parent || !child)
|
||||
return;
|
||||
|
||||
inport = coresight_find_link_inport(csdev, parent);
|
||||
outport = coresight_find_link_outport(csdev, child);
|
||||
inport = coresight_find_link_inport(csdev, parent, path);
|
||||
outport = coresight_find_link_outport(csdev, child, path);
|
||||
link_subtype = csdev->subtype.link_subtype;
|
||||
|
||||
if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_MERG) {
|
||||
|
|
@ -592,7 +627,7 @@ static void coresight_disable_path_from(struct list_head *path,
|
|||
case CORESIGHT_DEV_TYPE_LINK:
|
||||
parent = list_prev_entry(nd, link)->csdev;
|
||||
child = list_next_entry(nd, link)->csdev;
|
||||
coresight_disable_link(csdev, parent, child);
|
||||
coresight_disable_link(csdev, parent, child, path);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
@ -654,7 +689,7 @@ int coresight_enable_path(struct list_head *path, u32 mode, void *sink_data)
|
|||
case CORESIGHT_DEV_TYPE_LINK:
|
||||
parent = list_prev_entry(nd, link)->csdev;
|
||||
child = list_next_entry(nd, link)->csdev;
|
||||
ret = coresight_enable_link(csdev, parent, child);
|
||||
ret = coresight_enable_link(csdev, parent, child, path);
|
||||
if (ret)
|
||||
goto err;
|
||||
break;
|
||||
|
|
@ -928,7 +963,8 @@ static void coresight_drop_device(struct coresight_device *csdev)
|
|||
*/
|
||||
static int _coresight_build_path(struct coresight_device *csdev,
|
||||
struct coresight_device *sink,
|
||||
struct list_head *path)
|
||||
struct list_head *path,
|
||||
struct coresight_device *source)
|
||||
{
|
||||
int i, ret;
|
||||
bool found = false;
|
||||
|
|
@ -940,7 +976,7 @@ static int _coresight_build_path(struct coresight_device *csdev,
|
|||
|
||||
if (coresight_is_percpu_source(csdev) && coresight_is_percpu_sink(sink) &&
|
||||
sink == per_cpu(csdev_sink, source_ops(csdev)->cpu_id(csdev))) {
|
||||
if (_coresight_build_path(sink, sink, path) == 0) {
|
||||
if (_coresight_build_path(sink, sink, path, source) == 0) {
|
||||
found = true;
|
||||
goto out;
|
||||
}
|
||||
|
|
@ -951,8 +987,12 @@ static int _coresight_build_path(struct coresight_device *csdev,
|
|||
struct coresight_device *child_dev;
|
||||
|
||||
child_dev = csdev->pdata->conns[i].child_dev;
|
||||
if (csdev->pdata->conns[i].source_name &&
|
||||
strcmp(csdev->pdata->conns[i].source_name,
|
||||
dev_name(&source->dev)))
|
||||
continue;
|
||||
if (child_dev &&
|
||||
_coresight_build_path(child_dev, sink, path) == 0) {
|
||||
_coresight_build_path(child_dev, sink, path, source) == 0) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
|
@ -997,7 +1037,7 @@ struct list_head *coresight_build_path(struct coresight_device *source,
|
|||
|
||||
INIT_LIST_HEAD(path);
|
||||
|
||||
rc = _coresight_build_path(source, sink, path);
|
||||
rc = _coresight_build_path(source, sink, path, source);
|
||||
if (rc) {
|
||||
kfree(path);
|
||||
return ERR_PTR(rc);
|
||||
|
|
|
|||
|
|
@ -235,6 +235,7 @@ static int of_coresight_parse_endpoint(struct device *dev,
|
|||
struct device *rdev = NULL;
|
||||
struct fwnode_handle *rdev_fwnode;
|
||||
struct coresight_connection *conn;
|
||||
struct device_node *sn = NULL;
|
||||
|
||||
do {
|
||||
/* Parse the local port details */
|
||||
|
|
@ -279,6 +280,13 @@ static int of_coresight_parse_endpoint(struct device *dev,
|
|||
*/
|
||||
conn->child_fwnode = fwnode_handle_get(rdev_fwnode);
|
||||
conn->child_port = rendpoint.port;
|
||||
conn->source_name = NULL;
|
||||
sn = of_parse_phandle(ep, "source", 0);
|
||||
if (sn) {
|
||||
ret = of_property_read_string(sn,
|
||||
"coresight-name", &conn->source_name);
|
||||
of_node_put(sn);
|
||||
}
|
||||
/* Connection record updated */
|
||||
} while (0);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (c) 2012, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2012, 2020-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_CORESIGHT_H
|
||||
|
|
@ -165,6 +165,7 @@ struct coresight_desc {
|
|||
* struct coresight_connection - representation of a single connection
|
||||
* @outport: a connection's output port number.
|
||||
* @child_port: remote component's port number @output is connected to.
|
||||
* @source_name: source component's name.
|
||||
* @chid_fwnode: remote component's fwnode handle.
|
||||
* @child_dev: a @coresight_device representation of the component
|
||||
connected to @outport.
|
||||
|
|
@ -173,6 +174,7 @@ struct coresight_desc {
|
|||
struct coresight_connection {
|
||||
int outport;
|
||||
int child_port;
|
||||
const char *source_name;
|
||||
struct fwnode_handle *child_fwnode;
|
||||
struct coresight_device *child_dev;
|
||||
struct coresight_sysfs_link *link;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user