From c541adc637066407d4cda9db14dcb0e618966a4c Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Wed, 4 Apr 2012 09:27:46 -0600 Subject: [PATCH] dt: add property iteration helpers This patch adds macros of_property_for_each_u32() and of_property_for_each_string(), which iterate over an array of values within a device-tree property. Usage is for example: struct property *prop; const __be32 *p; u32 u; of_property_for_each_u32(np, "propname", prop, p, u) printk("U32 value: %x\n", u); struct property *prop; const char *s; of_property_for_each_string(np, "propname", prop, s) printk("String value: %s\n", s); Based on work by Rob Herring Cc: Grant Likely Signed-off-by: Stephen Warren Acked-by: Rob Herring Signed-off-by: Linus Walleij --- drivers/of/base.c | 41 +++++++++++++++++++++++++++++++++++++++++ include/linux/of.h | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) diff --git a/drivers/of/base.c b/drivers/of/base.c index 580644986945..d9bfd49b1935 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -1260,3 +1260,44 @@ int of_alias_get_id(struct device_node *np, const char *stem) return id; } EXPORT_SYMBOL_GPL(of_alias_get_id); + +const __be32 *of_prop_next_u32(struct property *prop, const __be32 *cur, + u32 *pu) +{ + const void *curv = cur; + + if (!prop) + return NULL; + + if (!cur) { + curv = prop->value; + goto out_val; + } + + curv += sizeof(*cur); + if (curv >= prop->value + prop->length) + return NULL; + +out_val: + *pu = be32_to_cpup(curv); + return curv; +} +EXPORT_SYMBOL_GPL(of_prop_next_u32); + +const char *of_prop_next_string(struct property *prop, const char *cur) +{ + const void *curv = cur; + + if (!prop) + return NULL; + + if (!cur) + return prop->value; + + curv += strlen(cur) + 1; + if (curv >= prop->value + prop->length) + return NULL; + + return curv; +} +EXPORT_SYMBOL_GPL(of_prop_next_string); diff --git a/include/linux/of.h b/include/linux/of.h index fa7fb1d97458..e3f942d9da89 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -259,6 +259,37 @@ extern void of_detach_node(struct device_node *); #endif #define of_match_ptr(_ptr) (_ptr) + +/* + * struct property *prop; + * const __be32 *p; + * u32 u; + * + * of_property_for_each_u32(np, "propname", prop, p, u) + * printk("U32 value: %x\n", u); + */ +const __be32 *of_prop_next_u32(struct property *prop, const __be32 *cur, + u32 *pu); +#define of_property_for_each_u32(np, propname, prop, p, u) \ + for (prop = of_find_property(np, propname, NULL), \ + p = of_prop_next_u32(prop, NULL, &u); \ + p; \ + p = of_prop_next_u32(prop, p, &u)) + +/* + * struct property *prop; + * const char *s; + * + * of_property_for_each_string(np, "propname", prop, s) + * printk("String value: %s\n", s); + */ +const char *of_prop_next_string(struct property *prop, const char *cur); +#define of_property_for_each_string(np, propname, prop, s) \ + for (prop = of_find_property(np, propname, NULL), \ + s = of_prop_next_string(prop, NULL); \ + s; \ + s = of_prop_next_string(prop, s)) + #else /* CONFIG_OF */ static inline bool of_have_populated_dt(void) @@ -349,6 +380,10 @@ static inline int of_machine_is_compatible(const char *compat) #define of_match_ptr(_ptr) NULL #define of_match_node(_matches, _node) NULL +#define of_property_for_each_u32(np, propname, prop, p, u) \ + while (0) +#define of_property_for_each_string(np, propname, prop, s) \ + while (0) #endif /* CONFIG_OF */ /**