}
EXPORT_SYMBOL(of_get_cpu_node);
--------/** Checks if the given "compat" string matches one of the strings in
-------- * the device's "compatible" property
++++++++/**
++++++++ * __of_device_is_compatible() - Check if the node matches given constraints
++++++++ * @device: pointer to node
++++++++ * @compat: required compatible string, NULL or "" for any match
++++++++ * @type: required device_type value, NULL or "" for any match
++++++++ * @name: required node name, NULL or "" for any match
++++++++ *
++++++++ * Checks if the given @compat, @type and @name strings match the
++++++++ * properties of the given @device. A constraints can be skipped by
++++++++ * passing NULL or an empty string as the constraint.
++++++++ *
++++++++ * Returns 0 for no match, and a positive integer on match. The return
++++++++ * value is a relative score with larger values indicating better
++++++++ * matches. The score is weighted for the most specific compatible value
++++++++ * to get the highest score. Matching type is next, followed by matching
++++++++ * name. Practically speaking, this results in the following priority
++++++++ * order for matches:
++++++++ *
++++++++ * 1. specific compatible && type && name
++++++++ * 2. specific compatible && type
++++++++ * 3. specific compatible && name
++++++++ * 4. specific compatible
++++++++ * 5. general compatible && type && name
++++++++ * 6. general compatible && type
++++++++ * 7. general compatible && name
++++++++ * 8. general compatible
++++++++ * 9. type && name
++++++++ * 10. type
++++++++ * 11. name
*/
static int __of_device_is_compatible(const struct device_node *device,
-------- const char *compat)
++++++++ const char *compat, const char *type, const char *name)
{
-------- const char* cp;
-------- int cplen, l;
++++++++ struct property *prop;
++++++++ const char *cp;
++++++++ int index = 0, score = 0;
++++++++
++++++++ /* Compatible match has highest priority */
++++++++ if (compat && compat[0]) {
++++++++ prop = __of_find_property(device, "compatible", NULL);
++++++++ for (cp = of_prop_next_string(prop, NULL); cp;
++++++++ cp = of_prop_next_string(prop, cp), index++) {
++++++++ if (of_compat_cmp(cp, compat, strlen(compat)) == 0) {
++++++++ score = INT_MAX/2 - (index << 2);
++++++++ break;
++++++++ }
++++++++ }
++++++++ if (!score)
++++++++ return 0;
++++++++ }
-------- cp = __of_get_property(device, "compatible", &cplen);
-------- if (cp == NULL)
-------- return 0;
-------- while (cplen > 0) {
-------- if (of_compat_cmp(cp, compat, strlen(compat)) == 0)
-------- return 1;
-------- l = strlen(cp) + 1;
-------- cp += l;
-------- cplen -= l;
++++++++ /* Matching type is better than matching name */
++++++++ if (type && type[0]) {
++++++++ if (!device->type || of_node_cmp(type, device->type))
++++++++ return 0;
++++++++ score += 2;
}
-------- return 0;
++++++++ /* Matching name is a bit better than not */
++++++++ if (name && name[0]) {
++++++++ if (!device->name || of_node_cmp(name, device->name))
++++++++ return 0;
++++++++ score++;
++++++++ }
++++++++
++++++++ return score;
}
/** Checks if the given "compat" string matches one of the strings in
int res;
raw_spin_lock_irqsave(&devtree_lock, flags);
-------- res = __of_device_is_compatible(device, compat);
++++++++ res = __of_device_is_compatible(device, compat, NULL, NULL);
raw_spin_unlock_irqrestore(&devtree_lock, flags);
return res;
}
raw_spin_lock_irqsave(&devtree_lock, flags);
np = from ? from->allnext : of_allnodes;
for (; np; np = np->allnext) {
-------- if (type
-------- && !(np->type && (of_node_cmp(np->type, type) == 0)))
-------- continue;
-------- if (__of_device_is_compatible(np, compatible) &&
++++++++ if (__of_device_is_compatible(np, compatible, type, NULL) &&
of_node_get(np))
break;
}
const struct of_device_id *__of_match_node(const struct of_device_id *matches,
const struct device_node *node)
{
-------- const char *cp;
-------- int cplen, l;
++++++++ const struct of_device_id *best_match = NULL;
++++++++ int score, best_score = 0;
if (!matches)
return NULL;
-------- cp = __of_get_property(node, "compatible", &cplen);
-------- do {
-------- const struct of_device_id *m = matches;
--------
-------- /* Check against matches with current compatible string */
-------- while (m->name[0] || m->type[0] || m->compatible[0]) {
-------- int match = 1;
-------- if (m->name[0])
-------- match &= node->name
-------- && !strcmp(m->name, node->name);
-------- if (m->type[0])
-------- match &= node->type
-------- && !strcmp(m->type, node->type);
-------- if (m->compatible[0])
-------- match &= cp
-------- && !of_compat_cmp(m->compatible, cp,
-------- strlen(m->compatible));
-------- if (match)
-------- return m;
-------- m++;
---- --- }
---- ---
---- --- /* Get node's next compatible string */
---- --- if (cp) {
---- --- l = strlen(cp) + 1;
---- --- cp += l;
---- --- cplen -= l;
++++++++ for (; matches->name[0] || matches->type[0] || matches->compatible[0]; matches++) {
++++++++ score = __of_device_is_compatible(node, matches->compatible,
++++++++ matches->type, matches->name);
++++++++ if (score > best_score) {
++++++++ best_match = matches;
++++++++ best_score = score;
}
---- --- } while (cp && (cplen > 0));
++++++++ }
- /* Get node's next compatible string */
- if (cp) {
- l = strlen(cp) + 1;
- cp += l;
- cplen -= l;
- }
- } while (cp && (cplen > 0));
-
-------- return NULL;
++++++++ return best_match;
}
/**
* @matches: array of of device match structures to search in
* @node: the of device structure to match against
*
-------- * Low level utility function used by device matching. Matching order
-------- * is to compare each of the node's compatibles with all given matches
-------- * first. This implies node's compatible is sorted from specific to
-------- * generic while matches can be in any order.
++++++++ * Low level utility function used by device matching.
*/
const struct of_device_id *of_match_node(const struct of_device_id *matches,
const struct device_node *node)
}
EXPORT_SYMBOL(of_find_node_by_phandle);
+++++ +++/**
+++++ +++ * of_property_count_elems_of_size - Count the number of elements in a property
+++++ +++ *
+++++ +++ * @np: device node from which the property value is to be read.
+++++ +++ * @propname: name of the property to be searched.
+++++ +++ * @elem_size: size of the individual element
+++++ +++ *
+++++ +++ * Search for a property in a device node and count the number of elements of
+++++ +++ * size elem_size in it. Returns number of elements on sucess, -EINVAL if the
+++++ +++ * property does not exist or its length does not match a multiple of elem_size
+++++ +++ * and -ENODATA if the property does not have a value.
+++++ +++ */
+++++ +++int of_property_count_elems_of_size(const struct device_node *np,
+++++ +++ const char *propname, int elem_size)
+++++ +++{
+++++ +++ struct property *prop = of_find_property(np, propname, NULL);
+++++ +++
+++++ +++ if (!prop)
+++++ +++ return -EINVAL;
+++++ +++ if (!prop->value)
+++++ +++ return -ENODATA;
+++++ +++
+++++ +++ if (prop->length % elem_size != 0) {
+++++ +++ pr_err("size of %s in node %s is not a multiple of %d\n",
+++++ +++ propname, np->full_name, elem_size);
+++++ +++ return -EINVAL;
+++++ +++ }
+++++ +++
+++++ +++ return prop->length / elem_size;
+++++ +++}
+++++ +++EXPORT_SYMBOL_GPL(of_property_count_elems_of_size);
+++++ +++
/**
* of_find_property_value_of_size
*
extern struct device_node *of_find_node_by_name(struct device_node *from,
const char *name);
--------#define for_each_node_by_name(dn, name) \
-------- for (dn = of_find_node_by_name(NULL, name); dn; \
-------- dn = of_find_node_by_name(dn, name))
extern struct device_node *of_find_node_by_type(struct device_node *from,
const char *type);
--------#define for_each_node_by_type(dn, type) \
-------- for (dn = of_find_node_by_type(NULL, type); dn; \
-------- dn = of_find_node_by_type(dn, type))
extern struct device_node *of_find_compatible_node(struct device_node *from,
const char *type, const char *compat);
--------#define for_each_compatible_node(dn, type, compatible) \
-------- for (dn = of_find_compatible_node(NULL, type, compatible); dn; \
-------- dn = of_find_compatible_node(dn, type, compatible))
extern struct device_node *of_find_matching_node_and_match(
struct device_node *from,
const struct of_device_id *matches,
const struct of_device_id **match);
--------static inline struct device_node *of_find_matching_node(
-------- struct device_node *from,
-------- const struct of_device_id *matches)
--------{
-------- return of_find_matching_node_and_match(from, matches, NULL);
--------}
--------#define for_each_matching_node(dn, matches) \
-------- for (dn = of_find_matching_node(NULL, matches); dn; \
-------- dn = of_find_matching_node(dn, matches))
--------#define for_each_matching_node_and_match(dn, matches, match) \
-------- for (dn = of_find_matching_node_and_match(NULL, matches, match); \
-------- dn; dn = of_find_matching_node_and_match(dn, matches, match))
++++++++
extern struct device_node *of_find_node_by_path(const char *path);
extern struct device_node *of_find_node_by_phandle(phandle handle);
extern struct device_node *of_get_parent(const struct device_node *node);
extern struct device_node *of_get_child_by_name(const struct device_node *node,
const char *name);
--------#define for_each_child_of_node(parent, child) \
-------- for (child = of_get_next_child(parent, NULL); child != NULL; \
-------- child = of_get_next_child(parent, child))
--------
--------#define for_each_available_child_of_node(parent, child) \
-------- for (child = of_get_next_available_child(parent, NULL); child != NULL; \
-------- child = of_get_next_available_child(parent, child))
--------
--------static inline int of_get_child_count(const struct device_node *np)
--------{
-------- struct device_node *child;
-------- int num = 0;
--------
-------- for_each_child_of_node(np, child)
-------- num++;
--------
-------- return num;
--------}
--------
--------static inline int of_get_available_child_count(const struct device_node *np)
--------{
-------- struct device_node *child;
-------- int num = 0;
--------
-------- for_each_available_child_of_node(np, child)
-------- num++;
--------
-------- return num;
--------}
/* cache lookup */
extern struct device_node *of_find_next_cache_node(const struct device_node *);
extern struct device_node *of_find_node_with_property(
struct device_node *from, const char *prop_name);
--------#define for_each_node_with_property(dn, prop_name) \
-------- for (dn = of_find_node_with_property(NULL, prop_name); dn; \
-------- dn = of_find_node_with_property(dn, prop_name))
extern struct property *of_find_property(const struct device_node *np,
const char *name,
int *lenp);
+++++ +++extern int of_property_count_elems_of_size(const struct device_node *np,
+++++ +++ const char *propname, int elem_size);
extern int of_property_read_u32_index(const struct device_node *np,
const char *propname,
u32 index, u32 *out_value);
return NULL;
}
--------static inline struct device_node *of_get_parent(const struct device_node *node)
++++++++static inline struct device_node *of_find_node_by_type(struct device_node *from,
++++++++ const char *type)
{
return NULL;
}
--------static inline bool of_have_populated_dt(void)
++++++++static inline struct device_node *of_find_matching_node_and_match(
++++++++ struct device_node *from,
++++++++ const struct of_device_id *matches,
++++++++ const struct of_device_id **match)
{
-------- return false;
++++++++ return NULL;
}
--------/* Kill an unused variable warning on a device_node pointer */
--------static inline void __of_use_dn(const struct device_node *np)
++++++++static inline struct device_node *of_get_parent(const struct device_node *node)
{
++++++++ return NULL;
}
--------#define for_each_child_of_node(parent, child) \
-------- while (__of_use_dn(parent), __of_use_dn(child), 0)
++++++++static inline struct device_node *of_get_next_child(
++++++++ const struct device_node *node, struct device_node *prev)
++++++++{
++++++++ return NULL;
++++++++}
--------#define for_each_available_child_of_node(parent, child) \
-------- while (0)
++++++++static inline struct device_node *of_get_next_available_child(
++++++++ const struct device_node *node, struct device_node *prev)
++++++++{
++++++++ return NULL;
++++++++}
--------static inline struct device_node *of_get_child_by_name(
-------- const struct device_node *node,
-------- const char *name)
++++++++static inline struct device_node *of_find_node_with_property(
++++++++ struct device_node *from, const char *prop_name)
{
return NULL;
}
--------static inline int of_get_child_count(const struct device_node *np)
++++++++static inline bool of_have_populated_dt(void)
{
-------- return 0;
++++++++ return false;
}
--------static inline int of_get_available_child_count(const struct device_node *np)
++++++++static inline struct device_node *of_get_child_by_name(
++++++++ const struct device_node *node,
++++++++ const char *name)
{
-------- return 0;
++++++++ return NULL;
}
static inline int of_device_is_compatible(const struct device_node *device,
return NULL;
}
+++++ +++static inline int of_property_count_elems_of_size(const struct device_node *np,
+++++ +++ const char *propname, int elem_size)
+++++ +++{
+++++ +++ return -ENOSYS;
+++++ +++}
+++++ +++
static inline int of_property_read_u32_index(const struct device_node *np,
const char *propname, u32 index, u32 *out_value)
{
static inline int of_node_to_nid(struct device_node *device) { return 0; }
#endif
++++++++static inline struct device_node *of_find_matching_node(
++++++++ struct device_node *from,
++++++++ const struct of_device_id *matches)
++++++++{
++++++++ return of_find_matching_node_and_match(from, matches, NULL);
++++++++}
++++++++
+++++ +++/**
+++++ +++ * of_property_count_u8_elems - Count the number of u8 elements in a property
+++++ +++ *
+++++ +++ * @np: device node from which the property value is to be read.
+++++ +++ * @propname: name of the property to be searched.
+++++ +++ *
+++++ +++ * Search for a property in a device node and count the number of u8 elements
+++++ +++ * in it. Returns number of elements on sucess, -EINVAL if the property does
+++++ +++ * not exist or its length does not match a multiple of u8 and -ENODATA if the
+++++ +++ * property does not have a value.
+++++ +++ */
+++++ +++static inline int of_property_count_u8_elems(const struct device_node *np,
+++++ +++ const char *propname)
+++++ +++{
+++++ +++ return of_property_count_elems_of_size(np, propname, sizeof(u8));
+++++ +++}
+++++ +++
+++++ +++/**
+++++ +++ * of_property_count_u16_elems - Count the number of u16 elements in a property
+++++ +++ *
+++++ +++ * @np: device node from which the property value is to be read.
+++++ +++ * @propname: name of the property to be searched.
+++++ +++ *
+++++ +++ * Search for a property in a device node and count the number of u16 elements
+++++ +++ * in it. Returns number of elements on sucess, -EINVAL if the property does
+++++ +++ * not exist or its length does not match a multiple of u16 and -ENODATA if the
+++++ +++ * property does not have a value.
+++++ +++ */
+++++ +++static inline int of_property_count_u16_elems(const struct device_node *np,
+++++ +++ const char *propname)
+++++ +++{
+++++ +++ return of_property_count_elems_of_size(np, propname, sizeof(u16));
+++++ +++}
+++++ +++
+++++ +++/**
+++++ +++ * of_property_count_u32_elems - Count the number of u32 elements in a property
+++++ +++ *
+++++ +++ * @np: device node from which the property value is to be read.
+++++ +++ * @propname: name of the property to be searched.
+++++ +++ *
+++++ +++ * Search for a property in a device node and count the number of u32 elements
+++++ +++ * in it. Returns number of elements on sucess, -EINVAL if the property does
+++++ +++ * not exist or its length does not match a multiple of u32 and -ENODATA if the
+++++ +++ * property does not have a value.
+++++ +++ */
+++++ +++static inline int of_property_count_u32_elems(const struct device_node *np,
+++++ +++ const char *propname)
+++++ +++{
+++++ +++ return of_property_count_elems_of_size(np, propname, sizeof(u32));
+++++ +++}
+++++ +++
+++++ +++/**
+++++ +++ * of_property_count_u64_elems - Count the number of u64 elements in a property
+++++ +++ *
+++++ +++ * @np: device node from which the property value is to be read.
+++++ +++ * @propname: name of the property to be searched.
+++++ +++ *
+++++ +++ * Search for a property in a device node and count the number of u64 elements
+++++ +++ * in it. Returns number of elements on sucess, -EINVAL if the property does
+++++ +++ * not exist or its length does not match a multiple of u64 and -ENODATA if the
+++++ +++ * property does not have a value.
+++++ +++ */
+++++ +++static inline int of_property_count_u64_elems(const struct device_node *np,
+++++ +++ const char *propname)
+++++ +++{
+++++ +++ return of_property_count_elems_of_size(np, propname, sizeof(u64));
+++++ +++}
+++++ +++
/**
* of_property_read_bool - Findfrom a property
* @np: device node from which the property value is to be read.
s; \
s = of_prop_next_string(prop, s))
++++++++#define for_each_node_by_name(dn, name) \
++++++++ for (dn = of_find_node_by_name(NULL, name); dn; \
++++++++ dn = of_find_node_by_name(dn, name))
++++++++#define for_each_node_by_type(dn, type) \
++++++++ for (dn = of_find_node_by_type(NULL, type); dn; \
++++++++ dn = of_find_node_by_type(dn, type))
++++++++#define for_each_compatible_node(dn, type, compatible) \
++++++++ for (dn = of_find_compatible_node(NULL, type, compatible); dn; \
++++++++ dn = of_find_compatible_node(dn, type, compatible))
++++++++#define for_each_matching_node(dn, matches) \
++++++++ for (dn = of_find_matching_node(NULL, matches); dn; \
++++++++ dn = of_find_matching_node(dn, matches))
++++++++#define for_each_matching_node_and_match(dn, matches, match) \
++++++++ for (dn = of_find_matching_node_and_match(NULL, matches, match); \
++++++++ dn; dn = of_find_matching_node_and_match(dn, matches, match))
++++++++
++++++++#define for_each_child_of_node(parent, child) \
++++++++ for (child = of_get_next_child(parent, NULL); child != NULL; \
++++++++ child = of_get_next_child(parent, child))
++++++++#define for_each_available_child_of_node(parent, child) \
++++++++ for (child = of_get_next_available_child(parent, NULL); child != NULL; \
++++++++ child = of_get_next_available_child(parent, child))
++++++++
++++++++#define for_each_node_with_property(dn, prop_name) \
++++++++ for (dn = of_find_node_with_property(NULL, prop_name); dn; \
++++++++ dn = of_find_node_with_property(dn, prop_name))
++++++++
++++++++static inline int of_get_child_count(const struct device_node *np)
++++++++{
++++++++ struct device_node *child;
++++++++ int num = 0;
++++++++
++++++++ for_each_child_of_node(np, child)
++++++++ num++;
++++++++
++++++++ return num;
++++++++}
++++++++
++++++++static inline int of_get_available_child_count(const struct device_node *np)
++++++++{
++++++++ struct device_node *child;
++++++++ int num = 0;
++++++++
++++++++ for_each_available_child_of_node(np, child)
++++++++ num++;
++++++++
++++++++ return num;
++++++++}
++++++++
#if defined(CONFIG_PROC_FS) && defined(CONFIG_PROC_DEVICETREE)
extern void proc_device_tree_add_node(struct device_node *, struct proc_dir_entry *);
extern void proc_device_tree_add_prop(struct proc_dir_entry *pde, struct property *prop);