From 878d68c0c357ff62120d5783d950f34ecd1065d9 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 12 Jun 2017 06:21:31 -0600 Subject: dm: core: Add functions to obtain node's address/size cells The of_n_addr_cells() and of_n_size_cells() functions are useful for getting the size of addresses in a node, but in a few places U-Boot needs to obtain the actual property value for a node without walking up the stack. Add functions for this and just the existing code to use it. Add a comment to the existing ofnode functions which do not do the right thing with a flat tree. This fixes a problem reading PCI addresses. Signed-off-by: Simon Glass Tested-by: Marcel Ziswiler Tested-on: Beaver, Jetson-TK1 diff --git a/drivers/core/of_access.c b/drivers/core/of_access.c index 93a6560..2bb23ee 100644 --- a/drivers/core/of_access.c +++ b/drivers/core/of_access.c @@ -96,6 +96,30 @@ int of_n_size_cells(const struct device_node *np) return OF_ROOT_NODE_SIZE_CELLS_DEFAULT; } +int of_simple_addr_cells(const struct device_node *np) +{ + const __be32 *ip; + + ip = of_get_property(np, "#address-cells", NULL); + if (ip) + return be32_to_cpup(ip); + + /* Return a default of 2 to match fdt_address_cells()*/ + return 2; +} + +int of_simple_size_cells(const struct device_node *np) +{ + const __be32 *ip; + + ip = of_get_property(np, "#size-cells", NULL); + if (ip) + return be32_to_cpup(ip); + + /* Return a default of 2 to match fdt_size_cells()*/ + return 2; +} + struct property *of_find_property(const struct device_node *np, const char *name, int *lenp) { diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index 79c80df..da7c477 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -552,7 +552,7 @@ int ofnode_read_addr_cells(ofnode node) { if (ofnode_is_np(node)) return of_n_addr_cells(ofnode_to_np(node)); - else + else /* NOTE: this call should walk up the parent stack */ return fdt_address_cells(gd->fdt_blob, ofnode_to_offset(node)); } @@ -560,6 +560,22 @@ int ofnode_read_size_cells(ofnode node) { if (ofnode_is_np(node)) return of_n_size_cells(ofnode_to_np(node)); + else /* NOTE: this call should walk up the parent stack */ + return fdt_size_cells(gd->fdt_blob, ofnode_to_offset(node)); +} + +int ofnode_read_simple_addr_cells(ofnode node) +{ + if (ofnode_is_np(node)) + return of_simple_addr_cells(ofnode_to_np(node)); + else + return fdt_address_cells(gd->fdt_blob, ofnode_to_offset(node)); +} + +int ofnode_read_simple_size_cells(ofnode node) +{ + if (ofnode_is_np(node)) + return of_simple_size_cells(ofnode_to_np(node)); else return fdt_size_cells(gd->fdt_blob, ofnode_to_offset(node)); } diff --git a/drivers/core/read.c b/drivers/core/read.c index 1080767..36293ba 100644 --- a/drivers/core/read.c +++ b/drivers/core/read.c @@ -94,6 +94,16 @@ int dev_read_size_cells(struct udevice *dev) return ofnode_read_size_cells(dev_ofnode(dev)); } +int dev_read_simple_addr_cells(struct udevice *dev) +{ + return ofnode_read_simple_addr_cells(dev_ofnode(dev)); +} + +int dev_read_simple_size_cells(struct udevice *dev) +{ + return ofnode_read_simple_size_cells(dev_ofnode(dev)); +} + int dev_read_phandle(struct udevice *dev) { ofnode node = dev_ofnode(dev); diff --git a/drivers/core/regmap.c b/drivers/core/regmap.c index 749d913..d4e16a2 100644 --- a/drivers/core/regmap.c +++ b/drivers/core/regmap.c @@ -72,8 +72,8 @@ int regmap_init_mem(struct udevice *dev, struct regmap **mapp) ofnode node = dev_ofnode(dev); struct resource r; - addr_len = dev_read_addr_cells(dev->parent); - size_len = dev_read_size_cells(dev->parent); + addr_len = dev_read_simple_addr_cells(dev->parent); + size_len = dev_read_simple_size_cells(dev->parent); both_len = addr_len + size_len; len = dev_read_size(dev, "reg"); diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c index b36ef33..4223040 100644 --- a/drivers/pci/pci-uclass.c +++ b/drivers/pci/pci-uclass.c @@ -766,9 +766,9 @@ static int decode_regions(struct pci_controller *hose, ofnode parent_node, prop = ofnode_read_prop(node, "ranges", &len); if (!prop) return -EINVAL; - pci_addr_cells = ofnode_read_addr_cells(node); - addr_cells = ofnode_read_addr_cells(parent_node); - size_cells = ofnode_read_size_cells(node); + pci_addr_cells = ofnode_read_simple_addr_cells(node); + addr_cells = ofnode_read_simple_addr_cells(parent_node); + size_cells = ofnode_read_simple_size_cells(node); /* PCI addresses are always 3-cells */ len /= sizeof(u32); diff --git a/include/dm/of_access.h b/include/dm/of_access.h index d282700..c5ea391 100644 --- a/include/dm/of_access.h +++ b/include/dm/of_access.h @@ -61,6 +61,26 @@ int of_n_addr_cells(const struct device_node *np); int of_n_size_cells(const struct device_node *np); /** + * of_simple_addr_cells() - Get the address cells property in a node + * + * This function matches fdt_address_cells(). + * + * @np: Node pointer to check + * @return value of #address-cells property in this node, or 2 if none + */ +int of_simple_addr_cells(const struct device_node *np); + +/** + * of_simple_size_cells() - Get the size cells property in a node + * + * This function matches fdt_size_cells(). + * + * @np: Node pointer to check + * @return value of #size-cells property in this node, or 2 if none + */ +int of_simple_size_cells(const struct device_node *np); + +/** * of_find_property() - find a property in a node * * @np: Pointer to device node holding property diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index d261a61..c3d8db5 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -562,6 +562,26 @@ int ofnode_read_addr_cells(ofnode node); int ofnode_read_size_cells(ofnode node); /** + * ofnode_read_simple_addr_cells() - Get the address cells property in a node + * + * This function matches fdt_address_cells(). + * + * @np: Node pointer to check + * @return value of #address-cells property in this node, or 2 if none + */ +int ofnode_read_simple_addr_cells(ofnode node); + +/** + * ofnode_read_simple_size_cells() - Get the size cells property in a node + * + * This function matches fdt_size_cells(). + * + * @np: Node pointer to check + * @return value of #size-cells property in this node, or 2 if none + */ +int ofnode_read_simple_size_cells(ofnode node); + +/** * ofnode_pre_reloc() - check if a node should be bound before relocation * * Device tree nodes can be marked as needing-to-be-bound in the loader stages diff --git a/include/dm/read.h b/include/dm/read.h index cea1c16..6dd1634 100644 --- a/include/dm/read.h +++ b/include/dm/read.h @@ -231,6 +231,26 @@ int dev_read_addr_cells(struct udevice *dev); int dev_read_size_cells(struct udevice *dev); /** + * dev_read_addr_cells() - Get the address cells property in a node + * + * This function matches fdt_address_cells(). + * + * @dev: devioe to check + * @return number of address cells this node uses + */ +int dev_read_simple_addr_cells(struct udevice *dev); + +/** + * dev_read_size_cells() - Get the size cells property in a node + * + * This function matches fdt_size_cells(). + * + * @dev: devioe to check + * @return number of size cells this node uses + */ +int dev_read_simple_size_cells(struct udevice *dev); + +/** * dev_read_phandle() - Get the phandle from a device * * @dev: device to check @@ -398,11 +418,23 @@ static inline int dev_read_phandle_with_args(struct udevice *dev, static inline int dev_read_addr_cells(struct udevice *dev) { + /* NOTE: this call should walk up the parent stack */ return fdt_address_cells(gd->fdt_blob, dev_of_offset(dev)); } static inline int dev_read_size_cells(struct udevice *dev) { + /* NOTE: this call should walk up the parent stack */ + return fdt_size_cells(gd->fdt_blob, dev_of_offset(dev)); +} + +static inline int dev_read_simple_addr_cells(struct udevice *dev) +{ + return fdt_address_cells(gd->fdt_blob, dev_of_offset(dev)); +} + +static inline int dev_read_simple_size_cells(struct udevice *dev) +{ return fdt_size_cells(gd->fdt_blob, dev_of_offset(dev)); } -- cgit v0.10.2