Merge git://git.denx.de/u-boot-fdt
This commit is contained in:
commit
2110957763
|
@ -40,6 +40,27 @@ struct fdt_memory {
|
||||||
fdt_addr_t end;
|
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.
|
* Compat types that we know about and for which we might have drivers.
|
||||||
* Each is named COMPAT_<dir>_<filename> where <dir> is the directory
|
* 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,
|
int fdtdec_read_fmap_entry(const void *blob, int node, const char *name,
|
||||||
struct fmap_entry *entry);
|
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
|
#endif
|
||||||
|
|
|
@ -163,6 +163,31 @@ int fdt_first_subnode(const void *fdt, int offset);
|
||||||
*/
|
*/
|
||||||
int fdt_next_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 */
|
/* 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);
|
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) */
|
/* Read-only functions (addressing related) */
|
||||||
/**********************************************************************/
|
/**********************************************************************/
|
||||||
|
|
71
lib/fdtdec.c
71
lib/fdtdec.c
|
@ -708,4 +708,75 @@ int fdtdec_read_fmap_entry(const void *blob, int node, const char *name,
|
||||||
|
|
||||||
return 0;
|
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
|
#endif
|
||||||
|
|
|
@ -491,6 +491,82 @@ int fdt_stringlist_contains(const char *strlist, int listlen, const char *str)
|
||||||
return 0;
|
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,
|
int fdt_node_check_compatible(const void *fdt, int nodeoffset,
|
||||||
const char *compatible)
|
const char *compatible)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue