Message ID | 1314315824-9687-12-git-send-email-swarren@nvidia.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Thu, Aug 25, 2011 at 05:43:42PM -0600, Stephen Warren wrote: > This patch adds macros for_each_u32_property_value and > for_each_string_property_value, which iterate over an array of values > within a device-tree property. Usage is for example: > > struct of_iter_string_prop iter; > for_each_string_property_value(iter, np, "pins") > printk("Got value %s\n", iter.value); > > Signed-off-by: Stephen Warren <swarren@nvidia.com> Nicely implemented! For the !CONFIG_OF case, I *think* that of_iter_u32_prop and of_iter_string_prop can be empty struct's, but I wouldn't want to bet money on that! Reviewed-by: Jamie Iles <jamie@jamieiles.com>
Jamie Iles wrote at Friday, August 26, 2011 3:27 AM: > On Thu, Aug 25, 2011 at 05:43:42PM -0600, Stephen Warren wrote: > > This patch adds macros for_each_u32_property_value and > > for_each_string_property_value, which iterate over an array of values > > within a device-tree property. Usage is for example: > > > > struct of_iter_string_prop iter; > > for_each_string_property_value(iter, np, "pins") > > printk("Got value %s\n", iter.value); > > > > Signed-off-by: Stephen Warren <swarren@nvidia.com> > > Nicely implemented! Thanks! > For the !CONFIG_OF case, I *think* that > of_iter_u32_prop and of_iter_string_prop can be empty struct's, but I > wouldn't want to bet money on that! Empty structs themselves certainly did compile OK, but the code that uses these macros references iter.value directly, and isn't under #ifdef CONFIG_OF, so that field has to exist. I suppose an alternative would be to add an accessor function: struct of_iter_string_prop iter; for_each_string_property_value(iter, np, "pins") printk("Got value %s\n", of_iter_string_value(iter)); which would return NULL/"" when !CONFIG_OF, and hence allow iter.value to be removed too. Do you think that's a good approach? It'd be easy to implement.
On Fri, Aug 26, 2011 at 08:59:44AM -0700, Stephen Warren wrote: > Jamie Iles wrote at Friday, August 26, 2011 3:27 AM: > > For the !CONFIG_OF case, I *think* that > > of_iter_u32_prop and of_iter_string_prop can be empty struct's, but I > > wouldn't want to bet money on that! > > Empty structs themselves certainly did compile OK, but the code that > uses these macros references iter.value directly, and isn't under #ifdef > CONFIG_OF, so that field has to exist. > > I suppose an alternative would be to add an accessor function: > > struct of_iter_string_prop iter; > for_each_string_property_value(iter, np, "pins") > printk("Got value %s\n", of_iter_string_value(iter)); > > which would return NULL/"" when !CONFIG_OF, and hence allow iter.value > to be removed too. Do you think that's a good approach? It'd be easy to > implement. I think I prefer what you have now rather than a separate accessor, but I'm happy either way! Jamie
diff --git a/include/linux/of_iter_prop.h b/include/linux/of_iter_prop.h new file mode 100644 index 0000000..c7fb2bf --- /dev/null +++ b/include/linux/of_iter_prop.h @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2011 NVIDIA Inc. + * + * Iterate over properties that store arrays. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef __OF_ITER_PROP_H__ +#define __OF_ITER_PROP_H__ + +#include <linux/of.h> + +#ifdef CONFIG_OF +struct of_iter_u32_prop { + const struct property *prop; + int len; + const __be32 *pvalue; + u32 value; +}; + +static inline void of_iter_u32_next(struct of_iter_u32_prop *iter) +{ + if (iter->len < 0) + return; + + iter->value = be32_to_cpup(iter->pvalue++); + iter->len--; +} + +static inline void of_iter_u32_init(struct of_iter_u32_prop *iter, + const struct device_node *np, + const char *name) +{ + iter->prop = of_find_property(np, name, &iter->len); + if (!iter->prop) { + iter->len = -1; + return; + } + + iter->pvalue = iter->prop->value; + if (!iter->pvalue) { + iter->len = -1; + return; + } + + iter->len /= sizeof(*iter->pvalue); + + of_iter_u32_next(iter); +} + +static inline bool of_iter_u32_test(struct of_iter_u32_prop *iter) +{ + return iter->len >= 0; +} + +#define for_each_u32_property_value(iter, np, prop_name) \ + for (of_iter_u32_init(&iter, np, prop_name); \ + of_iter_u32_test(&iter); \ + of_iter_u32_next(&iter)) + +struct of_iter_string_prop { + const struct property *prop; + int len; + const char *value; + const char *after; +}; + +static inline void of_iter_string_init(struct of_iter_string_prop *iter, + const struct device_node *np, + const char *name) +{ + iter->prop = of_find_property(np, name, &iter->len); + if (!iter->prop) { + iter->value = NULL; + return; + } + + iter->value = iter->prop->value; + if (!iter->value) + return; + + iter->after = iter->value + iter->len; +} + +static inline bool of_iter_string_test(struct of_iter_string_prop *iter) +{ + if (!iter->value) + return false; + + return iter->value < iter->after; +} + +static inline void of_iter_string_next(struct of_iter_string_prop *iter) +{ + int len; + + if (!iter->value) + return; + + len = strnlen(iter->value, iter->len); + iter->len -= len; + iter->value += len + 1; +} + +#define for_each_string_property_value(iter, np, prop_name) \ + for (of_iter_string_init(&iter, np, prop_name); \ + of_iter_string_test(&iter); \ + of_iter_string_next(&iter)) + +#else +struct of_iter_u32_prop { + u32 value; +}; + +#define for_each_u32_property_value(iter, np, prop_name) \ + while (0) + +struct of_iter_string_prop { + const char *value; +}; + +#define for_each_string_property_value(iter, np, prop_name) \ + while (0) + +#endif /* CONFIG_OF */ + +#endif /* __OF_ITER_PROP_H__ */
This patch adds macros for_each_u32_property_value and for_each_string_property_value, which iterate over an array of values within a device-tree property. Usage is for example: struct of_iter_string_prop iter; for_each_string_property_value(iter, np, "pins") printk("Got value %s\n", iter.value); Signed-off-by: Stephen Warren <swarren@nvidia.com> --- include/linux/of_iter_prop.h | 135 ++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 135 insertions(+), 0 deletions(-) create mode 100644 include/linux/of_iter_prop.h