summaryrefslogtreecommitdiff
path: root/drivers/core
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/core')
-rw-r--r--drivers/core/of_access.c61
-rw-r--r--drivers/core/ofnode.c124
2 files changed, 165 insertions, 20 deletions
diff --git a/drivers/core/of_access.c b/drivers/core/of_access.c
index 77acd766262..b11e36202c1 100644
--- a/drivers/core/of_access.c
+++ b/drivers/core/of_access.c
@@ -666,11 +666,12 @@ int of_property_read_string_helper(const struct device_node *np,
return i <= 0 ? -ENODATA : i;
}
-static int __of_parse_phandle_with_args(const struct device_node *np,
- const char *list_name,
- const char *cells_name,
- int cell_count, int index,
- struct of_phandle_args *out_args)
+static int __of_root_parse_phandle_with_args(struct device_node *root,
+ const struct device_node *np,
+ const char *list_name,
+ const char *cells_name,
+ int cell_count, int index,
+ struct of_phandle_args *out_args)
{
const __be32 *list, *list_end;
int rc = 0, cur_index = 0;
@@ -706,7 +707,7 @@ static int __of_parse_phandle_with_args(const struct device_node *np,
* below.
*/
if (cells_name || cur_index == index) {
- node = of_find_node_by_phandle(NULL, phandle);
+ node = of_find_node_by_phandle(root, phandle);
if (!node) {
dm_warn("%s: could not find phandle\n",
np->full_name);
@@ -783,39 +784,65 @@ static int __of_parse_phandle_with_args(const struct device_node *np,
return rc;
}
-struct device_node *of_parse_phandle(const struct device_node *np,
- const char *phandle_name, int index)
+struct device_node *of_root_parse_phandle(struct device_node *root,
+ const struct device_node *np,
+ const char *phandle_name, int index)
{
struct of_phandle_args args;
if (index < 0)
return NULL;
- if (__of_parse_phandle_with_args(np, phandle_name, NULL, 0, index,
- &args))
+ if (__of_root_parse_phandle_with_args(root, np, phandle_name, NULL, 0,
+ index, &args))
return NULL;
return args.np;
}
+int of_root_parse_phandle_with_args(struct device_node *root,
+ const struct device_node *np,
+ const char *list_name, const char *cells_name,
+ int cell_count, int index,
+ struct of_phandle_args *out_args)
+{
+ if (index < 0)
+ return -EINVAL;
+
+ return __of_root_parse_phandle_with_args(root, np, list_name, cells_name,
+ cell_count, index, out_args);
+}
+
+int of_root_count_phandle_with_args(struct device_node *root,
+ const struct device_node *np,
+ const char *list_name, const char *cells_name,
+ int cell_count)
+{
+ return __of_root_parse_phandle_with_args(root, np, list_name, cells_name,
+ cell_count, -1, NULL);
+}
+
+struct device_node *of_parse_phandle(const struct device_node *np,
+ const char *phandle_name, int index)
+{
+ return of_root_parse_phandle(NULL, np, phandle_name, index);
+}
+
int of_parse_phandle_with_args(const struct device_node *np,
const char *list_name, const char *cells_name,
int cell_count, int index,
struct of_phandle_args *out_args)
{
- if (index < 0)
- return -EINVAL;
-
- return __of_parse_phandle_with_args(np, list_name, cells_name,
- cell_count, index, out_args);
+ return of_root_parse_phandle_with_args(NULL, np, list_name, cells_name,
+ cell_count, index, out_args);
}
int of_count_phandle_with_args(const struct device_node *np,
const char *list_name, const char *cells_name,
int cell_count)
{
- return __of_parse_phandle_with_args(np, list_name, cells_name,
- cell_count, -1, NULL);
+ return of_root_count_phandle_with_args(NULL, np, list_name, cells_name,
+ cell_count);
}
static void of_alias_add(struct alias_prop *ap, struct device_node *np,
diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c
index 950895e72a9..c8161827d1c 100644
--- a/drivers/core/ofnode.c
+++ b/drivers/core/ofnode.c
@@ -879,11 +879,69 @@ int ofnode_read_string_list(ofnode node, const char *property,
return count;
}
-static void ofnode_from_fdtdec_phandle_args(struct fdtdec_phandle_args *in,
+ofnode ofnode_parse_phandle(ofnode node, const char *phandle_name,
+ int index)
+{
+ ofnode phandle;
+
+ if (ofnode_is_np(node)) {
+ struct device_node *np;
+
+ np = of_parse_phandle(ofnode_to_np(node), phandle_name,
+ index);
+ if (!np)
+ return ofnode_null();
+
+ phandle = np_to_ofnode(np);
+ } else {
+ struct fdtdec_phandle_args args;
+
+ if (fdtdec_parse_phandle_with_args(ofnode_to_fdt(node),
+ ofnode_to_offset(node),
+ phandle_name, NULL,
+ 0, index, &args))
+ return ofnode_null();
+
+ phandle = offset_to_ofnode(args.node);
+ }
+
+ return phandle;
+}
+
+ofnode oftree_parse_phandle(oftree tree, ofnode node, const char *phandle_name,
+ int index)
+{
+ ofnode phandle;
+
+ if (ofnode_is_np(node)) {
+ struct device_node *np;
+
+ np = of_root_parse_phandle(tree.np, ofnode_to_np(node),
+ phandle_name, index);
+ if (!np)
+ return ofnode_null();
+
+ phandle = np_to_ofnode(np);
+ } else {
+ struct fdtdec_phandle_args args;
+
+ if (fdtdec_parse_phandle_with_args(tree.fdt,
+ ofnode_to_offset(node),
+ phandle_name, NULL,
+ 0, index, &args))
+ return ofnode_null();
+
+ phandle = noffset_to_ofnode(node, args.node);
+ }
+
+ return phandle;
+}
+
+static void ofnode_from_fdtdec_phandle_args(ofnode node, struct fdtdec_phandle_args *in,
struct ofnode_phandle_args *out)
{
assert(OF_MAX_PHANDLE_ARGS == MAX_PHANDLE_ARGS);
- out->node = offset_to_ofnode(in->node);
+ out->node = noffset_to_ofnode(node, in->node);
out->args_count = in->args_count;
memcpy(out->args, in->args, sizeof(out->args));
}
@@ -923,7 +981,40 @@ int ofnode_parse_phandle_with_args(ofnode node, const char *list_name,
cell_count, index, &args);
if (ret)
return ret;
- ofnode_from_fdtdec_phandle_args(&args, out_args);
+ ofnode_from_fdtdec_phandle_args(node, &args, out_args);
+ }
+
+ return 0;
+}
+
+int oftree_parse_phandle_with_args(oftree tree, ofnode node, const char *list_name,
+ const char *cells_name, int cell_count,
+ int index,
+ struct ofnode_phandle_args *out_args)
+{
+ if (ofnode_is_np(node)) {
+ struct of_phandle_args args;
+ int ret;
+
+ ret = of_root_parse_phandle_with_args(tree.np,
+ ofnode_to_np(node),
+ list_name, cells_name,
+ cell_count, index,
+ &args);
+ if (ret)
+ return ret;
+ ofnode_from_of_phandle_args(&args, out_args);
+ } else {
+ struct fdtdec_phandle_args args;
+ int ret;
+
+ ret = fdtdec_parse_phandle_with_args(tree.fdt,
+ ofnode_to_offset(node),
+ list_name, cells_name,
+ cell_count, index, &args);
+ if (ret)
+ return ret;
+ ofnode_from_fdtdec_phandle_args(node, &args, out_args);
}
return 0;
@@ -941,6 +1032,18 @@ int ofnode_count_phandle_with_args(ofnode node, const char *list_name,
cell_count, -1, NULL);
}
+int oftree_count_phandle_with_args(oftree tree, ofnode node, const char *list_name,
+ const char *cells_name, int cell_count)
+{
+ if (ofnode_is_np(node))
+ return of_root_count_phandle_with_args(tree.np, ofnode_to_np(node),
+ list_name, cells_name, cell_count);
+ else
+ return fdtdec_parse_phandle_with_args(tree.fdt,
+ ofnode_to_offset(node), list_name, cells_name,
+ cell_count, -1, NULL);
+}
+
ofnode ofnode_path(const char *path)
{
if (of_live_active())
@@ -1768,6 +1871,21 @@ const char *ofnode_options_read_str(const char *prop_name)
return ofnode_read_string(uboot, prop_name);
}
+int ofnode_options_get_by_phandle(const char *prop_name, ofnode *nodep)
+{
+ ofnode uboot;
+
+ uboot = ofnode_path("/options/u-boot");
+ if (!ofnode_valid(uboot))
+ return -EINVAL;
+
+ *nodep = ofnode_parse_phandle(uboot, prop_name, 0);
+ if (!ofnode_valid(*nodep))
+ return -EINVAL;
+
+ return 0;
+}
+
int ofnode_read_bootscript_address(u64 *bootscr_address, u64 *bootscr_offset)
{
int ret;