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

Commit 5eadbde1 authored by Robin Murphy's avatar Robin Murphy Committed by John Stultz
Browse files

UPSTREAM: of: Factor out #{addr,size}-cells parsing



In some cases such as PCI host controllers, we may have a "parent bus"
which is an OF leaf node, but still need to correctly parse ranges from
the point of view of that bus. For that, factor out variants of the
"#addr-cells" and "#size-cells" parsers which do not assume they have a
device node and thus immediately traverse upwards before reading the
relevant property.

Signed-off-by: default avatarRobin Murphy <robin.murphy@arm.com>
[robh: don't make of_bus_n_{addr,size}_cells() public]
Reviewed-by: default avatarGeert Uytterhoeven <geert+renesas@glider.be>
Tested-by: default avatarNicolas Saenz Julienne <nsaenzjulienne@suse.de>
Reviewed-by: default avatarNicolas Saenz Julienne <nsaenzjulienne@suse.de>
Signed-off-by: default avatarRob Herring <robh@kernel.org>
(cherry picked from commit b68ac8dc22ebbf003e26e44bf4dd3030c076df5a)
Signed-off-by: default avatarJohn Stultz <john.stultz@linaro.org>
Change-Id: Ic36911cbf4bc48ec35d4f054a6b2ff311a7d2d28
parent 8ae7041d
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -14,6 +14,8 @@
#include <linux/slab.h>
#include <linux/string.h>

#include "of_private.h"

/* Max address size we deal with */
#define OF_MAX_ADDR_CELLS	4
#define OF_CHECK_ADDR_COUNT(na)	((na) > 0 && (na) <= OF_MAX_ADDR_CELLS)
+22 −10
Original line number Diff line number Diff line
@@ -86,34 +86,46 @@ static bool __of_node_is_type(const struct device_node *np, const char *type)
	return np && match && type && !strcmp(match, type);
}

int of_n_addr_cells(struct device_node *np)
int of_bus_n_addr_cells(struct device_node *np)
{
	u32 cells;

	do {
		if (np->parent)
			np = np->parent;
	for (; np; np = np->parent)
		if (!of_property_read_u32(np, "#address-cells", &cells))
			return cells;
	} while (np->parent);

	/* No #address-cells property for the root node */
	return OF_ROOT_NODE_ADDR_CELLS_DEFAULT;
}

int of_n_addr_cells(struct device_node *np)
{
	if (np->parent)
		np = np->parent;

	return of_bus_n_addr_cells(np);
}
EXPORT_SYMBOL(of_n_addr_cells);

int of_n_size_cells(struct device_node *np)
int of_bus_n_size_cells(struct device_node *np)
{
	u32 cells;

	do {
		if (np->parent)
			np = np->parent;
	for (; np; np = np->parent)
		if (!of_property_read_u32(np, "#size-cells", &cells))
			return cells;
	} while (np->parent);

	/* No #size-cells property for the root node */
	return OF_ROOT_NODE_SIZE_CELLS_DEFAULT;
}

int of_n_size_cells(struct device_node *np)
{
	if (np->parent)
		np = np->parent;

	return of_bus_n_size_cells(np);
}
EXPORT_SYMBOL(of_n_size_cells);

#ifdef CONFIG_NUMA
+3 −0
Original line number Diff line number Diff line
@@ -158,6 +158,9 @@ extern void __of_sysfs_remove_bin_file(struct device_node *np,
#define for_each_transaction_entry_reverse(_oft, _te) \
	list_for_each_entry_reverse(_te, &(_oft)->te_list, node)

extern int of_bus_n_addr_cells(struct device_node *np);
extern int of_bus_n_size_cells(struct device_node *np);

#ifdef CONFIG_OF_ADDRESS
extern int of_dma_get_range(struct device_node *np, u64 *dma_addr,
			    u64 *paddr, u64 *size);