From 704faaf4e33ca0bd9caa1e06c379c32a13d8c3f2 Mon Sep 17 00:00:00 2001 From: James Clark Date: Tue, 25 Apr 2023 15:35:30 +0100 Subject: coresight: Change name of pdata->conns conns is actually for output connections. Change the name to make it clearer and so that we can add input connections later. No functional changes. Reviewed-by: Mike Leach Signed-off-by: James Clark Signed-off-by: Suzuki K Poulose Link: https://lore.kernel.org/r/20230425143542.2305069-4-james.clark@arm.com --- drivers/hwtracing/coresight/coresight-platform.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers/hwtracing/coresight/coresight-platform.c') diff --git a/drivers/hwtracing/coresight/coresight-platform.c b/drivers/hwtracing/coresight/coresight-platform.c index 475899714104..5085525a32bb 100644 --- a/drivers/hwtracing/coresight/coresight-platform.c +++ b/drivers/hwtracing/coresight/coresight-platform.c @@ -27,9 +27,9 @@ static int coresight_alloc_conns(struct device *dev, struct coresight_platform_data *pdata) { if (pdata->nr_outport) { - pdata->conns = devm_kcalloc(dev, pdata->nr_outport, - sizeof(*pdata->conns), GFP_KERNEL); - if (!pdata->conns) + pdata->out_conns = devm_kcalloc(dev, pdata->nr_outport, + sizeof(*pdata->out_conns), GFP_KERNEL); + if (!pdata->out_conns) return -ENOMEM; } @@ -251,7 +251,7 @@ static int of_coresight_parse_endpoint(struct device *dev, break; } - conn = &pdata->conns[endpoint.port]; + conn = &pdata->out_conns[endpoint.port]; if (conn->child_fwnode) { dev_warn(dev, "Duplicate output port %d\n", endpoint.port); @@ -744,8 +744,8 @@ static int acpi_coresight_parse_graph(struct acpi_device *adev, int port = conns[i].outport; /* Duplicate output port */ - WARN_ON(pdata->conns[port].child_fwnode); - pdata->conns[port] = conns[i]; + WARN_ON(pdata->out_conns[port].child_fwnode); + pdata->out_conns[port] = conns[i]; } devm_kfree(&adev->dev, conns); -- cgit v1.2.3 From 81d0ea763d8a1089749a9b671a730cef6cc5c5d7 Mon Sep 17 00:00:00 2001 From: James Clark Date: Tue, 25 Apr 2023 15:35:31 +0100 Subject: coresight: Rename nr_outports to nr_outconns Rename to avoid confusion between port number and the index in the connection array. The port number is already stored in the connection, and in a later commit the connection array will be appended to, so the length of it will no longer reflect the number of ports. No functional changes. Reviewed-by: Mike Leach Signed-off-by: James Clark Signed-off-by: Suzuki K Poulose Link: https://lore.kernel.org/r/20230425143542.2305069-5-james.clark@arm.com --- drivers/hwtracing/coresight/coresight-core.c | 32 +++++++++++----------- drivers/hwtracing/coresight/coresight-platform.c | 34 ++++++++++++------------ drivers/hwtracing/coresight/coresight-tmc-etr.c | 2 +- include/linux/coresight.h | 10 +++---- 4 files changed, 39 insertions(+), 39 deletions(-) (limited to 'drivers/hwtracing/coresight/coresight-platform.c') diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c index 04c9d52f8f4f..0f6712a6fba3 100644 --- a/drivers/hwtracing/coresight/coresight-core.c +++ b/drivers/hwtracing/coresight/coresight-core.c @@ -118,7 +118,7 @@ static int coresight_find_link_inport(struct coresight_device *csdev, int i; struct coresight_connection *conn; - for (i = 0; i < parent->pdata->nr_outport; i++) { + for (i = 0; i < parent->pdata->nr_outconns; i++) { conn = &parent->pdata->out_conns[i]; if (conn->child_dev == csdev) return conn->child_port; @@ -136,7 +136,7 @@ static int coresight_find_link_outport(struct coresight_device *csdev, int i; struct coresight_connection *conn; - for (i = 0; i < csdev->pdata->nr_outport; i++) { + for (i = 0; i < csdev->pdata->nr_outconns; i++) { conn = &csdev->pdata->out_conns[i]; if (conn->child_dev == child) return conn->outport; @@ -397,9 +397,9 @@ static void coresight_disable_link(struct coresight_device *csdev, link_subtype = csdev->subtype.link_subtype; if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_MERG) { - nr_conns = csdev->pdata->nr_inport; + nr_conns = csdev->pdata->nr_inconns; } else if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_SPLIT) { - nr_conns = csdev->pdata->nr_outport; + nr_conns = csdev->pdata->nr_outconns; } else { nr_conns = 1; } @@ -603,7 +603,7 @@ coresight_find_enabled_sink(struct coresight_device *csdev) /* * Recursively explore each port found on this element. */ - for (i = 0; i < csdev->pdata->nr_outport; i++) { + for (i = 0; i < csdev->pdata->nr_outconns; i++) { struct coresight_device *child_dev; child_dev = csdev->pdata->out_conns[i].child_dev; @@ -719,7 +719,7 @@ static int coresight_grab_device(struct coresight_device *csdev) { int i; - for (i = 0; i < csdev->pdata->nr_outport; i++) { + for (i = 0; i < csdev->pdata->nr_outconns; i++) { struct coresight_device *child; child = csdev->pdata->out_conns[i].child_dev; @@ -749,7 +749,7 @@ static void coresight_drop_device(struct coresight_device *csdev) int i; coresight_put_ref(csdev); - for (i = 0; i < csdev->pdata->nr_outport; i++) { + for (i = 0; i < csdev->pdata->nr_outconns; i++) { struct coresight_device *child; child = csdev->pdata->out_conns[i].child_dev; @@ -791,7 +791,7 @@ static int _coresight_build_path(struct coresight_device *csdev, } /* Not a sink - recursively explore each port found on this element */ - for (i = 0; i < csdev->pdata->nr_outport; i++) { + for (i = 0; i < csdev->pdata->nr_outconns; i++) { struct coresight_device *child_dev; child_dev = csdev->pdata->out_conns[i].child_dev; @@ -960,7 +960,7 @@ coresight_find_sink(struct coresight_device *csdev, int *depth) * Not a sink we want - or possible child sink may be better. * recursively explore each port found on this element. */ - for (i = 0; i < csdev->pdata->nr_outport; i++) { + for (i = 0; i < csdev->pdata->nr_outconns; i++) { struct coresight_device *child_dev, *sink = NULL; int child_depth = curr_depth; @@ -1333,7 +1333,7 @@ static int coresight_orphan_match(struct device *dev, void *data) * Circle throuch all the connection of that component. If we find * an orphan connection whose name matches @csdev, link it. */ - for (i = 0; i < i_csdev->pdata->nr_outport; i++) { + for (i = 0; i < i_csdev->pdata->nr_outconns; i++) { conn = &i_csdev->pdata->out_conns[i]; /* Skip the port if FW doesn't describe it */ @@ -1374,7 +1374,7 @@ static int coresight_fixup_device_conns(struct coresight_device *csdev) { int i, ret = 0; - for (i = 0; i < csdev->pdata->nr_outport; i++) { + for (i = 0; i < csdev->pdata->nr_outconns; i++) { struct coresight_connection *conn = &csdev->pdata->out_conns[i]; if (!conn->child_fwnode) @@ -1411,7 +1411,7 @@ static int coresight_remove_match(struct device *dev, void *data) * Circle throuch all the connection of that component. If we find * a connection whose name matches @csdev, remove it. */ - for (i = 0; i < iterator->pdata->nr_outport; i++) { + for (i = 0; i < iterator->pdata->nr_outconns; i++) { conn = &iterator->pdata->out_conns[i]; if (conn->child_dev == NULL || conn->child_fwnode == NULL) @@ -1446,7 +1446,7 @@ static void coresight_remove_conns(struct coresight_device *csdev) * doesn't have at least one input port, there is no point * in searching all the devices. */ - if (csdev->pdata->nr_inport) + if (csdev->pdata->nr_inconns) bus_for_each_dev(&coresight_bustype, NULL, csdev, coresight_remove_match); } @@ -1545,7 +1545,7 @@ void coresight_release_platform_data(struct coresight_device *csdev, int i; struct coresight_connection *conns = pdata->out_conns; - for (i = 0; i < pdata->nr_outport; i++) { + for (i = 0; i < pdata->nr_outconns; i++) { /* If we have made the links, remove them now */ if (csdev && conns[i].child_dev) coresight_remove_links(csdev, &conns[i]); @@ -1582,9 +1582,9 @@ struct coresight_device *coresight_register(struct coresight_desc *desc) link_subtype = desc->subtype.link_subtype; if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_MERG) - nr_refcnts = desc->pdata->nr_inport; + nr_refcnts = desc->pdata->nr_inconns; else if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_SPLIT) - nr_refcnts = desc->pdata->nr_outport; + nr_refcnts = desc->pdata->nr_outconns; } refcnts = kcalloc(nr_refcnts, sizeof(*refcnts), GFP_KERNEL); diff --git a/drivers/hwtracing/coresight/coresight-platform.c b/drivers/hwtracing/coresight/coresight-platform.c index 5085525a32bb..ed865e0621a9 100644 --- a/drivers/hwtracing/coresight/coresight-platform.c +++ b/drivers/hwtracing/coresight/coresight-platform.c @@ -26,8 +26,8 @@ static int coresight_alloc_conns(struct device *dev, struct coresight_platform_data *pdata) { - if (pdata->nr_outport) { - pdata->out_conns = devm_kcalloc(dev, pdata->nr_outport, + if (pdata->nr_outconns) { + pdata->out_conns = devm_kcalloc(dev, pdata->nr_outconns, sizeof(*pdata->out_conns), GFP_KERNEL); if (!pdata->out_conns) return -ENOMEM; @@ -84,7 +84,7 @@ static inline bool of_coresight_legacy_ep_is_input(struct device_node *ep) } static void of_coresight_get_ports_legacy(const struct device_node *node, - int *nr_inport, int *nr_outport) + int *nr_inconns, int *nr_outconns) { struct device_node *ep = NULL; struct of_endpoint endpoint; @@ -114,8 +114,8 @@ static void of_coresight_get_ports_legacy(const struct device_node *node, } while (ep); - *nr_inport = in; - *nr_outport = out; + *nr_inconns = in; + *nr_outconns = out; } static struct device_node *of_coresight_get_port_parent(struct device_node *ep) @@ -164,7 +164,7 @@ of_coresight_count_ports(struct device_node *port_parent) } static void of_coresight_get_ports(const struct device_node *node, - int *nr_inport, int *nr_outport) + int *nr_inconns, int *nr_outconns) { struct device_node *input_ports = NULL, *output_ports = NULL; @@ -173,16 +173,16 @@ static void of_coresight_get_ports(const struct device_node *node, if (input_ports || output_ports) { if (input_ports) { - *nr_inport = of_coresight_count_ports(input_ports); + *nr_inconns = of_coresight_count_ports(input_ports); of_node_put(input_ports); } if (output_ports) { - *nr_outport = of_coresight_count_ports(output_ports); + *nr_outconns = of_coresight_count_ports(output_ports); of_node_put(output_ports); } } else { /* Fall back to legacy DT bindings parsing */ - of_coresight_get_ports_legacy(node, nr_inport, nr_outport); + of_coresight_get_ports_legacy(node, nr_inconns, nr_outconns); } } @@ -289,10 +289,10 @@ static int of_get_coresight_platform_data(struct device *dev, struct device_node *node = dev->of_node; /* Get the number of input and output port for this component */ - of_coresight_get_ports(node, &pdata->nr_inport, &pdata->nr_outport); + of_coresight_get_ports(node, &pdata->nr_inconns, &pdata->nr_outconns); /* If there are no output connections, we are done */ - if (!pdata->nr_outport) + if (!pdata->nr_outconns) return 0; ret = coresight_alloc_conns(dev, pdata); @@ -690,7 +690,7 @@ static int acpi_coresight_parse_graph(struct acpi_device *adev, const union acpi_object *graph; struct coresight_connection *conns, *ptr; - pdata->nr_inport = pdata->nr_outport = 0; + pdata->nr_inconns = pdata->nr_outconns = 0; graph = acpi_get_coresight_graph(adev); if (!graph) return -ENOENT; @@ -718,11 +718,11 @@ static int acpi_coresight_parse_graph(struct acpi_device *adev, return dir; if (dir == ACPI_CORESIGHT_LINK_MASTER) { - if (ptr->outport >= pdata->nr_outport) - pdata->nr_outport = ptr->outport + 1; + if (ptr->outport >= pdata->nr_outconns) + pdata->nr_outconns = ptr->outport + 1; ptr++; } else { - WARN_ON(pdata->nr_inport == ptr->child_port + 1); + WARN_ON(pdata->nr_inconns == ptr->child_port + 1); /* * We do not track input port connections for a device. * However we need the highest port number described, @@ -730,8 +730,8 @@ static int acpi_coresight_parse_graph(struct acpi_device *adev, * record for an output connection. Hence, do not move * the ptr for input connections */ - if (ptr->child_port >= pdata->nr_inport) - pdata->nr_inport = ptr->child_port + 1; + if (ptr->child_port >= pdata->nr_inconns) + pdata->nr_inconns = ptr->child_port + 1; } } diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c index a16f32d80ae2..32137b78eca2 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c @@ -781,7 +781,7 @@ tmc_etr_get_catu_device(struct tmc_drvdata *drvdata) if (!IS_ENABLED(CONFIG_CORESIGHT_CATU)) return NULL; - for (i = 0; i < etr->pdata->nr_outport; i++) { + for (i = 0; i < etr->pdata->nr_outconns; i++) { tmp = etr->pdata->out_conns[i].child_dev; if (tmp && coresight_is_catu_device(tmp)) return tmp; diff --git a/include/linux/coresight.h b/include/linux/coresight.h index bf621d064ef8..daf392fcb67a 100644 --- a/include/linux/coresight.h +++ b/include/linux/coresight.h @@ -102,13 +102,13 @@ union coresight_dev_subtype { * struct coresight_platform_data - data harvested from the firmware * specification. * - * @nr_inport: Number of elements for the input connections. - * @nr_outport: Number of elements for the output connections. - * @out_conns: Sparse array of nr_outport connections from this component. + * @nr_inconns: Number of elements for the input connections. + * @nr_outconns: Number of elements for the output connections. + * @out_conns: Sparse array of nr_outconns connections from this component. */ struct coresight_platform_data { - int nr_inport; - int nr_outport; + int nr_inconns; + int nr_outconns; struct coresight_connection *out_conns; }; -- cgit v1.2.3 From d49c9cf15f89cdd77f3ce3f0187fa1cfbdea28f5 Mon Sep 17 00:00:00 2001 From: James Clark Date: Tue, 25 Apr 2023 15:35:32 +0100 Subject: coresight: Rename connection members to make the direction explicit When input connections are added they will use the same connection object as the output so parent and child could be misinterpreted. Making the direction unambiguous in the names should improve readability. Reviewed-by: Mike Leach Signed-off-by: James Clark Signed-off-by: Suzuki K Poulose Link: https://lore.kernel.org/r/20230425143542.2305069-6-james.clark@arm.com --- drivers/hwtracing/coresight/coresight-core.c | 51 ++++++++++++------------ drivers/hwtracing/coresight/coresight-platform.c | 30 +++++++------- drivers/hwtracing/coresight/coresight-sysfs.c | 10 ++--- drivers/hwtracing/coresight/coresight-tmc-etr.c | 2 +- include/linux/coresight.h | 18 ++++----- 5 files changed, 55 insertions(+), 56 deletions(-) (limited to 'drivers/hwtracing/coresight/coresight-platform.c') diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c index 0f6712a6fba3..f3dc320b374c 100644 --- a/drivers/hwtracing/coresight/coresight-core.c +++ b/drivers/hwtracing/coresight/coresight-core.c @@ -120,8 +120,8 @@ static int coresight_find_link_inport(struct coresight_device *csdev, for (i = 0; i < parent->pdata->nr_outconns; i++) { conn = &parent->pdata->out_conns[i]; - if (conn->child_dev == csdev) - return conn->child_port; + if (conn->dest_dev == csdev) + return conn->dest_port; } dev_err(&csdev->dev, "couldn't find inport, parent: %s, child: %s\n", @@ -138,8 +138,8 @@ static int coresight_find_link_outport(struct coresight_device *csdev, for (i = 0; i < csdev->pdata->nr_outconns; i++) { conn = &csdev->pdata->out_conns[i]; - if (conn->child_dev == child) - return conn->outport; + if (conn->dest_dev == child) + return conn->src_port; } dev_err(&csdev->dev, "couldn't find outport, parent: %s, child: %s\n", @@ -606,7 +606,7 @@ coresight_find_enabled_sink(struct coresight_device *csdev) for (i = 0; i < csdev->pdata->nr_outconns; i++) { struct coresight_device *child_dev; - child_dev = csdev->pdata->out_conns[i].child_dev; + child_dev = csdev->pdata->out_conns[i].dest_dev; if (child_dev) sink = coresight_find_enabled_sink(child_dev); if (sink) @@ -722,7 +722,7 @@ static int coresight_grab_device(struct coresight_device *csdev) for (i = 0; i < csdev->pdata->nr_outconns; i++) { struct coresight_device *child; - child = csdev->pdata->out_conns[i].child_dev; + child = csdev->pdata->out_conns[i].dest_dev; if (child && child->type == CORESIGHT_DEV_TYPE_HELPER) if (!coresight_get_ref(child)) goto err; @@ -733,7 +733,7 @@ err: for (i--; i >= 0; i--) { struct coresight_device *child; - child = csdev->pdata->out_conns[i].child_dev; + child = csdev->pdata->out_conns[i].dest_dev; if (child && child->type == CORESIGHT_DEV_TYPE_HELPER) coresight_put_ref(child); } @@ -752,7 +752,7 @@ static void coresight_drop_device(struct coresight_device *csdev) for (i = 0; i < csdev->pdata->nr_outconns; i++) { struct coresight_device *child; - child = csdev->pdata->out_conns[i].child_dev; + child = csdev->pdata->out_conns[i].dest_dev; if (child && child->type == CORESIGHT_DEV_TYPE_HELPER) coresight_put_ref(child); } @@ -794,7 +794,7 @@ static int _coresight_build_path(struct coresight_device *csdev, for (i = 0; i < csdev->pdata->nr_outconns; i++) { struct coresight_device *child_dev; - child_dev = csdev->pdata->out_conns[i].child_dev; + child_dev = csdev->pdata->out_conns[i].dest_dev; if (child_dev && _coresight_build_path(child_dev, sink, path) == 0) { found = true; @@ -964,7 +964,7 @@ coresight_find_sink(struct coresight_device *csdev, int *depth) struct coresight_device *child_dev, *sink = NULL; int child_depth = curr_depth; - child_dev = csdev->pdata->out_conns[i].child_dev; + child_dev = csdev->pdata->out_conns[i].dest_dev; if (child_dev) sink = coresight_find_sink(child_dev, &child_depth); @@ -1337,12 +1337,12 @@ static int coresight_orphan_match(struct device *dev, void *data) conn = &i_csdev->pdata->out_conns[i]; /* Skip the port if FW doesn't describe it */ - if (!conn->child_fwnode) + if (!conn->dest_fwnode) continue; /* We have found at least one orphan connection */ - if (conn->child_dev == NULL) { + if (conn->dest_dev == NULL) { /* Does it match this newly added device? */ - if (conn->child_fwnode == csdev->dev.fwnode) { + if (conn->dest_fwnode == csdev->dev.fwnode) { ret = coresight_make_links(i_csdev, conn, csdev); if (ret) @@ -1377,13 +1377,12 @@ static int coresight_fixup_device_conns(struct coresight_device *csdev) for (i = 0; i < csdev->pdata->nr_outconns; i++) { struct coresight_connection *conn = &csdev->pdata->out_conns[i]; - if (!conn->child_fwnode) + if (!conn->dest_fwnode) continue; - conn->child_dev = - coresight_find_csdev_by_fwnode(conn->child_fwnode); - if (conn->child_dev && conn->child_dev->has_conns_grp) { - ret = coresight_make_links(csdev, conn, - conn->child_dev); + conn->dest_dev = + coresight_find_csdev_by_fwnode(conn->dest_fwnode); + if (conn->dest_dev && conn->dest_dev->has_conns_grp) { + ret = coresight_make_links(csdev, conn, conn->dest_dev); if (ret) break; } else { @@ -1414,14 +1413,14 @@ static int coresight_remove_match(struct device *dev, void *data) for (i = 0; i < iterator->pdata->nr_outconns; i++) { conn = &iterator->pdata->out_conns[i]; - if (conn->child_dev == NULL || conn->child_fwnode == NULL) + if (conn->dest_dev == NULL || conn->dest_fwnode == NULL) continue; - if (csdev->dev.fwnode == conn->child_fwnode) { + if (csdev->dev.fwnode == conn->dest_fwnode) { iterator->orphan = true; coresight_remove_links(iterator, conn); - conn->child_dev = NULL; + conn->dest_dev = NULL; /* No need to continue */ break; } @@ -1547,15 +1546,15 @@ void coresight_release_platform_data(struct coresight_device *csdev, for (i = 0; i < pdata->nr_outconns; i++) { /* If we have made the links, remove them now */ - if (csdev && conns[i].child_dev) + if (csdev && conns[i].dest_dev) coresight_remove_links(csdev, &conns[i]); /* * Drop the refcount and clear the handle as this device * is going away */ - if (conns[i].child_fwnode) { - fwnode_handle_put(conns[i].child_fwnode); - conns[i].child_fwnode = NULL; + if (conns[i].dest_fwnode) { + fwnode_handle_put(conns[i].dest_fwnode); + conns[i].dest_fwnode = NULL; } } if (csdev) diff --git a/drivers/hwtracing/coresight/coresight-platform.c b/drivers/hwtracing/coresight/coresight-platform.c index ed865e0621a9..566cc99a2c34 100644 --- a/drivers/hwtracing/coresight/coresight-platform.c +++ b/drivers/hwtracing/coresight/coresight-platform.c @@ -252,13 +252,13 @@ static int of_coresight_parse_endpoint(struct device *dev, } conn = &pdata->out_conns[endpoint.port]; - if (conn->child_fwnode) { + if (conn->dest_fwnode) { dev_warn(dev, "Duplicate output port %d\n", endpoint.port); ret = -EINVAL; break; } - conn->outport = endpoint.port; + conn->src_port = endpoint.port; /* * Hold the refcount to the target device. This could be * released via: @@ -267,8 +267,8 @@ static int of_coresight_parse_endpoint(struct device *dev, * 2) While removing the target device via * coresight_remove_match() */ - conn->child_fwnode = fwnode_handle_get(rdev_fwnode); - conn->child_port = rendpoint.port; + conn->dest_fwnode = fwnode_handle_get(rdev_fwnode); + conn->dest_port = rendpoint.port; /* Connection record updated */ } while (0); @@ -649,8 +649,8 @@ static int acpi_coresight_parse_link(struct acpi_device *adev, dir = fields[3].integer.value; if (dir == ACPI_CORESIGHT_LINK_MASTER) { - conn->outport = fields[0].integer.value; - conn->child_port = fields[1].integer.value; + conn->src_port = fields[0].integer.value; + conn->dest_port = fields[1].integer.value; rdev = coresight_find_device_by_fwnode(&r_adev->fwnode); if (!rdev) return -EPROBE_DEFER; @@ -662,14 +662,14 @@ static int acpi_coresight_parse_link(struct acpi_device *adev, * 2) While removing the target device via * coresight_remove_match(). */ - conn->child_fwnode = fwnode_handle_get(&r_adev->fwnode); + conn->dest_fwnode = fwnode_handle_get(&r_adev->fwnode); } else if (dir == ACPI_CORESIGHT_LINK_SLAVE) { /* * We are only interested in the port number * for the input ports at this component. * Store the port number in child_port. */ - conn->child_port = fields[0].integer.value; + conn->dest_port = fields[0].integer.value; } else { /* Invalid direction */ return -EINVAL; @@ -718,11 +718,11 @@ static int acpi_coresight_parse_graph(struct acpi_device *adev, return dir; if (dir == ACPI_CORESIGHT_LINK_MASTER) { - if (ptr->outport >= pdata->nr_outconns) - pdata->nr_outconns = ptr->outport + 1; + if (ptr->src_port >= pdata->nr_outconns) + pdata->nr_outconns = ptr->src_port + 1; ptr++; } else { - WARN_ON(pdata->nr_inconns == ptr->child_port + 1); + WARN_ON(pdata->nr_inconns == ptr->dest_port + 1); /* * We do not track input port connections for a device. * However we need the highest port number described, @@ -730,8 +730,8 @@ static int acpi_coresight_parse_graph(struct acpi_device *adev, * record for an output connection. Hence, do not move * the ptr for input connections */ - if (ptr->child_port >= pdata->nr_inconns) - pdata->nr_inconns = ptr->child_port + 1; + if (ptr->dest_port >= pdata->nr_inconns) + pdata->nr_inconns = ptr->dest_port + 1; } } @@ -741,10 +741,10 @@ static int acpi_coresight_parse_graph(struct acpi_device *adev, /* Copy the connection information to the final location */ for (i = 0; conns + i < ptr; i++) { - int port = conns[i].outport; + int port = conns[i].src_port; /* Duplicate output port */ - WARN_ON(pdata->out_conns[port].child_fwnode); + WARN_ON(pdata->out_conns[port].dest_fwnode); pdata->out_conns[port] = conns[i]; } diff --git a/drivers/hwtracing/coresight/coresight-sysfs.c b/drivers/hwtracing/coresight/coresight-sysfs.c index 34d2a2d31d00..a4a8e8e642e8 100644 --- a/drivers/hwtracing/coresight/coresight-sysfs.c +++ b/drivers/hwtracing/coresight/coresight-sysfs.c @@ -150,11 +150,11 @@ int coresight_make_links(struct coresight_device *orig, do { outs = devm_kasprintf(&orig->dev, GFP_KERNEL, - "out:%d", conn->outport); + "out:%d", conn->src_port); if (!outs) break; ins = devm_kasprintf(&target->dev, GFP_KERNEL, - "in:%d", conn->child_port); + "in:%d", conn->dest_port); if (!ins) break; link = devm_kzalloc(&orig->dev, @@ -178,7 +178,7 @@ int coresight_make_links(struct coresight_device *orig, * Install the device connection. This also indicates that * the links are operational on both ends. */ - conn->child_dev = target; + conn->dest_dev = target; return 0; } while (0); @@ -198,9 +198,9 @@ void coresight_remove_links(struct coresight_device *orig, coresight_remove_sysfs_link(conn->link); - devm_kfree(&conn->child_dev->dev, conn->link->target_name); + devm_kfree(&conn->dest_dev->dev, conn->link->target_name); devm_kfree(&orig->dev, conn->link->orig_name); devm_kfree(&orig->dev, conn->link); conn->link = NULL; - conn->child_dev = NULL; + conn->dest_dev = NULL; } diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c index 32137b78eca2..9ab77abbc7ec 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c @@ -782,7 +782,7 @@ tmc_etr_get_catu_device(struct tmc_drvdata *drvdata) return NULL; for (i = 0; i < etr->pdata->nr_outconns; i++) { - tmp = etr->pdata->out_conns[i].child_dev; + tmp = etr->pdata->out_conns[i].dest_dev; if (tmp && coresight_is_catu_device(tmp)) return tmp; } diff --git a/include/linux/coresight.h b/include/linux/coresight.h index daf392fcb67a..b6f444804bf3 100644 --- a/include/linux/coresight.h +++ b/include/linux/coresight.h @@ -164,18 +164,18 @@ 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. - * @chid_fwnode: remote component's fwnode handle. - * @child_dev: a @coresight_device representation of the component - connected to @outport. + * @src_port: a connection's output port number. + * @dest_port: destination's input port number @src_port is connected to. + * @dest_fwnode: destination component's fwnode handle. + * @dest_dev: a @coresight_device representation of the component + connected to @src_port. NULL until the device is created * @link: Representation of the connection as a sysfs link. */ struct coresight_connection { - int outport; - int child_port; - struct fwnode_handle *child_fwnode; - struct coresight_device *child_dev; + int src_port; + int dest_port; + struct fwnode_handle *dest_fwnode; + struct coresight_device *dest_dev; struct coresight_sysfs_link *link; }; -- cgit v1.2.3 From 3d4ff657e454f8dba3e5e268e731e6e28c6031c1 Mon Sep 17 00:00:00 2001 From: James Clark Date: Tue, 25 Apr 2023 15:35:33 +0100 Subject: coresight: Dynamically add connections Add a function for adding connections dynamically. This also removes the 1:1 mapping between port number and the index into the connections array. The only place this mapping was used was in the warning for duplicate output ports, which has been replaced by a search. Other uses of the port number already use the port member variable. Being able to dynamically add connections will allow other devices like CTI to re-use the connection mechanism despite not having explicit connections described in the DT. The connections array is now no longer sparse, so child_fwnode doesn't need to be checked as all connections have a target node. Because the array is no longer sparse, the high in and out port numbers are required for the refcount arrays. But these will also be removed in a later commit when the refcount is made a property of the connection. Reviewed-by: Mike Leach Signed-off-by: James Clark Signed-off-by: Suzuki K Poulose Link: https://lore.kernel.org/r/20230425143542.2305069-7-james.clark@arm.com --- drivers/hwtracing/coresight/coresight-core.c | 23 ++--- drivers/hwtracing/coresight/coresight-platform.c | 124 +++++++++++------------ include/linux/coresight.h | 8 +- 3 files changed, 77 insertions(+), 78 deletions(-) (limited to 'drivers/hwtracing/coresight/coresight-platform.c') diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c index f3dc320b374c..91274e7e6944 100644 --- a/drivers/hwtracing/coresight/coresight-core.c +++ b/drivers/hwtracing/coresight/coresight-core.c @@ -397,9 +397,9 @@ static void coresight_disable_link(struct coresight_device *csdev, link_subtype = csdev->subtype.link_subtype; if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_MERG) { - nr_conns = csdev->pdata->nr_inconns; + nr_conns = csdev->pdata->high_inport; } else if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_SPLIT) { - nr_conns = csdev->pdata->nr_outconns; + nr_conns = csdev->pdata->high_outport; } else { nr_conns = 1; } @@ -1336,9 +1336,6 @@ static int coresight_orphan_match(struct device *dev, void *data) for (i = 0; i < i_csdev->pdata->nr_outconns; i++) { conn = &i_csdev->pdata->out_conns[i]; - /* Skip the port if FW doesn't describe it */ - if (!conn->dest_fwnode) - continue; /* We have found at least one orphan connection */ if (conn->dest_dev == NULL) { /* Does it match this newly added device? */ @@ -1377,8 +1374,6 @@ static int coresight_fixup_device_conns(struct coresight_device *csdev) for (i = 0; i < csdev->pdata->nr_outconns; i++) { struct coresight_connection *conn = &csdev->pdata->out_conns[i]; - if (!conn->dest_fwnode) - continue; conn->dest_dev = coresight_find_csdev_by_fwnode(conn->dest_fwnode); if (conn->dest_dev && conn->dest_dev->has_conns_grp) { @@ -1413,7 +1408,7 @@ static int coresight_remove_match(struct device *dev, void *data) for (i = 0; i < iterator->pdata->nr_outconns; i++) { conn = &iterator->pdata->out_conns[i]; - if (conn->dest_dev == NULL || conn->dest_fwnode == NULL) + if (conn->dest_dev == NULL) continue; if (csdev->dev.fwnode == conn->dest_fwnode) { @@ -1445,7 +1440,7 @@ static void coresight_remove_conns(struct coresight_device *csdev) * doesn't have at least one input port, there is no point * in searching all the devices. */ - if (csdev->pdata->nr_inconns) + if (csdev->pdata->high_inport) bus_for_each_dev(&coresight_bustype, NULL, csdev, coresight_remove_match); } @@ -1552,10 +1547,8 @@ void coresight_release_platform_data(struct coresight_device *csdev, * Drop the refcount and clear the handle as this device * is going away */ - if (conns[i].dest_fwnode) { - fwnode_handle_put(conns[i].dest_fwnode); - conns[i].dest_fwnode = NULL; - } + fwnode_handle_put(conns[i].dest_fwnode); + conns[i].dest_fwnode = NULL; } if (csdev) coresight_remove_conns_sysfs_group(csdev); @@ -1581,9 +1574,9 @@ struct coresight_device *coresight_register(struct coresight_desc *desc) link_subtype = desc->subtype.link_subtype; if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_MERG) - nr_refcnts = desc->pdata->nr_inconns; + nr_refcnts = desc->pdata->high_inport; else if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_SPLIT) - nr_refcnts = desc->pdata->nr_outconns; + nr_refcnts = desc->pdata->high_outport; } refcnts = kcalloc(nr_refcnts, sizeof(*refcnts), GFP_KERNEL); diff --git a/drivers/hwtracing/coresight/coresight-platform.c b/drivers/hwtracing/coresight/coresight-platform.c index 566cc99a2c34..8c2029336161 100644 --- a/drivers/hwtracing/coresight/coresight-platform.c +++ b/drivers/hwtracing/coresight/coresight-platform.c @@ -19,22 +19,45 @@ #include #include "coresight-priv.h" + /* - * coresight_alloc_conns: Allocate connections record for each output - * port from the device. + * Add an entry to the connection list and assign @conn's contents to it. + * + * If the output port is already assigned on this device, return -EINVAL */ -static int coresight_alloc_conns(struct device *dev, - struct coresight_platform_data *pdata) +struct coresight_connection * +coresight_add_out_conn(struct device *dev, + struct coresight_platform_data *pdata, + const struct coresight_connection *new_conn) { - if (pdata->nr_outconns) { - pdata->out_conns = devm_kcalloc(dev, pdata->nr_outconns, - sizeof(*pdata->out_conns), GFP_KERNEL); - if (!pdata->out_conns) - return -ENOMEM; + int i; + struct coresight_connection *conn; + + /* + * Warn on any existing duplicate output port. + */ + for (i = 0; i < pdata->nr_outconns; ++i) { + conn = &pdata->out_conns[i]; + /* Output == -1 means ignore the port for example for helpers */ + if (conn->src_port != -1 && + conn->src_port == new_conn->src_port) { + dev_warn(dev, "Duplicate output port %d\n", + conn->src_port); + return ERR_PTR(-EINVAL); + } } - return 0; + pdata->nr_outconns++; + pdata->out_conns = + devm_krealloc_array(dev, pdata->out_conns, pdata->nr_outconns, + sizeof(*pdata->out_conns), GFP_KERNEL); + if (!pdata->out_conns) + return ERR_PTR(-ENOMEM); + + pdata->out_conns[pdata->nr_outconns - 1] = *new_conn; + return &pdata->out_conns[pdata->nr_outconns - 1]; } +EXPORT_SYMBOL_GPL(coresight_add_out_conn); static struct device * coresight_find_device_by_fwnode(struct fwnode_handle *fwnode) @@ -224,7 +247,8 @@ static int of_coresight_parse_endpoint(struct device *dev, struct device_node *rep = NULL; struct device *rdev = NULL; struct fwnode_handle *rdev_fwnode; - struct coresight_connection *conn; + struct coresight_connection conn = {}; + struct coresight_connection *new_conn; do { /* Parse the local port details */ @@ -251,14 +275,7 @@ static int of_coresight_parse_endpoint(struct device *dev, break; } - conn = &pdata->out_conns[endpoint.port]; - if (conn->dest_fwnode) { - dev_warn(dev, "Duplicate output port %d\n", - endpoint.port); - ret = -EINVAL; - break; - } - conn->src_port = endpoint.port; + conn.src_port = endpoint.port; /* * Hold the refcount to the target device. This could be * released via: @@ -267,8 +284,14 @@ static int of_coresight_parse_endpoint(struct device *dev, * 2) While removing the target device via * coresight_remove_match() */ - conn->dest_fwnode = fwnode_handle_get(rdev_fwnode); - conn->dest_port = rendpoint.port; + conn.dest_fwnode = fwnode_handle_get(rdev_fwnode); + conn.dest_port = rendpoint.port; + + new_conn = coresight_add_out_conn(dev, pdata, &conn); + if (IS_ERR_VALUE(new_conn)) { + fwnode_handle_put(conn.dest_fwnode); + return PTR_ERR(new_conn); + } /* Connection record updated */ } while (0); @@ -289,16 +312,12 @@ static int of_get_coresight_platform_data(struct device *dev, struct device_node *node = dev->of_node; /* Get the number of input and output port for this component */ - of_coresight_get_ports(node, &pdata->nr_inconns, &pdata->nr_outconns); + of_coresight_get_ports(node, &pdata->high_inport, &pdata->high_outport); /* If there are no output connections, we are done */ - if (!pdata->nr_outconns) + if (!pdata->high_outport) return 0; - ret = coresight_alloc_conns(dev, pdata); - if (ret) - return ret; - parent = of_coresight_get_output_ports_node(node); /* * If the DT uses obsoleted bindings, the ports are listed @@ -683,12 +702,14 @@ static int acpi_coresight_parse_link(struct acpi_device *adev, * connection information and populate the supplied coresight_platform_data * instance. */ -static int acpi_coresight_parse_graph(struct acpi_device *adev, +static int acpi_coresight_parse_graph(struct device *dev, + struct acpi_device *adev, struct coresight_platform_data *pdata) { - int rc, i, nlinks; + int i, nlinks; const union acpi_object *graph; - struct coresight_connection *conns, *ptr; + struct coresight_connection conn, zero_conn = {}; + struct coresight_connection *new_conn; pdata->nr_inconns = pdata->nr_outconns = 0; graph = acpi_get_coresight_graph(adev); @@ -699,30 +720,23 @@ static int acpi_coresight_parse_graph(struct acpi_device *adev, if (!nlinks) return 0; - /* - * To avoid scanning the table twice (once for finding the number of - * output links and then later for parsing the output links), - * cache the links information in one go and then later copy - * it to the pdata. - */ - conns = devm_kcalloc(&adev->dev, nlinks, sizeof(*conns), GFP_KERNEL); - if (!conns) - return -ENOMEM; - ptr = conns; for (i = 0; i < nlinks; i++) { const union acpi_object *link = &graph->package.elements[3 + i]; int dir; - dir = acpi_coresight_parse_link(adev, link, ptr); + conn = zero_conn; + dir = acpi_coresight_parse_link(adev, link, &conn); if (dir < 0) return dir; if (dir == ACPI_CORESIGHT_LINK_MASTER) { - if (ptr->src_port >= pdata->nr_outconns) - pdata->nr_outconns = ptr->src_port + 1; - ptr++; + if (conn.src_port >= pdata->high_outport) + pdata->high_outport = conn.src_port + 1; + new_conn = coresight_add_out_conn(dev, pdata, &conn); + if (IS_ERR(new_conn)) + return PTR_ERR(new_conn); } else { - WARN_ON(pdata->nr_inconns == ptr->dest_port + 1); + WARN_ON(pdata->high_inport == conn.dest_port + 1); /* * We do not track input port connections for a device. * However we need the highest port number described, @@ -730,25 +744,11 @@ static int acpi_coresight_parse_graph(struct acpi_device *adev, * record for an output connection. Hence, do not move * the ptr for input connections */ - if (ptr->dest_port >= pdata->nr_inconns) - pdata->nr_inconns = ptr->dest_port + 1; + if (conn.dest_port >= pdata->high_inport) + pdata->high_inport = conn.dest_port + 1; } } - rc = coresight_alloc_conns(&adev->dev, pdata); - if (rc) - return rc; - - /* Copy the connection information to the final location */ - for (i = 0; conns + i < ptr; i++) { - int port = conns[i].src_port; - - /* Duplicate output port */ - WARN_ON(pdata->out_conns[port].dest_fwnode); - pdata->out_conns[port] = conns[i]; - } - - devm_kfree(&adev->dev, conns); return 0; } @@ -809,7 +809,7 @@ acpi_get_coresight_platform_data(struct device *dev, if (!adev) return -EINVAL; - return acpi_coresight_parse_graph(adev, pdata); + return acpi_coresight_parse_graph(dev, adev, pdata); } #else diff --git a/include/linux/coresight.h b/include/linux/coresight.h index b6f444804bf3..12fdbd03e2f7 100644 --- a/include/linux/coresight.h +++ b/include/linux/coresight.h @@ -104,9 +104,11 @@ union coresight_dev_subtype { * * @nr_inconns: Number of elements for the input connections. * @nr_outconns: Number of elements for the output connections. - * @out_conns: Sparse array of nr_outconns connections from this component. + * @out_conns: Array of nr_outconns connections from this component. */ struct coresight_platform_data { + int high_inport; + int high_outport; int nr_inconns; int nr_outconns; struct coresight_connection *out_conns; @@ -609,5 +611,9 @@ static inline void coresight_write64(struct coresight_device *csdev, u64 val, u3 extern int coresight_get_cpu(struct device *dev); struct coresight_platform_data *coresight_get_platform_data(struct device *dev); +struct coresight_connection * +coresight_add_out_conn(struct device *dev, + struct coresight_platform_data *pdata, + const struct coresight_connection *new_conn); #endif /* _LINUX_COREISGHT_H */ -- cgit v1.2.3 From 4e8fe7e5c3a5e48295a6745727a6703adab8ff7f Mon Sep 17 00:00:00 2001 From: James Clark Date: Tue, 25 Apr 2023 15:35:34 +0100 Subject: coresight: Store pointers to connections rather than an array of them This will allow the same connection object to be referenced via the input connection list in a later commit rather than duplicating them. Reviewed-by: Mike Leach Signed-off-by: James Clark Signed-off-by: Suzuki K Poulose Link: https://lore.kernel.org/r/20230425143542.2305069-8-james.clark@arm.com --- drivers/hwtracing/coresight/coresight-core.c | 47 ++++++++++++------------ drivers/hwtracing/coresight/coresight-platform.c | 19 ++++++++-- drivers/hwtracing/coresight/coresight-priv.h | 1 + drivers/hwtracing/coresight/coresight-tmc-etr.c | 2 +- include/linux/coresight.h | 5 ++- 5 files changed, 44 insertions(+), 30 deletions(-) (limited to 'drivers/hwtracing/coresight/coresight-platform.c') diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c index 91274e7e6944..0b738960973b 100644 --- a/drivers/hwtracing/coresight/coresight-core.c +++ b/drivers/hwtracing/coresight/coresight-core.c @@ -119,7 +119,7 @@ static int coresight_find_link_inport(struct coresight_device *csdev, struct coresight_connection *conn; for (i = 0; i < parent->pdata->nr_outconns; i++) { - conn = &parent->pdata->out_conns[i]; + conn = parent->pdata->out_conns[i]; if (conn->dest_dev == csdev) return conn->dest_port; } @@ -137,7 +137,7 @@ static int coresight_find_link_outport(struct coresight_device *csdev, struct coresight_connection *conn; for (i = 0; i < csdev->pdata->nr_outconns; i++) { - conn = &csdev->pdata->out_conns[i]; + conn = csdev->pdata->out_conns[i]; if (conn->dest_dev == child) return conn->src_port; } @@ -606,7 +606,7 @@ coresight_find_enabled_sink(struct coresight_device *csdev) for (i = 0; i < csdev->pdata->nr_outconns; i++) { struct coresight_device *child_dev; - child_dev = csdev->pdata->out_conns[i].dest_dev; + child_dev = csdev->pdata->out_conns[i]->dest_dev; if (child_dev) sink = coresight_find_enabled_sink(child_dev); if (sink) @@ -722,7 +722,7 @@ static int coresight_grab_device(struct coresight_device *csdev) for (i = 0; i < csdev->pdata->nr_outconns; i++) { struct coresight_device *child; - child = csdev->pdata->out_conns[i].dest_dev; + child = csdev->pdata->out_conns[i]->dest_dev; if (child && child->type == CORESIGHT_DEV_TYPE_HELPER) if (!coresight_get_ref(child)) goto err; @@ -733,7 +733,7 @@ err: for (i--; i >= 0; i--) { struct coresight_device *child; - child = csdev->pdata->out_conns[i].dest_dev; + child = csdev->pdata->out_conns[i]->dest_dev; if (child && child->type == CORESIGHT_DEV_TYPE_HELPER) coresight_put_ref(child); } @@ -752,7 +752,7 @@ static void coresight_drop_device(struct coresight_device *csdev) for (i = 0; i < csdev->pdata->nr_outconns; i++) { struct coresight_device *child; - child = csdev->pdata->out_conns[i].dest_dev; + child = csdev->pdata->out_conns[i]->dest_dev; if (child && child->type == CORESIGHT_DEV_TYPE_HELPER) coresight_put_ref(child); } @@ -794,7 +794,7 @@ static int _coresight_build_path(struct coresight_device *csdev, for (i = 0; i < csdev->pdata->nr_outconns; i++) { struct coresight_device *child_dev; - child_dev = csdev->pdata->out_conns[i].dest_dev; + child_dev = csdev->pdata->out_conns[i]->dest_dev; if (child_dev && _coresight_build_path(child_dev, sink, path) == 0) { found = true; @@ -964,7 +964,7 @@ coresight_find_sink(struct coresight_device *csdev, int *depth) struct coresight_device *child_dev, *sink = NULL; int child_depth = curr_depth; - child_dev = csdev->pdata->out_conns[i].dest_dev; + child_dev = csdev->pdata->out_conns[i]->dest_dev; if (child_dev) sink = coresight_find_sink(child_dev, &child_depth); @@ -1334,7 +1334,7 @@ static int coresight_orphan_match(struct device *dev, void *data) * an orphan connection whose name matches @csdev, link it. */ for (i = 0; i < i_csdev->pdata->nr_outconns; i++) { - conn = &i_csdev->pdata->out_conns[i]; + conn = i_csdev->pdata->out_conns[i]; /* We have found at least one orphan connection */ if (conn->dest_dev == NULL) { @@ -1372,7 +1372,7 @@ static int coresight_fixup_device_conns(struct coresight_device *csdev) int i, ret = 0; for (i = 0; i < csdev->pdata->nr_outconns; i++) { - struct coresight_connection *conn = &csdev->pdata->out_conns[i]; + struct coresight_connection *conn = csdev->pdata->out_conns[i]; conn->dest_dev = coresight_find_csdev_by_fwnode(conn->dest_fwnode); @@ -1406,15 +1406,12 @@ static int coresight_remove_match(struct device *dev, void *data) * a connection whose name matches @csdev, remove it. */ for (i = 0; i < iterator->pdata->nr_outconns; i++) { - conn = &iterator->pdata->out_conns[i]; + conn = iterator->pdata->out_conns[i]; - if (conn->dest_dev == NULL) - continue; - - if (csdev->dev.fwnode == conn->dest_fwnode) { + /* Child_dev being set signifies that the links were made */ + if (csdev->dev.fwnode == conn->dest_fwnode && conn->dest_dev) { iterator->orphan = true; coresight_remove_links(iterator, conn); - conn->dest_dev = NULL; /* No need to continue */ break; @@ -1534,22 +1531,26 @@ void coresight_write64(struct coresight_device *csdev, u64 val, u32 offset) * to the output port of this device. */ void coresight_release_platform_data(struct coresight_device *csdev, + struct device *dev, struct coresight_platform_data *pdata) { int i; - struct coresight_connection *conns = pdata->out_conns; + struct coresight_connection **conns = pdata->out_conns; for (i = 0; i < pdata->nr_outconns; i++) { /* If we have made the links, remove them now */ - if (csdev && conns[i].dest_dev) - coresight_remove_links(csdev, &conns[i]); + if (csdev && conns[i]->dest_dev) + coresight_remove_links(csdev, conns[i]); /* * Drop the refcount and clear the handle as this device * is going away */ - fwnode_handle_put(conns[i].dest_fwnode); - conns[i].dest_fwnode = NULL; + fwnode_handle_put(conns[i]->dest_fwnode); + conns[i]->dest_fwnode = NULL; + devm_kfree(dev, conns[i]); } + devm_kfree(dev, pdata->out_conns); + devm_kfree(dev, pdata); if (csdev) coresight_remove_conns_sysfs_group(csdev); } @@ -1666,7 +1667,7 @@ out_unlock: err_out: /* Cleanup the connection information */ - coresight_release_platform_data(NULL, desc->pdata); + coresight_release_platform_data(NULL, desc->dev, desc->pdata); return ERR_PTR(ret); } EXPORT_SYMBOL_GPL(coresight_register); @@ -1679,7 +1680,7 @@ void coresight_unregister(struct coresight_device *csdev) cti_assoc_ops->remove(csdev); coresight_remove_conns(csdev); coresight_clear_default_sink(csdev); - coresight_release_platform_data(csdev, csdev->pdata); + coresight_release_platform_data(csdev, csdev->dev.parent, csdev->pdata); device_unregister(&csdev->dev); } EXPORT_SYMBOL_GPL(coresight_unregister); diff --git a/drivers/hwtracing/coresight/coresight-platform.c b/drivers/hwtracing/coresight/coresight-platform.c index 8c2029336161..9c05f787278b 100644 --- a/drivers/hwtracing/coresight/coresight-platform.c +++ b/drivers/hwtracing/coresight/coresight-platform.c @@ -37,7 +37,7 @@ coresight_add_out_conn(struct device *dev, * Warn on any existing duplicate output port. */ for (i = 0; i < pdata->nr_outconns; ++i) { - conn = &pdata->out_conns[i]; + conn = pdata->out_conns[i]; /* Output == -1 means ignore the port for example for helpers */ if (conn->src_port != -1 && conn->src_port == new_conn->src_port) { @@ -54,8 +54,19 @@ coresight_add_out_conn(struct device *dev, if (!pdata->out_conns) return ERR_PTR(-ENOMEM); - pdata->out_conns[pdata->nr_outconns - 1] = *new_conn; - return &pdata->out_conns[pdata->nr_outconns - 1]; + conn = devm_kmalloc(dev, sizeof(struct coresight_connection), + GFP_KERNEL); + if (!conn) + return ERR_PTR(-ENOMEM); + + /* + * Copy the new connection into the allocation, save the pointer to the + * end of the connection array and also return it in case it needs to be + * used right away. + */ + *conn = *new_conn; + pdata->out_conns[pdata->nr_outconns - 1] = conn; + return conn; } EXPORT_SYMBOL_GPL(coresight_add_out_conn); @@ -863,7 +874,7 @@ coresight_get_platform_data(struct device *dev) error: if (!IS_ERR_OR_NULL(pdata)) /* Cleanup the connection information */ - coresight_release_platform_data(NULL, pdata); + coresight_release_platform_data(NULL, dev, pdata); return ERR_PTR(ret); } EXPORT_SYMBOL_GPL(coresight_get_platform_data); diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h index 788ff19c60f6..65ae6d161c57 100644 --- a/drivers/hwtracing/coresight/coresight-priv.h +++ b/drivers/hwtracing/coresight/coresight-priv.h @@ -207,6 +207,7 @@ static inline void *coresight_get_uci_data(const struct amba_id *id) } void coresight_release_platform_data(struct coresight_device *csdev, + struct device *dev, struct coresight_platform_data *pdata); struct coresight_device * coresight_find_csdev_by_fwnode(struct fwnode_handle *r_fwnode); diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c index 9ab77abbc7ec..e4493647d66d 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c @@ -782,7 +782,7 @@ tmc_etr_get_catu_device(struct tmc_drvdata *drvdata) return NULL; for (i = 0; i < etr->pdata->nr_outconns; i++) { - tmp = etr->pdata->out_conns[i].dest_dev; + tmp = etr->pdata->out_conns[i]->dest_dev; if (tmp && coresight_is_catu_device(tmp)) return tmp; } diff --git a/include/linux/coresight.h b/include/linux/coresight.h index 12fdbd03e2f7..abf36a37fdb0 100644 --- a/include/linux/coresight.h +++ b/include/linux/coresight.h @@ -104,14 +104,15 @@ union coresight_dev_subtype { * * @nr_inconns: Number of elements for the input connections. * @nr_outconns: Number of elements for the output connections. - * @out_conns: Array of nr_outconns connections from this component. + * @out_conns: Array of nr_outconns pointers to connections from this + * component. */ struct coresight_platform_data { int high_inport; int high_outport; int nr_inconns; int nr_outconns; - struct coresight_connection *out_conns; + struct coresight_connection **out_conns; }; /** -- cgit v1.2.3 From e3f4e68797a960869ccae556ad63163b3dc470a2 Mon Sep 17 00:00:00 2001 From: James Clark Date: Tue, 25 Apr 2023 15:35:36 +0100 Subject: coresight: Store in-connections as well as out-connections This will allow CATU to get its associated ETR in a generic way where currently the enable path has some hard coded searches which avoid the need to store input connections. This also means that the full search for connected devices on removal can be replaced with a loop through only the input and output devices. Reviewed-by: Mike Leach Signed-off-by: James Clark Signed-off-by: Suzuki K Poulose Link: https://lore.kernel.org/r/20230425143542.2305069-10-james.clark@arm.com --- drivers/hwtracing/coresight/coresight-core.c | 81 ++++++++++++------------ drivers/hwtracing/coresight/coresight-platform.c | 31 ++++++++- drivers/hwtracing/coresight/coresight-sysfs.c | 7 -- include/linux/coresight.h | 26 ++++++++ 4 files changed, 95 insertions(+), 50 deletions(-) (limited to 'drivers/hwtracing/coresight/coresight-platform.c') diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c index 8d377a59e0be..a0a0ea2c626b 100644 --- a/drivers/hwtracing/coresight/coresight-core.c +++ b/drivers/hwtracing/coresight/coresight-core.c @@ -1349,6 +1349,17 @@ static int coresight_orphan_match(struct device *dev, void *data) ret = coresight_make_links(src_csdev, conn, dst_csdev); if (ret) return ret; + + /* + * Install the device connection. This also indicates that + * the links are operational on both ends. + */ + conn->dest_dev = dst_csdev; + conn->src_dev = src_csdev; + + ret = coresight_add_in_conn(conn); + if (ret) + return ret; } else { /* This component still has an orphan */ still_orphan = true; @@ -1370,58 +1381,43 @@ static int coresight_fixup_orphan_conns(struct coresight_device *csdev) csdev, coresight_orphan_match); } -static int coresight_remove_match(struct device *dev, void *data) +/* coresight_remove_conns - Remove other device's references to this device */ +static void coresight_remove_conns(struct coresight_device *csdev) { - int i; - struct coresight_device *csdev, *iterator; + int i, j; struct coresight_connection *conn; - csdev = data; - iterator = to_coresight_device(dev); - - /* No need to check oneself */ - if (csdev == iterator) - return 0; - /* - * Circle throuch all the connection of that component. If we find - * a connection whose name matches @csdev, remove it. + * Remove the input connection references from the destination device + * for each output connection. */ - for (i = 0; i < iterator->pdata->nr_outconns; i++) { - conn = iterator->pdata->out_conns[i]; - - /* Child_dev being set signifies that the links were made */ - if (csdev->dev.fwnode == conn->dest_fwnode && conn->dest_dev) { - iterator->orphan = true; - coresight_remove_links(iterator, conn); - conn->dest_dev = NULL; - /* No need to continue */ - break; - } + for (i = 0; i < csdev->pdata->nr_outconns; i++) { + conn = csdev->pdata->out_conns[i]; + if (!conn->dest_dev) + continue; + + for (j = 0; j < conn->dest_dev->pdata->nr_inconns; ++j) + if (conn->dest_dev->pdata->in_conns[j] == conn) { + conn->dest_dev->pdata->in_conns[j] = NULL; + break; + } } /* - * Returning '0' ensures that all known component on the - * bus will be checked. + * For all input connections, remove references to this device. + * Connection objects are shared so modifying this device's input + * connections affects the other device's output connection. */ - return 0; -} + for (i = 0; i < csdev->pdata->nr_inconns; ++i) { + conn = csdev->pdata->in_conns[i]; + /* Input conns array is sparse */ + if (!conn) + continue; -/* - * coresight_remove_conns - Remove references to this given devices - * from the connections of other devices. - */ -static void coresight_remove_conns(struct coresight_device *csdev) -{ - /* - * Another device will point to this device only if there is - * an output port connected to this one. i.e, if the device - * doesn't have at least one input port, there is no point - * in searching all the devices. - */ - if (csdev->pdata->high_inport) - bus_for_each_dev(&coresight_bustype, NULL, - csdev, coresight_remove_match); + conn->src_dev->orphan = true; + coresight_remove_links(conn->src_dev, conn); + conn->dest_dev = NULL; + } } /** @@ -1532,6 +1528,7 @@ void coresight_release_platform_data(struct coresight_device *csdev, devm_kfree(dev, conns[i]); } devm_kfree(dev, pdata->out_conns); + devm_kfree(dev, pdata->in_conns); devm_kfree(dev, pdata); if (csdev) coresight_remove_conns_sysfs_group(csdev); diff --git a/drivers/hwtracing/coresight/coresight-platform.c b/drivers/hwtracing/coresight/coresight-platform.c index 9c05f787278b..257ad48925a1 100644 --- a/drivers/hwtracing/coresight/coresight-platform.c +++ b/drivers/hwtracing/coresight/coresight-platform.c @@ -70,6 +70,35 @@ coresight_add_out_conn(struct device *dev, } EXPORT_SYMBOL_GPL(coresight_add_out_conn); +/* + * Add an input connection reference to @out_conn in the target's in_conns array + * + * @out_conn: Existing output connection to store as an input on the + * connection's remote device. + */ +int coresight_add_in_conn(struct coresight_connection *out_conn) +{ + int i; + struct device *dev = out_conn->dest_dev->dev.parent; + struct coresight_platform_data *pdata = out_conn->dest_dev->pdata; + + for (i = 0; i < pdata->nr_inconns; ++i) + if (!pdata->in_conns[i]) { + pdata->in_conns[i] = out_conn; + return 0; + } + + pdata->nr_inconns++; + pdata->in_conns = + devm_krealloc_array(dev, pdata->in_conns, pdata->nr_inconns, + sizeof(*pdata->in_conns), GFP_KERNEL); + if (!pdata->in_conns) + return -ENOMEM; + pdata->in_conns[pdata->nr_inconns - 1] = out_conn; + return 0; +} +EXPORT_SYMBOL_GPL(coresight_add_in_conn); + static struct device * coresight_find_device_by_fwnode(struct fwnode_handle *fwnode) { @@ -240,7 +269,7 @@ static int of_coresight_get_cpu(struct device *dev) /* * of_coresight_parse_endpoint : Parse the given output endpoint @ep - * and fill the connection information in @conn + * and fill the connection information in @pdata->out_conns * * Parses the local port, remote device name and the remote port. * diff --git a/drivers/hwtracing/coresight/coresight-sysfs.c b/drivers/hwtracing/coresight/coresight-sysfs.c index a4a8e8e642e8..464ba5e1343b 100644 --- a/drivers/hwtracing/coresight/coresight-sysfs.c +++ b/drivers/hwtracing/coresight/coresight-sysfs.c @@ -173,12 +173,6 @@ int coresight_make_links(struct coresight_device *orig, break; conn->link = link; - - /* - * Install the device connection. This also indicates that - * the links are operational on both ends. - */ - conn->dest_dev = target; return 0; } while (0); @@ -202,5 +196,4 @@ void coresight_remove_links(struct coresight_device *orig, devm_kfree(&orig->dev, conn->link->orig_name); devm_kfree(&orig->dev, conn->link); conn->link = NULL; - conn->dest_dev = NULL; } diff --git a/include/linux/coresight.h b/include/linux/coresight.h index abf36a37fdb0..e9c52c5ca7f3 100644 --- a/include/linux/coresight.h +++ b/include/linux/coresight.h @@ -106,6 +106,9 @@ union coresight_dev_subtype { * @nr_outconns: Number of elements for the output connections. * @out_conns: Array of nr_outconns pointers to connections from this * component. + * @in_conns: Sparse array of pointers to input connections. Sparse + * because the source device owns the connection so when it's + * unloaded the connection leaves an empty slot. */ struct coresight_platform_data { int high_inport; @@ -113,6 +116,7 @@ struct coresight_platform_data { int nr_inconns; int nr_outconns; struct coresight_connection **out_conns; + struct coresight_connection **in_conns; }; /** @@ -173,6 +177,26 @@ struct coresight_desc { * @dest_dev: a @coresight_device representation of the component connected to @src_port. NULL until the device is created * @link: Representation of the connection as a sysfs link. + * + * The full connection structure looks like this, where in_conns store + * references to same connection as the source device's out_conns. + * + * +-----------------------------+ +-----------------------------+ + * |coresight_device | |coresight_connection | + * |-----------------------------| |-----------------------------| + * | | | | + * | | | dest_dev*|<-- + * |pdata->out_conns[nr_outconns]|<->|src_dev* | | + * | | | | | + * +-----------------------------+ +-----------------------------+ | + * | + * +-----------------------------+ | + * |coresight_device | | + * |------------------------------ | + * | | | + * | pdata->in_conns[nr_inconns]|<-- + * | | + * +-----------------------------+ */ struct coresight_connection { int src_port; @@ -180,6 +204,7 @@ struct coresight_connection { struct fwnode_handle *dest_fwnode; struct coresight_device *dest_dev; struct coresight_sysfs_link *link; + struct coresight_device *src_dev; }; /** @@ -616,5 +641,6 @@ struct coresight_connection * coresight_add_out_conn(struct device *dev, struct coresight_platform_data *pdata, const struct coresight_connection *new_conn); +int coresight_add_in_conn(struct coresight_connection *conn); #endif /* _LINUX_COREISGHT_H */ -- cgit v1.2.3 From ae7f2b5a7b569f8ede4af9e215515e5a0b824edd Mon Sep 17 00:00:00 2001 From: James Clark Date: Tue, 25 Apr 2023 15:35:37 +0100 Subject: coresight: Make refcount a property of the connection This removes the need to do an additional lookup for the total number of ports used and also removes the need to allocate an array of refcounts which is just another representation of a connection array. This was only used for link type devices, for regular devices a single refcount on the coresight device is used. There is a both an input and output refcount in case two link type devices are connected together so that they don't overwrite each other's counts. Reviewed-by: Mike Leach Signed-off-by: James Clark Signed-off-by: Suzuki K Poulose Link: https://lore.kernel.org/r/20230425143542.2305069-11-james.clark@arm.com --- drivers/hwtracing/coresight/coresight-core.c | 116 +++++++-------------- drivers/hwtracing/coresight/coresight-etb10.c | 10 +- drivers/hwtracing/coresight/coresight-funnel.c | 26 +++-- drivers/hwtracing/coresight/coresight-platform.c | 109 ++----------------- drivers/hwtracing/coresight/coresight-replicator.c | 23 ++-- drivers/hwtracing/coresight/coresight-tmc-etf.c | 24 +++-- drivers/hwtracing/coresight/coresight-tmc-etr.c | 12 +-- drivers/hwtracing/coresight/coresight-tpda.c | 23 ++-- drivers/hwtracing/coresight/coresight-tpiu.c | 4 +- drivers/hwtracing/coresight/ultrasoc-smb.c | 8 +- include/linux/coresight.h | 14 ++- 11 files changed, 126 insertions(+), 243 deletions(-) (limited to 'drivers/hwtracing/coresight/coresight-platform.c') diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c index a0a0ea2c626b..939b7fb751b5 100644 --- a/drivers/hwtracing/coresight/coresight-core.c +++ b/drivers/hwtracing/coresight/coresight-core.c @@ -112,40 +112,24 @@ struct coresight_device *coresight_get_percpu_sink(int cpu) } EXPORT_SYMBOL_GPL(coresight_get_percpu_sink); -static int coresight_find_link_inport(struct coresight_device *csdev, - struct coresight_device *parent) +static struct coresight_connection * +coresight_find_out_connection(struct coresight_device *src_dev, + struct coresight_device *dest_dev) { int i; struct coresight_connection *conn; - for (i = 0; i < parent->pdata->nr_outconns; i++) { - conn = parent->pdata->out_conns[i]; - if (conn->dest_dev == csdev) - return conn->dest_port; + for (i = 0; i < src_dev->pdata->nr_outconns; i++) { + conn = src_dev->pdata->out_conns[i]; + if (conn->dest_dev == dest_dev) + return conn; } - dev_err(&csdev->dev, "couldn't find inport, parent: %s, child: %s\n", - dev_name(&parent->dev), dev_name(&csdev->dev)); + dev_err(&src_dev->dev, + "couldn't find output connection, src_dev: %s, dest_dev: %s\n", + dev_name(&src_dev->dev), dev_name(&dest_dev->dev)); - return -ENODEV; -} - -static int coresight_find_link_outport(struct coresight_device *csdev, - struct coresight_device *child) -{ - int i; - struct coresight_connection *conn; - - for (i = 0; i < csdev->pdata->nr_outconns; i++) { - conn = csdev->pdata->out_conns[i]; - if (conn->dest_dev == child) - return conn->src_port; - } - - dev_err(&csdev->dev, "couldn't find outport, parent: %s, child: %s\n", - dev_name(&csdev->dev), dev_name(&child->dev)); - - return -ENODEV; + return ERR_PTR(-ENODEV); } static inline u32 coresight_read_claim_tags(struct coresight_device *csdev) @@ -352,24 +336,24 @@ static int coresight_enable_link(struct coresight_device *csdev, { int ret = 0; int link_subtype; - int inport, outport; + struct coresight_connection *inconn, *outconn; if (!parent || !child) return -EINVAL; - inport = coresight_find_link_inport(csdev, parent); - outport = coresight_find_link_outport(csdev, child); + inconn = coresight_find_out_connection(parent, csdev); + outconn = coresight_find_out_connection(csdev, child); link_subtype = csdev->subtype.link_subtype; - if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_MERG && inport < 0) - return inport; - if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_SPLIT && outport < 0) - return outport; + if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_MERG && IS_ERR(inconn)) + return PTR_ERR(inconn); + if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_SPLIT && IS_ERR(outconn)) + return PTR_ERR(outconn); if (link_ops(csdev)->enable) { ret = coresight_control_assoc_ectdev(csdev, true); if (!ret) { - ret = link_ops(csdev)->enable(csdev, inport, outport); + ret = link_ops(csdev)->enable(csdev, inconn, outconn); if (ret) coresight_control_assoc_ectdev(csdev, false); } @@ -385,33 +369,36 @@ static void coresight_disable_link(struct coresight_device *csdev, struct coresight_device *parent, struct coresight_device *child) { - int i, nr_conns; + int i; int link_subtype; - int inport, outport; + struct coresight_connection *inconn, *outconn; if (!parent || !child) return; - inport = coresight_find_link_inport(csdev, parent); - outport = coresight_find_link_outport(csdev, child); + inconn = coresight_find_out_connection(parent, csdev); + outconn = coresight_find_out_connection(csdev, child); link_subtype = csdev->subtype.link_subtype; - if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_MERG) { - nr_conns = csdev->pdata->high_inport; - } else if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_SPLIT) { - nr_conns = csdev->pdata->high_outport; - } else { - nr_conns = 1; - } - if (link_ops(csdev)->disable) { - link_ops(csdev)->disable(csdev, inport, outport); + link_ops(csdev)->disable(csdev, inconn, outconn); coresight_control_assoc_ectdev(csdev, false); } - for (i = 0; i < nr_conns; i++) - if (atomic_read(&csdev->refcnt[i]) != 0) + if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_MERG) { + for (i = 0; i < csdev->pdata->nr_inconns; i++) + if (atomic_read(&csdev->pdata->in_conns[i]->dest_refcnt) != + 0) + return; + } else if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_SPLIT) { + for (i = 0; i < csdev->pdata->nr_outconns; i++) + if (atomic_read(&csdev->pdata->out_conns[i]->src_refcnt) != + 0) + return; + } else { + if (atomic_read(&csdev->refcnt) != 0) return; + } csdev->enable = false; } @@ -435,7 +422,7 @@ static int coresight_enable_source(struct coresight_device *csdev, csdev->enable = true; } - atomic_inc(csdev->refcnt); + atomic_inc(&csdev->refcnt); return 0; } @@ -450,7 +437,7 @@ static int coresight_enable_source(struct coresight_device *csdev, */ static bool coresight_disable_source(struct coresight_device *csdev) { - if (atomic_dec_return(csdev->refcnt) == 0) { + if (atomic_dec_return(&csdev->refcnt) == 0) { if (source_ops(csdev)->disable) source_ops(csdev)->disable(csdev, NULL); coresight_control_assoc_ectdev(csdev, false); @@ -1094,7 +1081,7 @@ int coresight_enable(struct coresight_device *csdev) * source is already enabled. */ if (subtype == CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE) - atomic_inc(csdev->refcnt); + atomic_inc(&csdev->refcnt); goto out; } @@ -1308,7 +1295,6 @@ static void coresight_device_release(struct device *dev) struct coresight_device *csdev = to_coresight_device(dev); fwnode_handle_put(csdev->dev.fwnode); - kfree(csdev->refcnt); kfree(csdev); } @@ -1537,9 +1523,6 @@ void coresight_release_platform_data(struct coresight_device *csdev, struct coresight_device *coresight_register(struct coresight_desc *desc) { int ret; - int link_subtype; - int nr_refcnts = 1; - atomic_t *refcnts = NULL; struct coresight_device *csdev; bool registered = false; @@ -1549,25 +1532,6 @@ struct coresight_device *coresight_register(struct coresight_desc *desc) goto err_out; } - if (desc->type == CORESIGHT_DEV_TYPE_LINK || - desc->type == CORESIGHT_DEV_TYPE_LINKSINK) { - link_subtype = desc->subtype.link_subtype; - - if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_MERG) - nr_refcnts = desc->pdata->high_inport; - else if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_SPLIT) - nr_refcnts = desc->pdata->high_outport; - } - - refcnts = kcalloc(nr_refcnts, sizeof(*refcnts), GFP_KERNEL); - if (!refcnts) { - ret = -ENOMEM; - kfree(csdev); - goto err_out; - } - - csdev->refcnt = refcnts; - csdev->pdata = desc->pdata; csdev->type = desc->type; diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtracing/coresight/coresight-etb10.c index eb99c445015a..fa80039e0821 100644 --- a/drivers/hwtracing/coresight/coresight-etb10.c +++ b/drivers/hwtracing/coresight/coresight-etb10.c @@ -163,7 +163,7 @@ static int etb_enable_sysfs(struct coresight_device *csdev) drvdata->mode = CS_MODE_SYSFS; } - atomic_inc(csdev->refcnt); + atomic_inc(&csdev->refcnt); out: spin_unlock_irqrestore(&drvdata->spinlock, flags); return ret; @@ -199,7 +199,7 @@ static int etb_enable_perf(struct coresight_device *csdev, void *data) * use for this session. */ if (drvdata->pid == pid) { - atomic_inc(csdev->refcnt); + atomic_inc(&csdev->refcnt); goto out; } @@ -217,7 +217,7 @@ static int etb_enable_perf(struct coresight_device *csdev, void *data) /* Associate with monitored process. */ drvdata->pid = pid; drvdata->mode = CS_MODE_PERF; - atomic_inc(csdev->refcnt); + atomic_inc(&csdev->refcnt); } out: @@ -356,7 +356,7 @@ static int etb_disable(struct coresight_device *csdev) spin_lock_irqsave(&drvdata->spinlock, flags); - if (atomic_dec_return(csdev->refcnt)) { + if (atomic_dec_return(&csdev->refcnt)) { spin_unlock_irqrestore(&drvdata->spinlock, flags); return -EBUSY; } @@ -447,7 +447,7 @@ static unsigned long etb_update_buffer(struct coresight_device *csdev, spin_lock_irqsave(&drvdata->spinlock, flags); /* Don't do anything if another tracer is using this sink */ - if (atomic_read(csdev->refcnt) != 1) + if (atomic_read(&csdev->refcnt) != 1) goto out; __etb_disable_hw(drvdata); diff --git a/drivers/hwtracing/coresight/coresight-funnel.c b/drivers/hwtracing/coresight/coresight-funnel.c index b363dd6bc510..b8e150e45b27 100644 --- a/drivers/hwtracing/coresight/coresight-funnel.c +++ b/drivers/hwtracing/coresight/coresight-funnel.c @@ -74,8 +74,9 @@ done: return rc; } -static int funnel_enable(struct coresight_device *csdev, int inport, - int outport) +static int funnel_enable(struct coresight_device *csdev, + struct coresight_connection *in, + struct coresight_connection *out) { int rc = 0; struct funnel_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); @@ -83,18 +84,19 @@ static int funnel_enable(struct coresight_device *csdev, int inport, bool first_enable = false; spin_lock_irqsave(&drvdata->spinlock, flags); - if (atomic_read(&csdev->refcnt[inport]) == 0) { + if (atomic_read(&in->dest_refcnt) == 0) { if (drvdata->base) - rc = dynamic_funnel_enable_hw(drvdata, inport); + rc = dynamic_funnel_enable_hw(drvdata, in->dest_port); if (!rc) first_enable = true; } if (!rc) - atomic_inc(&csdev->refcnt[inport]); + atomic_inc(&in->dest_refcnt); spin_unlock_irqrestore(&drvdata->spinlock, flags); if (first_enable) - dev_dbg(&csdev->dev, "FUNNEL inport %d enabled\n", inport); + dev_dbg(&csdev->dev, "FUNNEL inport %d enabled\n", + in->dest_port); return rc; } @@ -117,23 +119,25 @@ static void dynamic_funnel_disable_hw(struct funnel_drvdata *drvdata, CS_LOCK(drvdata->base); } -static void funnel_disable(struct coresight_device *csdev, int inport, - int outport) +static void funnel_disable(struct coresight_device *csdev, + struct coresight_connection *in, + struct coresight_connection *out) { struct funnel_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); unsigned long flags; bool last_disable = false; spin_lock_irqsave(&drvdata->spinlock, flags); - if (atomic_dec_return(&csdev->refcnt[inport]) == 0) { + if (atomic_dec_return(&in->dest_refcnt) == 0) { if (drvdata->base) - dynamic_funnel_disable_hw(drvdata, inport); + dynamic_funnel_disable_hw(drvdata, in->dest_port); last_disable = true; } spin_unlock_irqrestore(&drvdata->spinlock, flags); if (last_disable) - dev_dbg(&csdev->dev, "FUNNEL inport %d disabled\n", inport); + dev_dbg(&csdev->dev, "FUNNEL inport %d disabled\n", + in->dest_port); } static const struct coresight_ops_link funnel_link_ops = { diff --git a/drivers/hwtracing/coresight/coresight-platform.c b/drivers/hwtracing/coresight/coresight-platform.c index 257ad48925a1..3e2e135cb8f6 100644 --- a/drivers/hwtracing/coresight/coresight-platform.c +++ b/drivers/hwtracing/coresight/coresight-platform.c @@ -146,41 +146,6 @@ static inline bool of_coresight_legacy_ep_is_input(struct device_node *ep) return of_property_read_bool(ep, "slave-mode"); } -static void of_coresight_get_ports_legacy(const struct device_node *node, - int *nr_inconns, int *nr_outconns) -{ - struct device_node *ep = NULL; - struct of_endpoint endpoint; - int in = 0, out = 0; - - /* - * Avoid warnings in of_graph_get_next_endpoint() - * if the device doesn't have any graph connections - */ - if (!of_graph_is_present(node)) - return; - do { - ep = of_graph_get_next_endpoint(node, ep); - if (!ep) - break; - - if (of_graph_parse_endpoint(ep, &endpoint)) - continue; - - if (of_coresight_legacy_ep_is_input(ep)) { - in = (endpoint.port + 1 > in) ? - endpoint.port + 1 : in; - } else { - out = (endpoint.port + 1) > out ? - endpoint.port + 1 : out; - } - - } while (ep); - - *nr_inconns = in; - *nr_outconns = out; -} - static struct device_node *of_coresight_get_port_parent(struct device_node *ep) { struct device_node *parent = of_graph_get_port_parent(ep); @@ -196,59 +161,12 @@ static struct device_node *of_coresight_get_port_parent(struct device_node *ep) return parent; } -static inline struct device_node * -of_coresight_get_input_ports_node(const struct device_node *node) -{ - return of_get_child_by_name(node, "in-ports"); -} - static inline struct device_node * of_coresight_get_output_ports_node(const struct device_node *node) { return of_get_child_by_name(node, "out-ports"); } -static inline int -of_coresight_count_ports(struct device_node *port_parent) -{ - int i = 0; - struct device_node *ep = NULL; - struct of_endpoint endpoint; - - while ((ep = of_graph_get_next_endpoint(port_parent, ep))) { - /* Defer error handling to parsing */ - if (of_graph_parse_endpoint(ep, &endpoint)) - continue; - if (endpoint.port + 1 > i) - i = endpoint.port + 1; - } - - return i; -} - -static void of_coresight_get_ports(const struct device_node *node, - int *nr_inconns, int *nr_outconns) -{ - struct device_node *input_ports = NULL, *output_ports = NULL; - - input_ports = of_coresight_get_input_ports_node(node); - output_ports = of_coresight_get_output_ports_node(node); - - if (input_ports || output_ports) { - if (input_ports) { - *nr_inconns = of_coresight_count_ports(input_ports); - of_node_put(input_ports); - } - if (output_ports) { - *nr_outconns = of_coresight_count_ports(output_ports); - of_node_put(output_ports); - } - } else { - /* Fall back to legacy DT bindings parsing */ - of_coresight_get_ports_legacy(node, nr_inconns, nr_outconns); - } -} - static int of_coresight_get_cpu(struct device *dev) { int cpu; @@ -351,13 +269,6 @@ static int of_get_coresight_platform_data(struct device *dev, bool legacy_binding = false; struct device_node *node = dev->of_node; - /* Get the number of input and output port for this component */ - of_coresight_get_ports(node, &pdata->high_inport, &pdata->high_outport); - - /* If there are no output connections, we are done */ - if (!pdata->high_outport) - return 0; - parent = of_coresight_get_output_ports_node(node); /* * If the DT uses obsoleted bindings, the ports are listed @@ -365,6 +276,12 @@ static int of_get_coresight_platform_data(struct device *dev, * ports. */ if (!parent) { + /* + * Avoid warnings in of_graph_get_next_endpoint() + * if the device doesn't have any graph connections + */ + if (!of_graph_is_present(node)) + return 0; legacy_binding = true; parent = node; dev_warn_once(dev, "Uses obsolete Coresight DT bindings\n"); @@ -751,7 +668,6 @@ static int acpi_coresight_parse_graph(struct device *dev, struct coresight_connection conn, zero_conn = {}; struct coresight_connection *new_conn; - pdata->nr_inconns = pdata->nr_outconns = 0; graph = acpi_get_coresight_graph(adev); if (!graph) return -ENOENT; @@ -770,22 +686,9 @@ static int acpi_coresight_parse_graph(struct device *dev, return dir; if (dir == ACPI_CORESIGHT_LINK_MASTER) { - if (conn.src_port >= pdata->high_outport) - pdata->high_outport = conn.src_port + 1; new_conn = coresight_add_out_conn(dev, pdata, &conn); if (IS_ERR(new_conn)) return PTR_ERR(new_conn); - } else { - WARN_ON(pdata->high_inport == conn.dest_port + 1); - /* - * We do not track input port connections for a device. - * However we need the highest port number described, - * which can be recorded now and reuse this connection - * record for an output connection. Hence, do not move - * the ptr for input connections - */ - if (conn.dest_port >= pdata->high_inport) - pdata->high_inport = conn.dest_port + 1; } } diff --git a/drivers/hwtracing/coresight/coresight-replicator.c b/drivers/hwtracing/coresight/coresight-replicator.c index 4dd50546d7e4..b6be73034996 100644 --- a/drivers/hwtracing/coresight/coresight-replicator.c +++ b/drivers/hwtracing/coresight/coresight-replicator.c @@ -114,8 +114,9 @@ static int dynamic_replicator_enable(struct replicator_drvdata *drvdata, return rc; } -static int replicator_enable(struct coresight_device *csdev, int inport, - int outport) +static int replicator_enable(struct coresight_device *csdev, + struct coresight_connection *in, + struct coresight_connection *out) { int rc = 0; struct replicator_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); @@ -123,15 +124,15 @@ static int replicator_enable(struct coresight_device *csdev, int inport, bool first_enable = false; spin_lock_irqsave(&drvdata->spinlock, flags); - if (atomic_read(&csdev->refcnt[outport]) == 0) { + if (atomic_read(&out->src_refcnt) == 0) { if (drvdata->base) - rc = dynamic_replicator_enable(drvdata, inport, - outport); + rc = dynamic_replicator_enable(drvdata, in->dest_port, + out->src_port); if (!rc) first_enable = true; } if (!rc) - atomic_inc(&csdev->refcnt[outport]); + atomic_inc(&out->src_refcnt); spin_unlock_irqrestore(&drvdata->spinlock, flags); if (first_enable) @@ -168,17 +169,19 @@ static void dynamic_replicator_disable(struct replicator_drvdata *drvdata, CS_LOCK(drvdata->base); } -static void replicator_disable(struct coresight_device *csdev, int inport, - int outport) +static void replicator_disable(struct coresight_device *csdev, + struct coresight_connection *in, + struct coresight_connection *out) { struct replicator_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); unsigned long flags; bool last_disable = false; spin_lock_irqsave(&drvdata->spinlock, flags); - if (atomic_dec_return(&csdev->refcnt[outport]) == 0) { + if (atomic_dec_return(&out->src_refcnt) == 0) { if (drvdata->base) - dynamic_replicator_disable(drvdata, inport, outport); + dynamic_replicator_disable(drvdata, in->dest_port, + out->src_port); last_disable = true; } spin_unlock_irqrestore(&drvdata->spinlock, flags); diff --git a/drivers/hwtracing/coresight/coresight-tmc-etf.c b/drivers/hwtracing/coresight/coresight-tmc-etf.c index 14d3c1472455..79d8c64eac49 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-etf.c +++ b/drivers/hwtracing/coresight/coresight-tmc-etf.c @@ -206,7 +206,7 @@ static int tmc_enable_etf_sink_sysfs(struct coresight_device *csdev) * touched. */ if (drvdata->mode == CS_MODE_SYSFS) { - atomic_inc(csdev->refcnt); + atomic_inc(&csdev->refcnt); goto out; } @@ -229,7 +229,7 @@ static int tmc_enable_etf_sink_sysfs(struct coresight_device *csdev) ret = tmc_etb_enable_hw(drvdata); if (!ret) { drvdata->mode = CS_MODE_SYSFS; - atomic_inc(csdev->refcnt); + atomic_inc(&csdev->refcnt); } else { /* Free up the buffer if we failed to enable */ used = false; @@ -284,7 +284,7 @@ static int tmc_enable_etf_sink_perf(struct coresight_device *csdev, void *data) * use for this session. */ if (drvdata->pid == pid) { - atomic_inc(csdev->refcnt); + atomic_inc(&csdev->refcnt); break; } @@ -293,7 +293,7 @@ static int tmc_enable_etf_sink_perf(struct coresight_device *csdev, void *data) /* Associate with monitored process. */ drvdata->pid = pid; drvdata->mode = CS_MODE_PERF; - atomic_inc(csdev->refcnt); + atomic_inc(&csdev->refcnt); } } while (0); spin_unlock_irqrestore(&drvdata->spinlock, flags); @@ -338,7 +338,7 @@ static int tmc_disable_etf_sink(struct coresight_device *csdev) return -EBUSY; } - if (atomic_dec_return(csdev->refcnt)) { + if (atomic_dec_return(&csdev->refcnt)) { spin_unlock_irqrestore(&drvdata->spinlock, flags); return -EBUSY; } @@ -357,7 +357,8 @@ static int tmc_disable_etf_sink(struct coresight_device *csdev) } static int tmc_enable_etf_link(struct coresight_device *csdev, - int inport, int outport) + struct coresight_connection *in, + struct coresight_connection *out) { int ret = 0; unsigned long flags; @@ -370,7 +371,7 @@ static int tmc_enable_etf_link(struct coresight_device *csdev, return -EBUSY; } - if (atomic_read(&csdev->refcnt[0]) == 0) { + if (atomic_read(&csdev->refcnt) == 0) { ret = tmc_etf_enable_hw(drvdata); if (!ret) { drvdata->mode = CS_MODE_SYSFS; @@ -378,7 +379,7 @@ static int tmc_enable_etf_link(struct coresight_device *csdev, } } if (!ret) - atomic_inc(&csdev->refcnt[0]); + atomic_inc(&csdev->refcnt); spin_unlock_irqrestore(&drvdata->spinlock, flags); if (first_enable) @@ -387,7 +388,8 @@ static int tmc_enable_etf_link(struct coresight_device *csdev, } static void tmc_disable_etf_link(struct coresight_device *csdev, - int inport, int outport) + struct coresight_connection *in, + struct coresight_connection *out) { unsigned long flags; struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); @@ -399,7 +401,7 @@ static void tmc_disable_etf_link(struct coresight_device *csdev, return; } - if (atomic_dec_return(&csdev->refcnt[0]) == 0) { + if (atomic_dec_return(&csdev->refcnt) == 0) { tmc_etf_disable_hw(drvdata); drvdata->mode = CS_MODE_DISABLED; last_disable = true; @@ -487,7 +489,7 @@ static unsigned long tmc_update_etf_buffer(struct coresight_device *csdev, spin_lock_irqsave(&drvdata->spinlock, flags); /* Don't do anything if another tracer is using this sink */ - if (atomic_read(csdev->refcnt) != 1) + if (atomic_read(&csdev->refcnt) != 1) goto out; CS_UNLOCK(drvdata->base); diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c index e4493647d66d..23fa70cc2098 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c @@ -1209,7 +1209,7 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev) * touched, even if the buffer size has changed. */ if (drvdata->mode == CS_MODE_SYSFS) { - atomic_inc(csdev->refcnt); + atomic_inc(&csdev->refcnt); goto out; } @@ -1226,7 +1226,7 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev) ret = tmc_etr_enable_hw(drvdata, drvdata->sysfs_buf); if (!ret) { drvdata->mode = CS_MODE_SYSFS; - atomic_inc(csdev->refcnt); + atomic_inc(&csdev->refcnt); } out: spin_unlock_irqrestore(&drvdata->spinlock, flags); @@ -1535,7 +1535,7 @@ tmc_update_etr_buffer(struct coresight_device *csdev, spin_lock_irqsave(&drvdata->spinlock, flags); /* Don't do anything if another tracer is using this sink */ - if (atomic_read(csdev->refcnt) != 1) { + if (atomic_read(&csdev->refcnt) != 1) { spin_unlock_irqrestore(&drvdata->spinlock, flags); goto out; } @@ -1647,7 +1647,7 @@ static int tmc_enable_etr_sink_perf(struct coresight_device *csdev, void *data) * use for this session. */ if (drvdata->pid == pid) { - atomic_inc(csdev->refcnt); + atomic_inc(&csdev->refcnt); goto unlock_out; } @@ -1657,7 +1657,7 @@ static int tmc_enable_etr_sink_perf(struct coresight_device *csdev, void *data) drvdata->pid = pid; drvdata->mode = CS_MODE_PERF; drvdata->perf_buf = etr_perf->etr_buf; - atomic_inc(csdev->refcnt); + atomic_inc(&csdev->refcnt); } unlock_out: @@ -1690,7 +1690,7 @@ static int tmc_disable_etr_sink(struct coresight_device *csdev) return -EBUSY; } - if (atomic_dec_return(csdev->refcnt)) { + if (atomic_dec_return(&csdev->refcnt)) { spin_unlock_irqrestore(&drvdata->spinlock, flags); return -EBUSY; } diff --git a/drivers/hwtracing/coresight/coresight-tpda.c b/drivers/hwtracing/coresight/coresight-tpda.c index f712e112ecff..8d2b9d29237d 100644 --- a/drivers/hwtracing/coresight/coresight-tpda.c +++ b/drivers/hwtracing/coresight/coresight-tpda.c @@ -54,18 +54,20 @@ static void __tpda_enable(struct tpda_drvdata *drvdata, int port) CS_LOCK(drvdata->base); } -static int tpda_enable(struct coresight_device *csdev, int inport, int outport) +static int tpda_enable(struct coresight_device *csdev, + struct coresight_connection *in, + struct coresight_connection *out) { struct tpda_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); spin_lock(&drvdata->spinlock); - if (atomic_read(&csdev->refcnt[inport]) == 0) - __tpda_enable(drvdata, inport); + if (atomic_read(&in->dest_refcnt) == 0) + __tpda_enable(drvdata, in->dest_port); - atomic_inc(&csdev->refcnt[inport]); + atomic_inc(&in->dest_refcnt); spin_unlock(&drvdata->spinlock); - dev_dbg(drvdata->dev, "TPDA inport %d enabled.\n", inport); + dev_dbg(drvdata->dev, "TPDA inport %d enabled.\n", in->dest_port); return 0; } @@ -82,18 +84,19 @@ static void __tpda_disable(struct tpda_drvdata *drvdata, int port) CS_LOCK(drvdata->base); } -static void tpda_disable(struct coresight_device *csdev, int inport, - int outport) +static void tpda_disable(struct coresight_device *csdev, + struct coresight_connection *in, + struct coresight_connection *out) { struct tpda_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); spin_lock(&drvdata->spinlock); - if (atomic_dec_return(&csdev->refcnt[inport]) == 0) - __tpda_disable(drvdata, inport); + if (atomic_dec_return(&in->dest_refcnt) == 0) + __tpda_disable(drvdata, in->dest_port); spin_unlock(&drvdata->spinlock); - dev_dbg(drvdata->dev, "TPDA inport %d disabled\n", inport); + dev_dbg(drvdata->dev, "TPDA inport %d disabled\n", in->dest_port); } static const struct coresight_ops_link tpda_link_ops = { diff --git a/drivers/hwtracing/coresight/coresight-tpiu.c b/drivers/hwtracing/coresight/coresight-tpiu.c index b0179f761c98..59eac93fd6bb 100644 --- a/drivers/hwtracing/coresight/coresight-tpiu.c +++ b/drivers/hwtracing/coresight/coresight-tpiu.c @@ -73,7 +73,7 @@ static int tpiu_enable(struct coresight_device *csdev, enum cs_mode mode, void *__unused) { tpiu_enable_hw(&csdev->access); - atomic_inc(csdev->refcnt); + atomic_inc(&csdev->refcnt); dev_dbg(&csdev->dev, "TPIU enabled\n"); return 0; } @@ -96,7 +96,7 @@ static void tpiu_disable_hw(struct csdev_access *csa) static int tpiu_disable(struct coresight_device *csdev) { - if (atomic_dec_return(csdev->refcnt)) + if (atomic_dec_return(&csdev->refcnt)) return -EBUSY; tpiu_disable_hw(&csdev->access); diff --git a/drivers/hwtracing/coresight/ultrasoc-smb.c b/drivers/hwtracing/coresight/ultrasoc-smb.c index a2ced0b3c3cd..e9a32a97fbee 100644 --- a/drivers/hwtracing/coresight/ultrasoc-smb.c +++ b/drivers/hwtracing/coresight/ultrasoc-smb.c @@ -106,7 +106,7 @@ static int smb_open(struct inode *inode, struct file *file) goto out; } - if (atomic_read(drvdata->csdev->refcnt)) { + if (atomic_read(&drvdata->csdev->refcnt)) { ret = -EBUSY; goto out; } @@ -290,7 +290,7 @@ static int smb_enable(struct coresight_device *csdev, enum cs_mode mode, if (ret) goto out; - atomic_inc(csdev->refcnt); + atomic_inc(&csdev->refcnt); dev_dbg(&csdev->dev, "Ultrasoc SMB enabled\n"); out: @@ -311,7 +311,7 @@ static int smb_disable(struct coresight_device *csdev) goto out; } - if (atomic_dec_return(csdev->refcnt)) { + if (atomic_dec_return(&csdev->refcnt)) { ret = -EBUSY; goto out; } @@ -411,7 +411,7 @@ static unsigned long smb_update_buffer(struct coresight_device *csdev, mutex_lock(&drvdata->mutex); /* Don't do anything if another tracer is using this sink. */ - if (atomic_read(csdev->refcnt) != 1) + if (atomic_read(&csdev->refcnt) != 1) goto out; smb_disable_hw(drvdata); diff --git a/include/linux/coresight.h b/include/linux/coresight.h index e9c52c5ca7f3..b97edd24f3ec 100644 --- a/include/linux/coresight.h +++ b/include/linux/coresight.h @@ -111,8 +111,6 @@ union coresight_dev_subtype { * unloaded the connection leaves an empty slot. */ struct coresight_platform_data { - int high_inport; - int high_outport; int nr_inconns; int nr_outconns; struct coresight_connection **out_conns; @@ -205,6 +203,8 @@ struct coresight_connection { struct coresight_device *dest_dev; struct coresight_sysfs_link *link; struct coresight_device *src_dev; + atomic_t src_refcnt; + atomic_t dest_refcnt; }; /** @@ -256,7 +256,7 @@ struct coresight_device { const struct coresight_ops *ops; struct csdev_access access; struct device dev; - atomic_t *refcnt; + atomic_t refcnt; bool orphan; bool enable; /* true only if configured as part of a path */ /* sink specific fields */ @@ -341,8 +341,12 @@ struct coresight_ops_sink { * @disable: disables flow between iport and oport. */ struct coresight_ops_link { - int (*enable)(struct coresight_device *csdev, int iport, int oport); - void (*disable)(struct coresight_device *csdev, int iport, int oport); + int (*enable)(struct coresight_device *csdev, + struct coresight_connection *in, + struct coresight_connection *out); + void (*disable)(struct coresight_device *csdev, + struct coresight_connection *in, + struct coresight_connection *out); }; /** -- cgit v1.2.3