Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 055b8f44 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "coresight: Fix support for sparsely populated ports"

parents 49dec8e0 d2c7a07e
Loading
Loading
Loading
Loading
+62 −25
Original line number Diff line number Diff line
@@ -67,6 +67,7 @@ static void of_coresight_get_ports_legacy(const struct device_node *node,
					  int *nr_inport, int *nr_outport)
{
	struct device_node *ep = NULL;
	struct of_endpoint endpoint;
	int in = 0, out = 0;

	do {
@@ -74,10 +75,16 @@ static void of_coresight_get_ports_legacy(const struct device_node *node,
		if (!ep)
			break;

		if (of_coresight_legacy_ep_is_input(ep))
			in++;
		else
			out++;
		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);

@@ -117,9 +124,16 @@ 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;
	}

	while ((ep = of_graph_get_next_endpoint(port_parent, ep)))
		i++;
	return i;
}

@@ -171,14 +185,12 @@ static int of_coresight_get_cpu(struct device *dev)
 * Parses the local port, remote device name and the remote port.
 *
 * Returns :
 *	 1	- If the parsing is successful and a connection record
 *		  was created for an output connection.
 *	 0	- If the parsing completed without any fatal errors.
 *	-Errno	- Fatal error, abort the scanning.
 */
static int of_coresight_parse_endpoint(struct device *dev,
				       struct device_node *ep,
				       struct coresight_connection *conn)
				       struct coresight_platform_data *pdata)
{
	int ret = 0;
	struct of_endpoint endpoint, rendpoint;
@@ -189,6 +201,7 @@ static int of_coresight_parse_endpoint(struct device *dev,
#endif
	struct device *rdev = NULL;
	struct fwnode_handle *rdev_fwnode;
	struct coresight_connection *conn;

	do {
		/* Parse the local port details */
@@ -215,6 +228,14 @@ static int of_coresight_parse_endpoint(struct device *dev,
			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
@@ -236,7 +257,6 @@ static int of_coresight_parse_endpoint(struct device *dev,
		}
#endif
		/* Connection record updated */
		ret = 1;
	} while (0);

	of_node_put(rparent);
@@ -303,7 +323,6 @@ static int of_get_coresight_platform_data(struct device *dev,
					  struct coresight_platform_data *pdata)
{
	int ret = 0;
	struct coresight_connection *conn;
	struct device_node *ep = NULL;
	const struct device_node *parent = NULL;
	bool legacy_binding = false;
@@ -337,8 +356,6 @@ static int of_get_coresight_platform_data(struct device *dev,
		dev_warn_once(dev, "Uses obsolete Coresight DT bindings\n");
	}

	conn = pdata->conns;

	/* Iterate through each output port to discover topology */
	while ((ep = of_graph_get_next_endpoint(parent, ep))) {
		/*
@@ -350,16 +367,10 @@ static int of_get_coresight_platform_data(struct device *dev,
		if (legacy_binding && of_coresight_legacy_ep_is_input(ep))
			continue;

		ret = of_coresight_parse_endpoint(dev, ep, conn);
		switch (ret) {
		case 1:
			conn++;		/* Fall through */
		case 0:
			break;
		default:
		ret = of_coresight_parse_endpoint(dev, ep, pdata);
		if (ret)
			return ret;
	}
	}

	return 0;
}
@@ -697,6 +708,16 @@ static int acpi_coresight_parse_link(struct acpi_device *adev,
		 *    coresight_remove_match().
		 */
		conn->child_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;
	} else {
		/* Invalid direction */
		return -EINVAL;
	}

	return dir;
@@ -742,10 +763,20 @@ static int acpi_coresight_parse_graph(struct acpi_device *adev,
			return dir;

		if (dir == ACPI_CORESIGHT_LINK_MASTER) {
			pdata->nr_outport++;
			if (ptr->outport > pdata->nr_outport)
				pdata->nr_outport = ptr->outport;
			ptr++;
		} else {
			pdata->nr_inport++;
			WARN_ON(pdata->nr_inport == ptr->child_port);
			/*
			 * 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 (ptr->child_port > pdata->nr_inport)
				pdata->nr_inport = ptr->child_port;
		}
	}

@@ -754,8 +785,14 @@ static int acpi_coresight_parse_graph(struct acpi_device *adev,
		return rc;

	/* Copy the connection information to the final location */
	for (i = 0; i < pdata->nr_outport; i++)
		pdata->conns[i] = conns[i];

	for (i = 0; conns + i < ptr; i++) {
		int port = conns[i].outport;

		/* Duplicate output port */
		WARN_ON(pdata->conns[port].child_fwnode);
		pdata->conns[port] = conns[i];
	}

	devm_kfree(&adev->dev, conns);
	return 0;
+7 −1
Original line number Diff line number Diff line
@@ -1282,6 +1282,10 @@ static int coresight_orphan_match(struct device *dev, void *data)
	for (i = 0; i < i_csdev->pdata->nr_outport; i++) {
		conn = &i_csdev->pdata->conns[i];

		/* Skip the port if FW doesn't describe it */
		if (!conn->child_fwnode)
			continue;

		/* We have found at least one orphan connection */
		if (conn->child_dev == NULL) {
			/* Does it match this newly added device? */
@@ -1321,6 +1325,8 @@ static void coresight_fixup_device_conns(struct coresight_device *csdev)
		struct coresight_connection *conn = &csdev->pdata->conns[i];
		struct device *dev = NULL;

		if (!conn->child_fwnode)
			continue;
		dev = bus_find_device_by_fwnode(&coresight_bustype, conn->child_fwnode);
		if (dev) {
			conn->child_dev = to_coresight_device(dev);
@@ -1353,7 +1359,7 @@ static int coresight_remove_match(struct device *dev, void *data)
	for (i = 0; i < iterator->pdata->nr_outport; i++) {
		conn = &iterator->pdata->conns[i];

		if (conn->child_dev == NULL)
		if (conn->child_dev == NULL || conn->child_fwnode == NULL)
			continue;

		if (csdev->dev.fwnode == conn->child_fwnode) {
+6 −4
Original line number Diff line number Diff line
@@ -104,10 +104,12 @@ struct coresight_reg_clk {
};

/**
 * struct coresight_platform_data - data harvested from the DT specification
 * @nr_inport:	number of input ports for this component.
 * @nr_outport:	number of output ports for this component.
 * @conns:	Array of nr_outport connections from this component
 * 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.
 * @conns:	Sparse array of nr_outport connections from this component.
 * @reg_clk:	The clock this component is associated to.
 */
struct coresight_platform_data {