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 <mike.leach@linaro.org> Signed-off-by: James Clark <james.clark@arm.com> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> Link: https://lore.kernel.org/r/20230425143542.2305069-8-james.clark@arm.com
This commit is contained in:
parent
3d4ff657e4
commit
4e8fe7e5c3
|
@ -119,7 +119,7 @@ static int coresight_find_link_inport(struct coresight_device *csdev,
|
||||||
struct coresight_connection *conn;
|
struct coresight_connection *conn;
|
||||||
|
|
||||||
for (i = 0; i < parent->pdata->nr_outconns; i++) {
|
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)
|
if (conn->dest_dev == csdev)
|
||||||
return conn->dest_port;
|
return conn->dest_port;
|
||||||
}
|
}
|
||||||
|
@ -137,7 +137,7 @@ static int coresight_find_link_outport(struct coresight_device *csdev,
|
||||||
struct coresight_connection *conn;
|
struct coresight_connection *conn;
|
||||||
|
|
||||||
for (i = 0; i < csdev->pdata->nr_outconns; i++) {
|
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)
|
if (conn->dest_dev == child)
|
||||||
return conn->src_port;
|
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++) {
|
for (i = 0; i < csdev->pdata->nr_outconns; i++) {
|
||||||
struct coresight_device *child_dev;
|
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)
|
if (child_dev)
|
||||||
sink = coresight_find_enabled_sink(child_dev);
|
sink = coresight_find_enabled_sink(child_dev);
|
||||||
if (sink)
|
if (sink)
|
||||||
|
@ -722,7 +722,7 @@ static int coresight_grab_device(struct coresight_device *csdev)
|
||||||
for (i = 0; i < csdev->pdata->nr_outconns; i++) {
|
for (i = 0; i < csdev->pdata->nr_outconns; i++) {
|
||||||
struct coresight_device *child;
|
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 (child && child->type == CORESIGHT_DEV_TYPE_HELPER)
|
||||||
if (!coresight_get_ref(child))
|
if (!coresight_get_ref(child))
|
||||||
goto err;
|
goto err;
|
||||||
|
@ -733,7 +733,7 @@ err:
|
||||||
for (i--; i >= 0; i--) {
|
for (i--; i >= 0; i--) {
|
||||||
struct coresight_device *child;
|
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 (child && child->type == CORESIGHT_DEV_TYPE_HELPER)
|
||||||
coresight_put_ref(child);
|
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++) {
|
for (i = 0; i < csdev->pdata->nr_outconns; i++) {
|
||||||
struct coresight_device *child;
|
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 (child && child->type == CORESIGHT_DEV_TYPE_HELPER)
|
||||||
coresight_put_ref(child);
|
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++) {
|
for (i = 0; i < csdev->pdata->nr_outconns; i++) {
|
||||||
struct coresight_device *child_dev;
|
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 &&
|
if (child_dev &&
|
||||||
_coresight_build_path(child_dev, sink, path) == 0) {
|
_coresight_build_path(child_dev, sink, path) == 0) {
|
||||||
found = true;
|
found = true;
|
||||||
|
@ -964,7 +964,7 @@ coresight_find_sink(struct coresight_device *csdev, int *depth)
|
||||||
struct coresight_device *child_dev, *sink = NULL;
|
struct coresight_device *child_dev, *sink = NULL;
|
||||||
int child_depth = curr_depth;
|
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)
|
if (child_dev)
|
||||||
sink = coresight_find_sink(child_dev, &child_depth);
|
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.
|
* an orphan connection whose name matches @csdev, link it.
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < i_csdev->pdata->nr_outconns; i++) {
|
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 */
|
/* We have found at least one orphan connection */
|
||||||
if (conn->dest_dev == NULL) {
|
if (conn->dest_dev == NULL) {
|
||||||
|
@ -1372,7 +1372,7 @@ static int coresight_fixup_device_conns(struct coresight_device *csdev)
|
||||||
int i, ret = 0;
|
int i, ret = 0;
|
||||||
|
|
||||||
for (i = 0; i < csdev->pdata->nr_outconns; i++) {
|
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 =
|
conn->dest_dev =
|
||||||
coresight_find_csdev_by_fwnode(conn->dest_fwnode);
|
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.
|
* a connection whose name matches @csdev, remove it.
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < iterator->pdata->nr_outconns; i++) {
|
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)
|
/* Child_dev being set signifies that the links were made */
|
||||||
continue;
|
if (csdev->dev.fwnode == conn->dest_fwnode && conn->dest_dev) {
|
||||||
|
|
||||||
if (csdev->dev.fwnode == conn->dest_fwnode) {
|
|
||||||
iterator->orphan = true;
|
iterator->orphan = true;
|
||||||
coresight_remove_links(iterator, conn);
|
coresight_remove_links(iterator, conn);
|
||||||
|
|
||||||
conn->dest_dev = NULL;
|
conn->dest_dev = NULL;
|
||||||
/* No need to continue */
|
/* No need to continue */
|
||||||
break;
|
break;
|
||||||
|
@ -1534,22 +1531,26 @@ void coresight_write64(struct coresight_device *csdev, u64 val, u32 offset)
|
||||||
* to the output port of this device.
|
* to the output port of this device.
|
||||||
*/
|
*/
|
||||||
void coresight_release_platform_data(struct coresight_device *csdev,
|
void coresight_release_platform_data(struct coresight_device *csdev,
|
||||||
|
struct device *dev,
|
||||||
struct coresight_platform_data *pdata)
|
struct coresight_platform_data *pdata)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
struct coresight_connection *conns = pdata->out_conns;
|
struct coresight_connection **conns = pdata->out_conns;
|
||||||
|
|
||||||
for (i = 0; i < pdata->nr_outconns; i++) {
|
for (i = 0; i < pdata->nr_outconns; i++) {
|
||||||
/* If we have made the links, remove them now */
|
/* If we have made the links, remove them now */
|
||||||
if (csdev && conns[i].dest_dev)
|
if (csdev && conns[i]->dest_dev)
|
||||||
coresight_remove_links(csdev, &conns[i]);
|
coresight_remove_links(csdev, conns[i]);
|
||||||
/*
|
/*
|
||||||
* Drop the refcount and clear the handle as this device
|
* Drop the refcount and clear the handle as this device
|
||||||
* is going away
|
* is going away
|
||||||
*/
|
*/
|
||||||
fwnode_handle_put(conns[i].dest_fwnode);
|
fwnode_handle_put(conns[i]->dest_fwnode);
|
||||||
conns[i].dest_fwnode = NULL;
|
conns[i]->dest_fwnode = NULL;
|
||||||
|
devm_kfree(dev, conns[i]);
|
||||||
}
|
}
|
||||||
|
devm_kfree(dev, pdata->out_conns);
|
||||||
|
devm_kfree(dev, pdata);
|
||||||
if (csdev)
|
if (csdev)
|
||||||
coresight_remove_conns_sysfs_group(csdev);
|
coresight_remove_conns_sysfs_group(csdev);
|
||||||
}
|
}
|
||||||
|
@ -1666,7 +1667,7 @@ out_unlock:
|
||||||
|
|
||||||
err_out:
|
err_out:
|
||||||
/* Cleanup the connection information */
|
/* Cleanup the connection information */
|
||||||
coresight_release_platform_data(NULL, desc->pdata);
|
coresight_release_platform_data(NULL, desc->dev, desc->pdata);
|
||||||
return ERR_PTR(ret);
|
return ERR_PTR(ret);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(coresight_register);
|
EXPORT_SYMBOL_GPL(coresight_register);
|
||||||
|
@ -1679,7 +1680,7 @@ void coresight_unregister(struct coresight_device *csdev)
|
||||||
cti_assoc_ops->remove(csdev);
|
cti_assoc_ops->remove(csdev);
|
||||||
coresight_remove_conns(csdev);
|
coresight_remove_conns(csdev);
|
||||||
coresight_clear_default_sink(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);
|
device_unregister(&csdev->dev);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(coresight_unregister);
|
EXPORT_SYMBOL_GPL(coresight_unregister);
|
||||||
|
|
|
@ -37,7 +37,7 @@ coresight_add_out_conn(struct device *dev,
|
||||||
* Warn on any existing duplicate output port.
|
* Warn on any existing duplicate output port.
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < pdata->nr_outconns; ++i) {
|
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 */
|
/* Output == -1 means ignore the port for example for helpers */
|
||||||
if (conn->src_port != -1 &&
|
if (conn->src_port != -1 &&
|
||||||
conn->src_port == new_conn->src_port) {
|
conn->src_port == new_conn->src_port) {
|
||||||
|
@ -54,8 +54,19 @@ coresight_add_out_conn(struct device *dev,
|
||||||
if (!pdata->out_conns)
|
if (!pdata->out_conns)
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|
||||||
pdata->out_conns[pdata->nr_outconns - 1] = *new_conn;
|
conn = devm_kmalloc(dev, sizeof(struct coresight_connection),
|
||||||
return &pdata->out_conns[pdata->nr_outconns - 1];
|
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);
|
EXPORT_SYMBOL_GPL(coresight_add_out_conn);
|
||||||
|
|
||||||
|
@ -863,7 +874,7 @@ coresight_get_platform_data(struct device *dev)
|
||||||
error:
|
error:
|
||||||
if (!IS_ERR_OR_NULL(pdata))
|
if (!IS_ERR_OR_NULL(pdata))
|
||||||
/* Cleanup the connection information */
|
/* Cleanup the connection information */
|
||||||
coresight_release_platform_data(NULL, pdata);
|
coresight_release_platform_data(NULL, dev, pdata);
|
||||||
return ERR_PTR(ret);
|
return ERR_PTR(ret);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(coresight_get_platform_data);
|
EXPORT_SYMBOL_GPL(coresight_get_platform_data);
|
||||||
|
|
|
@ -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,
|
void coresight_release_platform_data(struct coresight_device *csdev,
|
||||||
|
struct device *dev,
|
||||||
struct coresight_platform_data *pdata);
|
struct coresight_platform_data *pdata);
|
||||||
struct coresight_device *
|
struct coresight_device *
|
||||||
coresight_find_csdev_by_fwnode(struct fwnode_handle *r_fwnode);
|
coresight_find_csdev_by_fwnode(struct fwnode_handle *r_fwnode);
|
||||||
|
|
|
@ -782,7 +782,7 @@ tmc_etr_get_catu_device(struct tmc_drvdata *drvdata)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
for (i = 0; i < etr->pdata->nr_outconns; i++) {
|
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))
|
if (tmp && coresight_is_catu_device(tmp))
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,14 +104,15 @@ union coresight_dev_subtype {
|
||||||
*
|
*
|
||||||
* @nr_inconns: Number of elements for the input connections.
|
* @nr_inconns: Number of elements for the input connections.
|
||||||
* @nr_outconns: Number of elements for the output 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 {
|
struct coresight_platform_data {
|
||||||
int high_inport;
|
int high_inport;
|
||||||
int high_outport;
|
int high_outport;
|
||||||
int nr_inconns;
|
int nr_inconns;
|
||||||
int nr_outconns;
|
int nr_outconns;
|
||||||
struct coresight_connection *out_conns;
|
struct coresight_connection **out_conns;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue