Merge branch 'for-next/of'
This commit is contained in:
commit
10169a04ca
|
@ -55,7 +55,36 @@ static int of_parse_prop_cells(char * const *newval, int count, char *data, int
|
|||
}
|
||||
|
||||
cp = newp;
|
||||
tmp = simple_strtoul(cp, &newp, 0);
|
||||
|
||||
if (isdigit(*cp)) {
|
||||
tmp = simple_strtoul(cp, &newp, 0);
|
||||
} else {
|
||||
struct device_node *n;
|
||||
char *str;
|
||||
int len = 0;
|
||||
|
||||
str = cp;
|
||||
while (*str && *str != '>' && *str != ' ') {
|
||||
str++;
|
||||
len++;
|
||||
}
|
||||
|
||||
str = xzalloc(len + 1);
|
||||
strncpy(str, cp, len);
|
||||
|
||||
n = of_find_node_by_path_or_alias(NULL, str);
|
||||
if (!n)
|
||||
printf("Cannot find node '%s'\n", str);
|
||||
|
||||
free(str);
|
||||
|
||||
if (!n)
|
||||
return -EINVAL;
|
||||
|
||||
tmp = of_node_create_phandle(n);
|
||||
newp += len;
|
||||
}
|
||||
|
||||
*(__be32 *)data = __cpu_to_be32(tmp);
|
||||
data += 4;
|
||||
*len += 4;
|
||||
|
@ -196,7 +225,7 @@ static int do_of_property(int argc, char *argv[])
|
|||
|
||||
if (optind < argc) {
|
||||
path = argv[optind];
|
||||
node = of_find_node_by_path(path);
|
||||
node = of_find_node_by_path_or_alias(NULL, path);
|
||||
if (!node) {
|
||||
printf("Cannot find nodepath %s\n", path);
|
||||
return -ENOENT;
|
||||
|
@ -276,7 +305,8 @@ BAREBOX_CMD_HELP_USAGE("of_property [OPTIONS] [NODE] [PROPERTY] [VALUES]\n")
|
|||
BAREBOX_CMD_HELP_OPT ("-s", "set property to value\n")
|
||||
BAREBOX_CMD_HELP_OPT ("-d", "delete property\n")
|
||||
BAREBOX_CMD_HELP_TEXT ("\nvalid formats for values:\n")
|
||||
BAREBOX_CMD_HELP_TEXT ("<0x00112233 4 05> - an array of cells\n")
|
||||
BAREBOX_CMD_HELP_TEXT ("<0x00112233 4 05> - an array of cells. cells not beginning with a digit are\n")
|
||||
BAREBOX_CMD_HELP_TEXT (" interpreted as node pathes and converted to phandles\n")
|
||||
BAREBOX_CMD_HELP_TEXT ("[00 11 22 .. nn] - byte stream\n")
|
||||
BAREBOX_CMD_HELP_TEXT ("If the value does not start with '<' or '[' it is interpreted as strings\n")
|
||||
BAREBOX_CMD_HELP_END
|
||||
|
|
|
@ -164,7 +164,7 @@ static int do_oftree(int argc, char *argv[])
|
|||
of_print_nodes(root, 0);
|
||||
of_delete_node(root);
|
||||
} else {
|
||||
struct device_node *n = of_find_node_by_path(node);
|
||||
struct device_node *n = of_find_node_by_path_or_alias(NULL, node);
|
||||
if (!n) {
|
||||
ret = -ENOENT;
|
||||
goto out;
|
||||
|
|
|
@ -240,6 +240,32 @@ const char *of_alias_get(struct device_node *np)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(of_alias_get);
|
||||
|
||||
/*
|
||||
* of_find_node_by_alias - Find a node given an alias name
|
||||
* @root: the root node of the tree. If NULL, use internal tree
|
||||
* @alias: the alias name to find
|
||||
*/
|
||||
struct device_node *of_find_node_by_alias(struct device_node *root, const char *alias)
|
||||
{
|
||||
struct device_node *aliasnp;
|
||||
int ret;
|
||||
const char *path;
|
||||
|
||||
if (!root)
|
||||
root = root_node;
|
||||
|
||||
aliasnp = of_find_node_by_path_from(root, "/aliases");
|
||||
if (!aliasnp)
|
||||
return NULL;
|
||||
|
||||
ret = of_property_read_string(aliasnp, alias, &path);
|
||||
if (ret)
|
||||
return NULL;
|
||||
|
||||
return of_find_node_by_path_from(root, path);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(of_find_node_by_alias);
|
||||
|
||||
/*
|
||||
* of_find_node_by_phandle - Find a node given a phandle
|
||||
* @handle: phandle of the node to find
|
||||
|
@ -255,6 +281,62 @@ struct device_node *of_find_node_by_phandle(phandle phandle)
|
|||
}
|
||||
EXPORT_SYMBOL(of_find_node_by_phandle);
|
||||
|
||||
/*
|
||||
* of_get_tree_max_phandle - Find the maximum phandle of a tree
|
||||
* @root: root node of the tree to search in. If NULL use the
|
||||
* internal tree.
|
||||
*/
|
||||
phandle of_get_tree_max_phandle(struct device_node *root)
|
||||
{
|
||||
struct device_node *n;
|
||||
phandle max;
|
||||
|
||||
if (!root)
|
||||
root = root_node;
|
||||
|
||||
if (!root)
|
||||
return 0;
|
||||
|
||||
max = root->phandle;
|
||||
|
||||
of_tree_for_each_node_from(n, root) {
|
||||
if (n->phandle > max)
|
||||
max = n->phandle;
|
||||
}
|
||||
|
||||
return max;
|
||||
}
|
||||
EXPORT_SYMBOL(of_get_tree_max_phandle);
|
||||
|
||||
/*
|
||||
* of_node_create_phandle - create a phandle for a node
|
||||
* @node: The node to create a phandle in
|
||||
*
|
||||
* returns the new phandle or the existing phandle if the node
|
||||
* already has a phandle.
|
||||
*/
|
||||
phandle of_node_create_phandle(struct device_node *node)
|
||||
{
|
||||
phandle p;
|
||||
struct device_node *root;
|
||||
|
||||
if (node->phandle)
|
||||
return node->phandle;
|
||||
|
||||
root = of_find_root_node(node);
|
||||
|
||||
p = of_get_tree_max_phandle(root) + 1;
|
||||
|
||||
node->phandle = p;
|
||||
|
||||
p = cpu_to_be32(p);
|
||||
|
||||
of_set_property(node, "phandle", &p, sizeof(p), 1);
|
||||
|
||||
return node->phandle;
|
||||
}
|
||||
EXPORT_SYMBOL(of_node_create_phandle);
|
||||
|
||||
/*
|
||||
* Find a property with a given name for a given node
|
||||
* and return the value.
|
||||
|
@ -318,6 +400,35 @@ struct device_node *of_find_node_by_name(struct device_node *from,
|
|||
}
|
||||
EXPORT_SYMBOL(of_find_node_by_name);
|
||||
|
||||
/**
|
||||
* of_find_node_by_type - Find a node by its "device_type" property
|
||||
* @from: The node to start searching from, or NULL to start searching
|
||||
* the entire device tree. The node you pass will not be
|
||||
* searched, only the next one will; typically, you pass
|
||||
* what the previous call returned.
|
||||
* @type: The type string to match against.
|
||||
*
|
||||
* Returns a pointer to the node found or NULL.
|
||||
*/
|
||||
struct device_node *of_find_node_by_type(struct device_node *from,
|
||||
const char *type)
|
||||
{
|
||||
struct device_node *np;
|
||||
const char *device_type;
|
||||
int ret;
|
||||
|
||||
if (!from)
|
||||
from = root_node;
|
||||
|
||||
of_tree_for_each_node_from(np, from) {
|
||||
ret = of_property_read_string(np, "device_type", &device_type);
|
||||
if (!ret && !of_node_cmp(device_type, type))
|
||||
return np;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(of_find_node_by_type);
|
||||
|
||||
/**
|
||||
* of_find_compatible_node - Find a node based on type and one of the
|
||||
* tokens in its "compatible" property
|
||||
|
@ -1211,6 +1322,9 @@ struct device_node *of_find_node_by_path_from(struct device_node *from,
|
|||
{
|
||||
char *slash, *p, *freep;
|
||||
|
||||
if (!from)
|
||||
from = root_node;
|
||||
|
||||
if (!from || !path || *path != '/')
|
||||
return NULL;
|
||||
|
||||
|
@ -1254,6 +1368,25 @@ struct device_node *of_find_node_by_path(const char *path)
|
|||
}
|
||||
EXPORT_SYMBOL(of_find_node_by_path);
|
||||
|
||||
/**
|
||||
* of_find_node_by_path_or_alias - Find a node matching a full OF path
|
||||
* or an alias
|
||||
* @root: The root node. If NULL the internal tree is used
|
||||
* @str: the full path or alias
|
||||
*
|
||||
* Returns a pointer to the node found or NULL.
|
||||
*/
|
||||
struct device_node *of_find_node_by_path_or_alias(struct device_node *root,
|
||||
const char *str)
|
||||
{
|
||||
if (*str == '/')
|
||||
return of_find_node_by_path_from(root, str);
|
||||
else
|
||||
return of_find_node_by_alias(root, str);
|
||||
|
||||
}
|
||||
EXPORT_SYMBOL(of_find_node_by_path_or_alias);
|
||||
|
||||
/**
|
||||
* of_modalias_node - Lookup appropriate modalias for a device node
|
||||
* @node: pointer to a device tree node
|
||||
|
@ -1568,22 +1701,6 @@ int of_add_memory(struct device_node *node, bool dump)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void __of_parse_phandles(struct device_node *node)
|
||||
{
|
||||
struct device_node *n;
|
||||
phandle phandle;
|
||||
int ret;
|
||||
|
||||
ret = of_property_read_u32(node, "phandle", &phandle);
|
||||
if (!ret) {
|
||||
node->phandle = phandle;
|
||||
list_add_tail(&node->phandles, &phandle_list);
|
||||
}
|
||||
|
||||
list_for_each_entry(n, &node->children, parent_list)
|
||||
__of_parse_phandles(n);
|
||||
}
|
||||
|
||||
struct device_node *of_chosen;
|
||||
const char *of_model;
|
||||
|
||||
|
@ -1602,7 +1719,7 @@ const struct of_device_id of_default_bus_match_table[] = {
|
|||
|
||||
int of_probe(void)
|
||||
{
|
||||
struct device_node *memory;
|
||||
struct device_node *memory, *node;
|
||||
|
||||
if(!root_node)
|
||||
return -ENODEV;
|
||||
|
@ -1610,7 +1727,9 @@ int of_probe(void)
|
|||
of_chosen = of_find_node_by_path("/chosen");
|
||||
of_property_read_string(root_node, "model", &of_model);
|
||||
|
||||
__of_parse_phandles(root_node);
|
||||
of_tree_for_each_node_from(node, root_node)
|
||||
if (node->phandle)
|
||||
list_add_tail(&node->phandles, &phandle_list);
|
||||
|
||||
memory = of_find_node_by_path("/memory");
|
||||
if (memory)
|
||||
|
|
|
@ -185,9 +185,12 @@ struct device_node *of_unflatten_dtb(struct device_node *root, void *infdt)
|
|||
if (merge && p) {
|
||||
free(p->value);
|
||||
p->value = xzalloc(len);
|
||||
p->length = len;
|
||||
memcpy(p->value, nodep, len);
|
||||
} else {
|
||||
of_new_property(node, name, nodep, len);
|
||||
p = of_new_property(node, name, nodep, len);
|
||||
if (!strcmp(name, "phandle") && len == 4)
|
||||
node->phandle = be32_to_cpup(p->value);
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
16
include/of.h
16
include/of.h
|
@ -124,6 +124,8 @@ extern struct device_node *of_find_node_by_path_from(struct device_node *from,
|
|||
const char *path);
|
||||
extern struct device_node *of_find_node_by_path(const char *path);
|
||||
extern struct device_node *of_find_node_by_phandle(phandle phandle);
|
||||
extern struct device_node *of_find_node_by_type(struct device_node *from,
|
||||
const char *type);
|
||||
extern struct device_node *of_find_compatible_node(struct device_node *from,
|
||||
const char *type, const char *compat);
|
||||
extern const struct of_device_id *of_match_node(
|
||||
|
@ -689,4 +691,18 @@ int of_device_enable_path(const char *path);
|
|||
int of_device_disable(struct device_node *node);
|
||||
int of_device_disable_path(const char *path);
|
||||
|
||||
phandle of_get_tree_max_phandle(struct device_node *root);
|
||||
phandle of_node_create_phandle(struct device_node *node);
|
||||
struct device_node *of_find_node_by_alias(struct device_node *root,
|
||||
const char *alias);
|
||||
struct device_node *of_find_node_by_path_or_alias(struct device_node *root,
|
||||
const char *str);
|
||||
|
||||
static inline struct device_node *of_find_root_node(struct device_node *node)
|
||||
{
|
||||
while (node->parent)
|
||||
node = node->parent;
|
||||
|
||||
return node;
|
||||
}
|
||||
#endif /* __OF_H */
|
||||
|
|
Loading…
Reference in New Issue