All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH 11/22] OF: base: import of_find_matching_node_and_match from Linux OF API
@ 2013-07-02 18:35 NISHIMOTO Hiroki
  2013-07-03 21:14 ` Sebastian Hesselbarth
  0 siblings, 1 reply; 3+ messages in thread
From: NISHIMOTO Hiroki @ 2013-07-02 18:35 UTC (permalink / raw)
  To: Sebastian Hesselbarth, barebox

Hi,

on master/next branch,

of_find_matching_node_and_match macro can make infinite loop.

This is because, of_tree_for_each_node traverse all nodes each time.
But a callee of of_find_matching_node_and_match,
such as for_each_matching_node, calls it by changing "from" arg.
So if "matches" have two or more nodes, previously matched node can be re-matched.

Below change can fix the issue.
Or is it better to port node->allnext from linux kernel?

Signed-off-by: NISHIMOTO Hiroki <hiroki.nishimoto.if@gmail.com>
---
 drivers/of/base.c | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/drivers/of/base.c b/drivers/of/base.c
index 63ff647..36774de 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -36,6 +36,9 @@
 #define of_tree_for_each_node(node, root) \
 	list_for_each_entry(node, &root->list, list)
 
+#define of_get_next_node(np) \
+	list_first_entry(&np->list, typeof(*np), list)
+
 /**
  * struct alias_prop - Alias property in 'aliases' node
  * @link:	List node to link the structure in aliases_lookup list
@@ -444,17 +447,20 @@ struct device_node *of_find_matching_node_and_match(struct device_node *from,
 	if (match)
 		*match = NULL;
 
-	if (!from)
-		from = root_node;
+	np = from ? of_get_next_node(from) : root_node;
 
-	of_tree_for_each_node(np, from) {
+	if (from != NULL && np == root_node)
+		return NULL;
+
+	do {
 		const struct of_device_id *m = of_match_node(matches, np);
 		if (m) {
 			if (match)
 				*match = m;
 			return np;
 		}
-	}
+		np = of_get_next_node(np);
+	} while (np != root_node);
 
 	return NULL;
 }
-- 
1.8.1.2


> This imports of_find_matching_node_and_match and corresponding helpers
> from Linux OF API.
> 
> Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@xxxxxxxxx>
> ---
> Cc: barebox@xxxxxxxxxxxxxxxxxxx
> ---
>  drivers/of/base.c |   37 +++++++++++++++++++++++++++++++++++++
>  include/of.h      |   24 ++++++++++++++++++++++++
>  2 files changed, 61 insertions(+), 0 deletions(-)
> 
> diff --git a/drivers/of/base.c b/drivers/of/base.c
> index 50a3c22..218cb5a 100644
> --- a/drivers/of/base.c
> +++ b/drivers/of/base.c
> @@ -389,6 +389,43 @@ const struct of_device_id *of_match_node(const struct of_device_id *matches,
>  	return NULL;
>  }
>  
> +/**
> + *	of_find_matching_node_and_match - Find a node based on an of_device_id
> + *					  match table.
> + *	@from:		The node to start searching from or NULL, the node
> + *			you pass will not be searched, only the next one
> + *			will; typically, you pass what the previous call
> + *			returned.
> + *	@matches:	array of of device match structures to search in
> + *	@match		Updated to point at the matches entry which matched
> + *
> + *	Returns a pointer to the node found or NULL.
> + */
> +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)
> +{
> +	struct device_node *np;
> +
> +	if (match)
> +		*match = NULL;
> +
> +	if (!from)
> +		from = root_node;
> +
> +	of_tree_for_each_node(np, from) {
> +		const struct of_device_id *m = of_match_node(matches, np);
> +		if (m) {
> +			if (match)
> +				*match = m;
> +			return np;
> +		}
> +	}
> +
> +	return NULL;
> +}
> +EXPORT_SYMBOL(of_find_matching_node_and_match);
> +
>  int of_match(struct device_d *dev, struct driver_d *drv)
>  {
>  	const struct of_device_id *id;
> diff --git a/include/of.h b/include/of.h
> index e170e2b..c21e73d 100644
> --- a/include/of.h
> +++ b/include/of.h
> @@ -187,6 +187,10 @@ extern struct device_node *of_find_node_by_name(struct device_node *from,
>  extern struct device_node *of_find_node_by_path(const char *path);
>  extern struct device_node *of_find_compatible_node(struct device_node *from,
>  	const char *type, const char *compat);
> +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);
>  extern int of_device_is_available(const struct device_node *device);
>  
>  extern void of_alias_scan(void);
> @@ -259,6 +263,14 @@ static inline struct device_node *of_find_compatible_node(
>  	return NULL;
>  }
>  
> +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 NULL;
> +}
> +
>  static inline int of_device_is_available(const struct device_node *device)
>  {
>  	return 0;
> @@ -285,5 +297,17 @@ static inline const char *of_alias_get(struct device_node *np)
>  #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))
> +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))
>  
>  #endif /* __OF_H */
> -- 
> 1.7.2.5



_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply related	[flat|nested] 3+ messages in thread
* [PATCH 00/22] Barebox OF API fixes, sync, and cleanup
@ 2013-06-18 17:29 Sebastian Hesselbarth
  2013-06-18 17:29 ` [PATCH 11/22] OF: base: import of_find_matching_node_and_match from Linux OF API Sebastian Hesselbarth
  0 siblings, 1 reply; 3+ messages in thread
From: Sebastian Hesselbarth @ 2013-06-18 17:29 UTC (permalink / raw)
  To: Sebastian Hesselbarth; +Cc: barebox

This is a quite large patch set to make Barebox OF API more behave
like Linux OF API. Also, it prepares Barebox to reuse Linux OF address
handling and drivers/of/of_* helpers soon.

The patch set is roughly divided into 5 sections:

(1) Patch 1 introduces case-insensitive string compare functions that will
    be used later during import of Linux OF API functions.

(2) Patches 2 and 3 fix some bugs in existing OF API functions.

(3) Patches 4-8 synchronize existing OF API functions with Linux OF API
    counterparts.

(4) Patches 9-18 import API functions from Linux OF API or introduce new
    functions based on existing Barebox OF API functions.

(5) Patches 19-22 convert to new API functions and remove now obsolete
    functions. Further, it cleans up existing OF include, by providing
    OFTREE prototypes and !OFTREE bogus stubs.

I have tested the patch set with both CONFIG_OFTREE set and not set.

The patch set applied to barebox/next can also be found at
git://github.com/shesselba/barebox-dove.git  barebox-of-sync-v1

Sebastian Hesselbarth (22):
  lib: string: import case-insensitive string compare
  OF: base: bail out early on missing matches for of_match_node
  OF: base: also update property length on of_property_write_u32
  OF: base: export of_alias_scan
  OF: base: convert strcmp to default string compare functions
  OF: base: sync of_find_property with linux OF API
  OF: base: sync of_find_node_by_path with linux OF API
  OF: base: rename of_node_disabled to of_device_is_available
  OF: base: import of_find_node_by_name from Linux OF API
  OF: base: import of_find_compatible_node from Linux OF API
  OF: base: import of_find_matching_node_and_match from Linux OF API
  OF: base: import of_find_node_with_property from Linux OF API
  OF: base: import parent/child functions from Linux OF API
  OF: base: import of_property_read_* helpers from Linux OF API
  OF: base: import of_parse_phandle from Linux OF API
  OF: base: import parse phandle functions from Linux OF API
  OF: base: introduce property write for bool, u8, u16, and u64
  OF: base: import property iterators from Linux OF API
  OF: base: remove of_tree_for_each_node from public API
  OF: base: remove of_find_child_by_name
  OF: base: convert and remove device_node_for_nach_child
  OF: base: cleanup base function include

 arch/arm/boards/at91sam9x5ek/hw_version.c |   10 +-
 arch/arm/boards/highbank/init.c           |   20 +-
 arch/ppc/mach-mpc5xxx/cpu.c               |    4 +-
 commands/of_node.c                        |    2 +-
 commands/of_property.c                    |   12 +-
 commands/oftree.c                         |   11 +-
 common/oftree.c                           |    2 +-
 drivers/i2c/i2c.c                         |    2 +-
 drivers/mfd/stmpe-i2c.c                   |    7 +-
 drivers/of/base.c                         | 1234 +++++++++++++++++++++++------
 drivers/of/fdt.c                          |   14 +-
 drivers/of/gpio.c                         |    9 +-
 drivers/of/of_net.c                       |    6 +-
 drivers/of/partition.c                    |    2 +-
 drivers/pinctrl/pinctrl.c                 |    4 +-
 drivers/spi/spi.c                         |   12 +-
 drivers/usb/imx/chipidea-imx.c            |   14 +-
 include/linux/string.h                    |    9 +
 include/of.h                              |  616 ++++++++++++--
 lib/string.c                              |   60 ++
 net/eth.c                                 |    2 +-
 21 files changed, 1624 insertions(+), 428 deletions(-)
---
Cc: barebox@lists.infradead.org
-- 
1.7.2.5


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2013-07-03 21:14 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-07-02 18:35 [PATCH 11/22] OF: base: import of_find_matching_node_and_match from Linux OF API NISHIMOTO Hiroki
2013-07-03 21:14 ` Sebastian Hesselbarth
  -- strict thread matches above, loose matches on Subject: below --
2013-06-18 17:29 [PATCH 00/22] Barebox OF API fixes, sync, and cleanup Sebastian Hesselbarth
2013-06-18 17:29 ` [PATCH 11/22] OF: base: import of_find_matching_node_and_match from Linux OF API Sebastian Hesselbarth

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.