in coresight/coresight-platform.c [217:280]
static int of_coresight_parse_endpoint(struct device *dev,
struct device_node *ep,
struct coresight_platform_data *pdata)
{
int ret = 0;
struct of_endpoint endpoint, rendpoint;
struct device_node *rparent = NULL;
struct device_node *rep = NULL;
struct device *rdev = NULL;
struct fwnode_handle *rdev_fwnode;
struct coresight_connection *conn;
do {
/* Parse the local port details */
if (of_graph_parse_endpoint(ep, &endpoint))
break;
/*
* Get a handle on the remote endpoint and the device it is
* attached to.
*/
rep = of_graph_get_remote_endpoint(ep);
if (!rep)
break;
rparent = of_coresight_get_port_parent(rep);
if (!rparent)
break;
if (of_graph_parse_endpoint(rep, &rendpoint))
break;
rdev_fwnode = of_fwnode_handle(rparent);
/* If the remote device is not available, defer probing */
rdev = coresight_find_device_by_fwnode(rdev_fwnode);
if (!rdev) {
ret = -EPROBE_DEFER;
break;
}
conn = &pdata->conns[endpoint.port];
if (conn->child_fwnode) {
dev_warn(dev, "Duplicate output port %d\n",
endpoint.port);
ret = -EINVAL;
break;
}
conn->outport = endpoint.port;
/*
* Hold the refcount to the target device. This could be
* released via:
* 1) coresight_release_platform_data() if the probe fails or
* this device is unregistered.
* 2) While removing the target device via
* coresight_remove_match()
*/
conn->child_fwnode = fwnode_handle_get(rdev_fwnode);
conn->child_port = rendpoint.port;
/* Connection record updated */
} while (0);
of_node_put(rparent);
of_node_put(rep);
put_device(rdev);
return ret;
}