]> git.sur5r.net Git - u-boot/blobdiff - drivers/core/ofnode.c
drivers: net: pfe_eth: provide pfe commands
[u-boot] / drivers / core / ofnode.c
index da7c477c81db224687027557e0805e8012483606..4e4532651fca608ae96a0d4d7b2e8bb28bacd44f 100644 (file)
@@ -9,11 +9,12 @@
 #include <dm.h>
 #include <fdtdec.h>
 #include <fdt_support.h>
-#include <libfdt.h>
+#include <linux/libfdt.h>
 #include <dm/of_access.h>
 #include <dm/of_addr.h>
 #include <dm/ofnode.h>
 #include <linux/err.h>
+#include <linux/ioport.h>
 
 int ofnode_read_u32(ofnode node, const char *propname, u32 *outp)
 {
@@ -23,7 +24,7 @@ int ofnode_read_u32(ofnode node, const char *propname, u32 *outp)
        if (ofnode_is_np(node)) {
                return of_read_u32(ofnode_to_np(node), propname, outp);
        } else {
-               const int *cell;
+               const fdt32_t *cell;
                int len;
 
                cell = fdt_getprop(gd->fdt_blob, ofnode_to_offset(node),
@@ -57,20 +58,16 @@ int ofnode_read_s32_default(ofnode node, const char *propname, s32 def)
 
 bool ofnode_read_bool(ofnode node, const char *propname)
 {
-       bool val;
+       const void *prop;
 
        assert(ofnode_valid(node));
        debug("%s: %s: ", __func__, propname);
 
-       if (ofnode_is_np(node)) {
-               val = !!of_find_property(ofnode_to_np(node), propname, NULL);
-       } else {
-               val = !!fdt_getprop(gd->fdt_blob, ofnode_to_offset(node),
-                                   propname, NULL);
-       }
-       debug("%s\n", val ? "true" : "false");
+       prop = ofnode_get_property(node, propname, NULL);
+
+       debug("%s\n", prop ? "true" : "false");
 
-       return val;
+       return prop ? true : false;
 }
 
 const char *ofnode_read_string(ofnode node, const char *propname)
@@ -168,6 +165,20 @@ ofnode ofnode_next_subnode(ofnode node)
                fdt_next_subnode(gd->fdt_blob, ofnode_to_offset(node)));
 }
 
+ofnode ofnode_get_parent(ofnode node)
+{
+       ofnode parent;
+
+       assert(ofnode_valid(node));
+       if (ofnode_is_np(node))
+               parent = np_to_ofnode(of_get_parent(ofnode_to_np(node)));
+       else
+               parent.of_offset = fdt_parent_offset(gd->fdt_blob,
+                                                    ofnode_to_offset(node));
+
+       return parent;
+}
+
 const char *ofnode_get_name(ofnode node)
 {
        assert(ofnode_valid(node));
@@ -177,6 +188,19 @@ const char *ofnode_get_name(ofnode node)
        return fdt_get_name(gd->fdt_blob, ofnode_to_offset(node), NULL);
 }
 
+ofnode ofnode_get_by_phandle(uint phandle)
+{
+       ofnode node;
+
+       if (of_live_active())
+               node = np_to_ofnode(of_find_node_by_phandle(phandle));
+       else
+               node.of_offset = fdt_node_offset_by_phandle(gd->fdt_blob,
+                                                           phandle);
+
+       return node;
+}
+
 int ofnode_read_size(ofnode node, const char *propname)
 {
        int len;
@@ -202,13 +226,19 @@ fdt_addr_t ofnode_get_addr_index(ofnode node, int index)
                const __be32 *prop_val;
                uint flags;
                u64 size;
+               int na;
 
-               prop_val = of_get_address(
-                       (struct device_node *)ofnode_to_np(node), index,
-                       &size, &flags);
+               prop_val = of_get_address(ofnode_to_np(node), index, &size,
+                                         &flags);
                if (!prop_val)
                        return FDT_ADDR_T_NONE;
-               return  be32_to_cpup(prop_val);
+
+               if (IS_ENABLED(CONFIG_OF_TRANSLATE)) {
+                       return of_translate_address(ofnode_to_np(node), prop_val);
+               } else {
+                       na = of_n_addr_cells(ofnode_to_np(node));
+                       return of_read_number(prop_val, na);
+               }
        } else {
                return fdt_get_base_address(gd->fdt_blob,
                                            ofnode_to_offset(node));
@@ -298,7 +328,8 @@ int ofnode_parse_phandle_with_args(ofnode node, const char *list_name,
                int ret;
 
                ret = of_parse_phandle_with_args(ofnode_to_np(node),
-                               list_name, cells_name, index, &args);
+                                                list_name, cells_name, index,
+                                                &args);
                if (ret)
                        return ret;
                ofnode_from_of_phandle_args(&args, out_args);
@@ -307,8 +338,9 @@ int ofnode_parse_phandle_with_args(ofnode node, const char *list_name,
                int ret;
 
                ret = fdtdec_parse_phandle_with_args(gd->fdt_blob,
-                               ofnode_to_offset(node), list_name, cells_name,
-                               cell_count, index, &args);
+                                                    ofnode_to_offset(node),
+                                                    list_name, cells_name,
+                                                    cell_count, index, &args);
                if (ret)
                        return ret;
                ofnode_from_fdtdec_phandle_args(&args, out_args);
@@ -317,6 +349,18 @@ int ofnode_parse_phandle_with_args(ofnode node, const char *list_name,
        return 0;
 }
 
+int ofnode_count_phandle_with_args(ofnode node, const char *list_name,
+                                  const char *cells_name)
+{
+       if (ofnode_is_np(node))
+               return of_count_phandle_with_args(ofnode_to_np(node),
+                               list_name, cells_name);
+       else
+               return fdtdec_parse_phandle_with_args(gd->fdt_blob,
+                               ofnode_to_offset(node), list_name, cells_name,
+                               0, -1, NULL);
+}
+
 ofnode ofnode_path(const char *path)
 {
        if (of_live_active())
@@ -380,10 +424,11 @@ int ofnode_decode_display_timing(ofnode parent, int index,
        if (!ofnode_valid(timings))
                return -EINVAL;
 
-       for (i = 0, node = ofnode_first_subnode(timings);
-            ofnode_valid(node) && i != index;
-            node = ofnode_first_subnode(node))
-               i++;
+       i = 0;
+       ofnode_for_each_subnode(node, timings) {
+               if (i++ == index)
+                       break;
+       }
 
        if (!ofnode_valid(node))
                return -EINVAL;
@@ -432,19 +477,13 @@ int ofnode_decode_display_timing(ofnode parent, int index,
        return ret;
 }
 
-const u32 *ofnode_read_prop(ofnode node, const char *propname, int *lenp)
+const void *ofnode_get_property(ofnode node, const char *propname, int *lenp)
 {
-       if (ofnode_is_np(node)) {
-               struct property *prop;
-
-               prop = of_find_property(ofnode_to_np(node), propname, lenp);
-               if (!prop)
-                       return NULL;
-               return prop->value;
-       } else {
+       if (ofnode_is_np(node))
+               return of_get_property(ofnode_to_np(node), propname, lenp);
+       else
                return fdt_getprop(gd->fdt_blob, ofnode_to_offset(node),
                                   propname, lenp);
-       }
 }
 
 bool ofnode_is_available(ofnode node)
@@ -463,8 +502,10 @@ fdt_addr_t ofnode_get_addr_size(ofnode node, const char *property,
                int na, ns;
                int psize;
                const struct device_node *np = ofnode_to_np(node);
-               const __be32 *prop = of_get_property(np, "reg", &psize);
+               const __be32 *prop = of_get_property(np, property, &psize);
 
+               if (!prop)
+                       return FDT_ADDR_T_NONE;
                na = of_n_addr_cells(np);
                ns = of_n_addr_cells(np);
                *sizep = of_read_number(prop + na, ns);
@@ -497,7 +538,7 @@ const uint8_t *ofnode_read_u8_array_ptr(ofnode node, const char *propname,
 int ofnode_read_pci_addr(ofnode node, enum fdt_pci_space type,
                         const char *propname, struct fdt_pci_addr *addr)
 {
-       const u32 *cell;
+       const fdt32_t *cell;
        int len;
        int ret = -ENOENT;
 
@@ -509,7 +550,7 @@ int ofnode_read_pci_addr(ofnode node, enum fdt_pci_space type,
         * #size-cells. They need to be 3 and 2 accordingly. However,
         * for simplicity we skip the check here.
         */
-       cell = ofnode_read_prop(node, propname, &len);
+       cell = ofnode_get_property(node, propname, &len);
        if (!cell)
                goto fail;
 
@@ -527,10 +568,10 @@ int ofnode_read_pci_addr(ofnode node, enum fdt_pci_space type,
                                addr->phys_mid = fdt32_to_cpu(cell[1]);
                                addr->phys_lo = fdt32_to_cpu(cell[1]);
                                break;
-                       } else {
-                               cell += (FDT_PCI_ADDR_CELLS +
-                                        FDT_PCI_SIZE_CELLS);
                        }
+
+                       cell += (FDT_PCI_ADDR_CELLS +
+                                FDT_PCI_SIZE_CELLS);
                }
 
                if (i == num) {
@@ -539,10 +580,10 @@ int ofnode_read_pci_addr(ofnode node, enum fdt_pci_space type,
                }
 
                return 0;
-       } else {
-               ret = -EINVAL;
        }
 
+       ret = -EINVAL;
+
 fail:
        debug("(not found)\n");
        return ret;
@@ -582,24 +623,64 @@ int ofnode_read_simple_size_cells(ofnode node)
 
 bool ofnode_pre_reloc(ofnode node)
 {
-       if (ofnode_read_prop(node, "u-boot,dm-pre-reloc", NULL))
+       if (ofnode_read_bool(node, "u-boot,dm-pre-reloc"))
                return true;
 
 #ifdef CONFIG_TPL_BUILD
-       if (ofnode_read_prop(node, "u-boot,dm-tpl", NULL))
+       if (ofnode_read_bool(node, "u-boot,dm-tpl"))
                return true;
 #elif defined(CONFIG_SPL_BUILD)
-       if (ofnode_read_prop(node, "u-boot,dm-spl", NULL))
+       if (ofnode_read_bool(node, "u-boot,dm-spl"))
                return true;
 #else
        /*
         * In regular builds individual spl and tpl handling both
         * count as handled pre-relocation for later second init.
         */
-       if (ofnode_read_prop(node, "u-boot,dm-spl", NULL) ||
-           ofnode_read_prop(node, "u-boot,dm-tpl", NULL))
+       if (ofnode_read_bool(node, "u-boot,dm-spl") ||
+           ofnode_read_bool(node, "u-boot,dm-tpl"))
                return true;
 #endif
 
        return false;
 }
+
+int ofnode_read_resource(ofnode node, uint index, struct resource *res)
+{
+       if (ofnode_is_np(node)) {
+               return of_address_to_resource(ofnode_to_np(node), index, res);
+       } else {
+               struct fdt_resource fres;
+               int ret;
+
+               ret = fdt_get_resource(gd->fdt_blob, ofnode_to_offset(node),
+                                      "reg", index, &fres);
+               if (ret < 0)
+                       return -EINVAL;
+               memset(res, '\0', sizeof(*res));
+               res->start = fres.start;
+               res->end = fres.end;
+
+               return 0;
+       }
+}
+
+int ofnode_read_resource_byname(ofnode node, const char *name,
+                               struct resource *res)
+{
+       int index;
+
+       index = ofnode_stringlist_search(node, "reg-names", name);
+       if (index < 0)
+               return index;
+
+       return ofnode_read_resource(node, index, res);
+}
+
+u64 ofnode_translate_address(ofnode node, const fdt32_t *in_addr)
+{
+       if (ofnode_is_np(node))
+               return of_translate_address(ofnode_to_np(node), in_addr);
+       else
+               return fdt_translate_address(gd->fdt_blob, ofnode_to_offset(node), in_addr);
+}