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 <sjg@chromium.org>
Tested-by: Marcel Ziswiler <marcel.ziswiler@toradex.com>
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 @@
 	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 @@
 {
 	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 @@
 {
 	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 @@
 	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 @@
 	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 @@
 	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_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_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_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_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));
 }