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: Robin Murphy <robin.murphy@arm.com> [robh: don't make of_bus_n_{addr,size}_cells() public] Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> Tested-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de> Reviewed-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de> Signed-off-by: Rob Herring <robh@kernel.org>
This commit is contained in:

committed by
Rob Herring

parent
c60bf3eb88
commit
b68ac8dc22
@@ -14,6 +14,8 @@
|
|||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/string.h>
|
#include <linux/string.h>
|
||||||
|
|
||||||
|
#include "of_private.h"
|
||||||
|
|
||||||
/* Max address size we deal with */
|
/* Max address size we deal with */
|
||||||
#define OF_MAX_ADDR_CELLS 4
|
#define OF_MAX_ADDR_CELLS 4
|
||||||
#define OF_CHECK_ADDR_COUNT(na) ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS)
|
#define OF_CHECK_ADDR_COUNT(na) ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS)
|
||||||
|
@@ -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);
|
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;
|
u32 cells;
|
||||||
|
|
||||||
do {
|
for (; np; np = np->parent)
|
||||||
if (np->parent)
|
|
||||||
np = np->parent;
|
|
||||||
if (!of_property_read_u32(np, "#address-cells", &cells))
|
if (!of_property_read_u32(np, "#address-cells", &cells))
|
||||||
return cells;
|
return cells;
|
||||||
} while (np->parent);
|
|
||||||
/* No #address-cells property for the root node */
|
/* No #address-cells property for the root node */
|
||||||
return OF_ROOT_NODE_ADDR_CELLS_DEFAULT;
|
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);
|
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;
|
u32 cells;
|
||||||
|
|
||||||
do {
|
for (; np; np = np->parent)
|
||||||
if (np->parent)
|
|
||||||
np = np->parent;
|
|
||||||
if (!of_property_read_u32(np, "#size-cells", &cells))
|
if (!of_property_read_u32(np, "#size-cells", &cells))
|
||||||
return cells;
|
return cells;
|
||||||
} while (np->parent);
|
|
||||||
/* No #size-cells property for the root node */
|
/* No #size-cells property for the root node */
|
||||||
return OF_ROOT_NODE_SIZE_CELLS_DEFAULT;
|
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);
|
EXPORT_SYMBOL(of_n_size_cells);
|
||||||
|
|
||||||
#ifdef CONFIG_NUMA
|
#ifdef CONFIG_NUMA
|
||||||
|
@@ -158,6 +158,9 @@ extern void __of_sysfs_remove_bin_file(struct device_node *np,
|
|||||||
#define for_each_transaction_entry_reverse(_oft, _te) \
|
#define for_each_transaction_entry_reverse(_oft, _te) \
|
||||||
list_for_each_entry_reverse(_te, &(_oft)->te_list, node)
|
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
|
#ifdef CONFIG_OF_ADDRESS
|
||||||
extern int of_dma_get_range(struct device_node *np, u64 *dma_addr,
|
extern int of_dma_get_range(struct device_node *np, u64 *dma_addr,
|
||||||
u64 *paddr, u64 *size);
|
u64 *paddr, u64 *size);
|
||||||
|
Reference in New Issue
Block a user