Johnny Hughes
2019-02-04 c1f36c28393a7bb126cbf436cd6a4077a5b5c313
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
From 154dfb69cffd35f4bbbc5a82d823579119491dcd Mon Sep 17 00:00:00 2001
From: Marcin Wojtas <mw@semihalf.com>
Date: Thu, 18 Jan 2018 13:31:41 +0100
Subject: [PATCH 24/46] device property: Allow iterating over available child
 fwnodes
 
Implement a new helper function fwnode_get_next_available_child_node(),
which enables obtaining next enabled child fwnode, which
works on a similar basis to OF's of_get_next_available_child().
 
This commit also introduces a macro, thanks to which it is
possible to iterate over the available fwnodes, using the
new function described above.
 
Signed-off-by: Marcin Wojtas <mw@semihalf.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit 3395de96ae5998692bd86024d0d5e4dd55cd6cc3)
Signed-off-by: Marcin Wojtas <mw@semihalf.com>
---
 drivers/base/property.c  | 26 ++++++++++++++++++++++++++
 include/linux/property.h |  6 ++++++
 2 files changed, 32 insertions(+)
 
diff --git a/drivers/base/property.c b/drivers/base/property.c
index 3a20e2c..75aec5b 100644
--- a/drivers/base/property.c
+++ b/drivers/base/property.c
@@ -998,6 +998,32 @@ fwnode_get_next_child_node(const struct fwnode_handle *fwnode,
 EXPORT_SYMBOL_GPL(fwnode_get_next_child_node);
 
 /**
+ * fwnode_get_next_available_child_node - Return the next
+ * available child node handle for a node
+ * @fwnode: Firmware node to find the next child node for.
+ * @child: Handle to one of the node's child nodes or a %NULL handle.
+ */
+struct fwnode_handle *
+fwnode_get_next_available_child_node(const struct fwnode_handle *fwnode,
+                     struct fwnode_handle *child)
+{
+    struct fwnode_handle *next_child = child;
+
+    if (!fwnode)
+        return NULL;
+
+    do {
+        next_child = fwnode_get_next_child_node(fwnode, next_child);
+
+        if (!next_child || fwnode_device_is_available(next_child))
+            break;
+    } while (next_child);
+
+    return next_child;
+}
+EXPORT_SYMBOL_GPL(fwnode_get_next_available_child_node);
+
+/**
  * device_get_next_child_node - Return the next child node handle for a device
  * @dev: Device to find the next child node for.
  * @child: Handle to one of the device's child nodes or a null handle.
diff --git a/include/linux/property.h b/include/linux/property.h
index cd70998..f8ba672 100644
--- a/include/linux/property.h
+++ b/include/linux/property.h
@@ -83,11 +83,17 @@ struct fwnode_handle *fwnode_get_next_parent(
     struct fwnode_handle *fwnode);
 struct fwnode_handle *fwnode_get_next_child_node(
     const struct fwnode_handle *fwnode, struct fwnode_handle *child);
+struct fwnode_handle *fwnode_get_next_available_child_node(
+    const struct fwnode_handle *fwnode, struct fwnode_handle *child);
 
 #define fwnode_for_each_child_node(fwnode, child)            \
     for (child = fwnode_get_next_child_node(fwnode, NULL); child;    \
          child = fwnode_get_next_child_node(fwnode, child))
 
+#define fwnode_for_each_available_child_node(fwnode, child)               \
+    for (child = fwnode_get_next_available_child_node(fwnode, NULL); child;\
+         child = fwnode_get_next_available_child_node(fwnode, child))
+
 struct fwnode_handle *device_get_next_child_node(
     struct device *dev, struct fwnode_handle *child);
 
-- 
2.7.4