1
0
Fork 0

Merge git://git.denx.de/u-boot-fdt

utp
Tom Rini 2014-10-23 06:51:46 -04:00
commit 2110957763
4 changed files with 282 additions and 0 deletions

View File

@ -40,6 +40,27 @@ struct fdt_memory {
fdt_addr_t end;
};
/*
* Information about a resource. start is the first address of the resource
* and end is the last address (inclusive). The length of the resource will
* be equal to: end - start + 1.
*/
struct fdt_resource {
fdt_addr_t start;
fdt_addr_t end;
};
/**
* Compute the size of a resource.
*
* @param res the resource to operate on
* @return the size of the resource
*/
static inline fdt_size_t fdt_resource_size(const struct fdt_resource *res)
{
return res->end - res->start + 1;
}
/**
* Compat types that we know about and for which we might have drivers.
* Each is named COMPAT_<dir>_<filename> where <dir> is the directory
@ -597,4 +618,46 @@ struct fmap_entry {
*/
int fdtdec_read_fmap_entry(const void *blob, int node, const char *name,
struct fmap_entry *entry);
/**
* Obtain an indexed resource from a device property.
*
* @param fdt FDT blob
* @param node node to examine
* @param property name of the property to parse
* @param index index of the resource to retrieve
* @param res returns the resource
* @return 0 if ok, negative on error
*/
int fdt_get_resource(const void *fdt, int node, const char *property,
unsigned int index, struct fdt_resource *res);
/**
* Obtain a named resource from a device property.
*
* Look up the index of the name in a list of strings and return the resource
* at that index.
*
* @param fdt FDT blob
* @param node node to examine
* @param property name of the property to parse
* @param prop_names name of the property containing the list of names
* @param name the name of the entry to look up
* @param res returns the resource
*/
int fdt_get_named_resource(const void *fdt, int node, const char *property,
const char *prop_names, const char *name,
struct fdt_resource *res);
/**
* Look at the reg property of a device node that represents a PCI device
* and parse the bus, device and function number from it.
*
* @param fdt FDT blob
* @param node node to examine
* @param bdf returns bus, device, function triplet
* @return 0 if ok, negative on error
*/
int fdtdec_pci_get_bdf(const void *fdt, int node, int *bdf);
#endif

View File

@ -163,6 +163,31 @@ int fdt_first_subnode(const void *fdt, int offset);
*/
int fdt_next_subnode(const void *fdt, int offset);
/**
* fdt_for_each_subnode - iterate over all subnodes of a parent
*
* This is actually a wrapper around a for loop and would be used like so:
*
* fdt_for_each_subnode(fdt, node, parent) {
* ...
* use node
* ...
* }
*
* Note that this is implemented as a macro and node is used as iterator in
* the loop. It should therefore be a locally allocated variable. The parent
* variable on the other hand is never modified, so it can be constant or
* even a literal.
*
* @fdt: FDT blob (const void *)
* @node: child node (int)
* @parent: parent node (int)
*/
#define fdt_for_each_subnode(fdt, node, parent) \
for (node = fdt_first_subnode(fdt, parent); \
node >= 0; \
node = fdt_next_subnode(fdt, node))
/**********************************************************************/
/* General functions */
/**********************************************************************/
@ -857,6 +882,53 @@ int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
*/
int fdt_stringlist_contains(const char *strlist, int listlen, const char *str);
/**
* fdt_count_strings - count the number of strings in a string list
* @fdt: pointer to the device tree blob
* @node: offset of the node
* @property: name of the property containing the string list
* @return: the number of strings in the given property
*/
int fdt_count_strings(const void *fdt, int node, const char *property);
/**
* fdt_find_string - find a string in a string list and return its index
* @fdt: pointer to the device tree blob
* @node: offset of the node
* @property: name of the property containing the string list
* @string: string to look up in the string list
* @return: the index of the string or negative on error
*/
int fdt_find_string(const void *fdt, int node, const char *property,
const char *string);
/**
* fdt_get_string_index() - obtain the string at a given index in a string list
* @fdt: pointer to the device tree blob
* @node: offset of the node
* @property: name of the property containing the string list
* @index: index of the string to return
* @output: return location for the string
* @return: 0 if the string was found or a negative error code otherwise
*/
int fdt_get_string_index(const void *fdt, int node, const char *property,
int index, const char **output);
/**
* fdt_get_string() - obtain the string at a given index in a string list
* @fdt: pointer to the device tree blob
* @node: offset of the node
* @property: name of the property containing the string list
* @output: return location for the string
* @return: 0 if the string was found or a negative error code otherwise
*
* This is a shortcut for:
*
* fdt_get_string_index(fdt, node, property, 0, output).
*/
int fdt_get_string(const void *fdt, int node, const char *property,
const char **output);
/**********************************************************************/
/* Read-only functions (addressing related) */
/**********************************************************************/

View File

@ -708,4 +708,75 @@ int fdtdec_read_fmap_entry(const void *blob, int node, const char *name,
return 0;
}
static u64 fdtdec_get_number(const fdt32_t *ptr, unsigned int cells)
{
u64 number = 0;
while (cells--)
number = (number << 32) | fdt32_to_cpu(*ptr++);
return number;
}
int fdt_get_resource(const void *fdt, int node, const char *property,
unsigned int index, struct fdt_resource *res)
{
const fdt32_t *ptr, *end;
int na, ns, len, parent;
unsigned int i = 0;
parent = fdt_parent_offset(fdt, node);
if (parent < 0)
return parent;
na = fdt_address_cells(fdt, parent);
ns = fdt_size_cells(fdt, parent);
ptr = fdt_getprop(fdt, node, property, &len);
if (!ptr)
return len;
end = ptr + len / sizeof(*ptr);
while (ptr + na + ns <= end) {
if (i == index) {
res->start = res->end = fdtdec_get_number(ptr, na);
res->end += fdtdec_get_number(&ptr[na], ns) - 1;
return 0;
}
ptr += na + ns;
i++;
}
return -FDT_ERR_NOTFOUND;
}
int fdt_get_named_resource(const void *fdt, int node, const char *property,
const char *prop_names, const char *name,
struct fdt_resource *res)
{
int index;
index = fdt_find_string(fdt, node, prop_names, name);
if (index < 0)
return index;
return fdt_get_resource(fdt, node, property, index, res);
}
int fdtdec_pci_get_bdf(const void *fdt, int node, int *bdf)
{
const fdt32_t *prop;
int len;
prop = fdt_getprop(fdt, node, "reg", &len);
if (!prop)
return len;
*bdf = fdt32_to_cpu(*prop) & 0xffffff;
return 0;
}
#endif

View File

@ -491,6 +491,82 @@ int fdt_stringlist_contains(const char *strlist, int listlen, const char *str)
return 0;
}
int fdt_count_strings(const void *fdt, int node, const char *property)
{
int length, i, count = 0;
const char *list;
list = fdt_getprop(fdt, node, property, &length);
if (!list)
return -length;
for (i = 0; i < length; i++) {
int len = strlen(list);
list += len + 1;
i += len;
count++;
}
return count;
}
int fdt_find_string(const void *fdt, int node, const char *property,
const char *string)
{
const char *list, *end;
int len, index = 0;
list = fdt_getprop(fdt, node, property, &len);
if (!list)
return len;
end = list + len;
len = strlen(string);
while (list < end) {
int l = strlen(list);
if (l == len && memcmp(list, string, len) == 0)
return index;
list += l + 1;
index++;
}
return -FDT_ERR_NOTFOUND;
}
int fdt_get_string_index(const void *fdt, int node, const char *property,
int index, const char **output)
{
const char *list;
int length, i;
list = fdt_getprop(fdt, node, property, &length);
for (i = 0; i < length; i++) {
int len = strlen(list);
if (index == 0) {
*output = list;
return 0;
}
list += len + 1;
i += len;
index--;
}
return FDT_ERR_NOTFOUND;
}
int fdt_get_string(const void *fdt, int node, const char *property,
const char **output)
{
return fdt_get_string_index(fdt, node, property, 0, output);
}
int fdt_node_check_compatible(const void *fdt, int nodeoffset,
const char *compatible)
{