mirror of
https://github.com/Fishwaldo/u-boot.git
synced 2025-03-17 12:41:32 +00:00
Merge git://git.denx.de/u-boot-fdt
This commit is contained in:
commit
2110957763
4 changed files with 282 additions and 0 deletions
|
@ -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
|
||||
|
|
|
@ -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) */
|
||||
/**********************************************************************/
|
||||
|
|
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;
|
||||
}
|
||||
|
||||
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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue