dm: core: Add functions to obtain node's address/size cells
authorSimon Glass <sjg@chromium.org>
Mon, 12 Jun 2017 12:21:31 +0000 (06:21 -0600)
committerSimon Glass <sjg@chromium.org>
Tue, 11 Jul 2017 16:08:20 +0000 (10:08 -0600)
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

drivers/core/of_access.c
drivers/core/ofnode.c
drivers/core/read.c
drivers/core/regmap.c
drivers/pci/pci-uclass.c
include/dm/of_access.h
include/dm/ofnode.h
include/dm/read.h

index 93a65604967bfb0f2c74646fd13331346b8ec8e5..2bb23eef8850743d2e68a8af57b88fcca5a3af71 100644 (file)
@@ -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)
 {
index 79c80df7f4a03cf6d845f25b38ae648aa232e21a..da7c477c81db224687027557e0805e8012483606 100644 (file)
@@ -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));
 }
index 10807673136139416b244575c5a748f140bcdb9c..36293ba3263843349c92eca89b43856669da4e57 100644 (file)
@@ -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);
index 749d913372110c1ebb2b1cbe7c8eb63e093b860d..d4e16a27ef345fc078d3bb258e1d409bd959edaf 100644 (file)
@@ -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");
index b36ef3338ceb84d7c2ffbbfb39d0925e3532c2a6..42230405412c6406c4563770952511f135f53b00 100644 (file)
@@ -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);
index d2827001e2be7e211a572594ac1e00199962c66b..c5ea391aec169a2c8a17666b0257896dbc4bf45c 100644 (file)
@@ -60,6 +60,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
  *
index d261a61e914706e6d5bf9be3280004cd71ec9778..c3d8db5b16f60e37596a9b2ec1fedf06c7a8ad80 100644 (file)
@@ -561,6 +561,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
  *
index cea1c16a006005bacd8d1f52adc1eb104cbfc7f7..6dd1634675b43abdd16b08181ecf0a9b537fff12 100644 (file)
@@ -230,6 +230,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
  *
@@ -398,10 +418,22 @@ 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));
 }