static int of_coresight_parse_endpoint()

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;
}