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

Commit cd209b41 authored by Joerg Roedel's avatar Joerg Roedel Committed by Rob Herring
Browse files

of: Move phandle walking to of_phandle_iterator_next()



Move the code to walk over the phandles out of the loop in
__of_parse_phandle_with_args() to a separate function that
just works with the iterator handle: of_phandle_iterator_next().

Signed-off-by: default avatarJoerg Roedel <jroedel@suse.de>
Signed-off-by: default avatarRob Herring <robh@kernel.org>
parent 74e1fbb1
Loading
Loading
Loading
Loading
+74 −56
Original line number Original line Diff line number Diff line
@@ -1465,74 +1465,93 @@ int of_phandle_iterator_init(struct of_phandle_iterator *it,
	return 0;
	return 0;
}
}


static int __of_parse_phandle_with_args(const struct device_node *np,
int of_phandle_iterator_next(struct of_phandle_iterator *it)
					const char *list_name,
					const char *cells_name,
					int cell_count, int index,
					struct of_phandle_args *out_args)
{
{
	struct of_phandle_iterator it;
	uint32_t count = 0;
	int rc, cur_index = 0;


	rc = of_phandle_iterator_init(&it, np, list_name,
	if (it->node) {
				      cells_name, cell_count);
		of_node_put(it->node);
	if (rc)
		it->node = NULL;
		return rc;
	}


	/* Loop over the phandles until all the requested entry is found */
	if (!it->cur || it->phandle_end >= it->list_end)
	while (it.cur < it.list_end) {
		return -ENOENT;
		rc = -EINVAL;

		it.cur_count = 0;
	it->cur = it->phandle_end;

	/* If phandle is 0, then it is an empty entry with no arguments. */
	it->phandle = be32_to_cpup(it->cur++);

	if (it->phandle) {


		/*
		/*
		 * If phandle is 0, then it is an empty entry with no
		 * Find the provider node and parse the #*-cells property to
		 * arguments.  Skip forward to the next entry.
		 * determine the argument length.
		 */
		it.phandle = be32_to_cpup(it.cur++);
		if (it.phandle) {
			/*
			 * Find the provider node and parse the #*-cells
			 * property to determine the argument length.
			 *
			 * This is not needed if the cell count is hard-coded
			 * (i.e. cells_name not set, but cell_count is set),
			 * except when we're going to return the found node
			 * below.
		 */
		 */
			if (it.cells_name || cur_index == index) {
		it->node = of_find_node_by_phandle(it->phandle);
				it.node = of_find_node_by_phandle(it.phandle);

				if (!it.node) {
		if (it->cells_name) {
			if (!it->node) {
				pr_err("%s: could not find phandle\n",
				pr_err("%s: could not find phandle\n",
						it.parent->full_name);
				       it->parent->full_name);
				goto err;
				goto err;
			}
			}
			}


			if (it.cells_name) {
			if (of_property_read_u32(it->node, it->cells_name,
				if (of_property_read_u32(it.node, it.cells_name,
						 &count)) {
							 &it.cur_count)) {
				pr_err("%s: could not get %s for %s\n",
				pr_err("%s: could not get %s for %s\n",
						it.parent->full_name, it.cells_name,
				       it->parent->full_name,
						it.node->full_name);
				       it->cells_name,
				       it->node->full_name);
				goto err;
				goto err;
			}
			}
		} else {
		} else {
				it.cur_count = it.cell_count;
			count = it->cell_count;
		}
		}


		/*
		/*
			 * Make sure that the arguments actually fit in the
		 * Make sure that the arguments actually fit in the remaining
			 * remaining property data length
		 * property data length
		 */
		 */
			if (it.cur + it.cur_count > it.list_end) {
		if (it->cur + count > it->list_end) {
			pr_err("%s: arguments longer than property\n",
			pr_err("%s: arguments longer than property\n",
					 it.parent->full_name);
			       it->parent->full_name);
			goto err;
			goto err;
		}
		}
	}
	}


	it->phandle_end = it->cur + count;
	it->cur_count = count;

	return 0;

err:
	if (it->node) {
		of_node_put(it->node);
		it->node = NULL;
	}

	return -EINVAL;
}

static int __of_parse_phandle_with_args(const struct device_node *np,
					const char *list_name,
					const char *cells_name,
					int cell_count, int index,
					struct of_phandle_args *out_args)
{
	struct of_phandle_iterator it;
	int rc, cur_index = 0;

	rc = of_phandle_iterator_init(&it, np, list_name,
				      cells_name, cell_count);
	if (rc)
		return rc;

	/* Loop over the phandles until all the requested entry is found */
	while ((rc = of_phandle_iterator_next(&it)) == 0) {
		/*
		/*
		 * All of the error cases above bail out of the loop, so at
		 * All of the error cases bail out of the loop, so at
		 * this point, the parsing is successful. If the requested
		 * this point, the parsing is successful. If the requested
		 * index matches, then fill the out_args structure and return,
		 * index matches, then fill the out_args structure and return,
		 * or return -ENOENT for an empty entry.
		 * or return -ENOENT for an empty entry.
@@ -1558,9 +1577,6 @@ static int __of_parse_phandle_with_args(const struct device_node *np,
			return 0;
			return 0;
		}
		}


		of_node_put(it.node);
		it.node = NULL;
		it.cur += it.cur_count;
		cur_index++;
		cur_index++;
	}
	}


@@ -1570,7 +1586,9 @@ static int __of_parse_phandle_with_args(const struct device_node *np,
	 * -EINVAL : parsing error on data
	 * -EINVAL : parsing error on data
	 * [1..n]  : Number of phandle (count mode; when index = -1)
	 * [1..n]  : Number of phandle (count mode; when index = -1)
	 */
	 */
	rc = index < 0 ? cur_index : -ENOENT;
	if (rc == -ENOENT && index < 0)
		rc = cur_index;

 err:
 err:
	if (it.node)
	if (it.node)
		of_node_put(it.node);
		of_node_put(it.node);
+7 −0
Original line number Original line Diff line number Diff line
@@ -358,6 +358,8 @@ extern int of_phandle_iterator_init(struct of_phandle_iterator *it,
				    const char *cells_name,
				    const char *cells_name,
				    int cell_count);
				    int cell_count);


extern int of_phandle_iterator_next(struct of_phandle_iterator *it);

extern void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align));
extern void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align));
extern int of_alias_get_id(struct device_node *np, const char *stem);
extern int of_alias_get_id(struct device_node *np, const char *stem);
extern int of_alias_get_highest_id(const char *stem);
extern int of_alias_get_highest_id(const char *stem);
@@ -641,6 +643,11 @@ static inline int of_phandle_iterator_init(struct of_phandle_iterator *it,
	return -ENOSYS;
	return -ENOSYS;
}
}


static inline int of_phandle_iterator_next(struct of_phandle_iterator *it)
{
	return -ENOSYS;
}

static inline int of_alias_get_id(struct device_node *np, const char *stem)
static inline int of_alias_get_id(struct device_node *np, const char *stem)
{
{
	return -ENOSYS;
	return -ENOSYS;