9
0
Fork 0

Merge branch 'for-next/of'

This commit is contained in:
Sascha Hauer 2013-09-05 10:37:54 +02:00
commit 10169a04ca
5 changed files with 191 additions and 23 deletions

View File

@ -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

View File

@ -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;

View File

@ -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)

View File

@ -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;

View File

@ -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 */