]> git.karo-electronics.de Git - linux-beck.git/commitdiff
device property: Add function to search for named child of device
authorAdam Thomson <Adam.Thomson.Opensource@diasemi.com>
Tue, 21 Jun 2016 17:50:20 +0000 (18:50 +0100)
committerMark Brown <broonie@kernel.org>
Sun, 26 Jun 2016 11:39:03 +0000 (12:39 +0100)
For device nodes in both DT and ACPI, it possible to have named
child nodes which contain properties (an existing example being
gpio-leds). This adds a function to find a named child node for
a device which can be used by drivers for property retrieval.

For DT data node name matching, of_node_cmp() and similar functions
are made available outside of CONFIG_OF block so the new function
can reference these for DT and non-DT builds.

For ACPI data node name matching, a helper function is also added
which returns false if CONFIG_ACPI is not set, otherwise it
performs a string comparison on the data node name. This avoids
using the acpi_data_node struct for non CONFIG_ACPI builds,
which would otherwise cause a build failure.

Signed-off-by: Adam Thomson <Adam.Thomson.Opensource@diasemi.com>
Acked-by: Sathyanarayana Nujella <sathyanarayana.nujella@intel.com>
Acked-by: Rob Herring <robh@kernel.org>
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
drivers/base/property.c
include/acpi/acpi_bus.h
include/linux/acpi.h
include/linux/of.h
include/linux/property.h

index f38c21de29b735982480f8042dce35e8d2ed2a8a..43a36d68c3fded1602c9e8ce97358264c9f33c8a 100644 (file)
@@ -887,6 +887,34 @@ struct fwnode_handle *device_get_next_child_node(struct device *dev,
 }
 EXPORT_SYMBOL_GPL(device_get_next_child_node);
 
+/**
+ * device_get_named_child_node - Return first matching named child node handle
+ * @dev: Device to find the named child node for.
+ * @childname: String to match child node name against.
+ */
+struct fwnode_handle *device_get_named_child_node(struct device *dev,
+                                                 const char *childname)
+{
+       struct fwnode_handle *child;
+
+       /*
+        * Find first matching named child node of this device.
+        * For ACPI this will be a data only sub-node.
+        */
+       device_for_each_child_node(dev, child) {
+               if (is_of_node(child)) {
+                       if (!of_node_cmp(to_of_node(child)->name, childname))
+                               return child;
+               } else if (is_acpi_data_node(child)) {
+                       if (acpi_data_node_match(child, childname))
+                               return child;
+               }
+       }
+
+       return NULL;
+}
+EXPORT_SYMBOL_GPL(device_get_named_child_node);
+
 /**
  * fwnode_handle_put - Drop reference to a device node
  * @fwnode: Pointer to the device node to drop the reference to.
index 788c6c35291a42c448296876ab6c32bff25a5200..c1a524de67c5b8ab8f1c63ea77365dec085fcd91 100644 (file)
@@ -420,6 +420,13 @@ static inline struct acpi_data_node *to_acpi_data_node(struct fwnode_handle *fwn
                container_of(fwnode, struct acpi_data_node, fwnode) : NULL;
 }
 
+static inline bool acpi_data_node_match(struct fwnode_handle *fwnode,
+                                       const char *name)
+{
+       return is_acpi_data_node(fwnode) ?
+               (!strcmp(to_acpi_data_node(fwnode)->name, name)) : false;
+}
+
 static inline struct fwnode_handle *acpi_fwnode_handle(struct acpi_device *adev)
 {
        return &adev->fwnode;
index 288fac5294f5e26aacfe97ac772d5f0247aa1dd2..03039c472e951a718075931f9b24916610aed7e7 100644 (file)
@@ -568,6 +568,12 @@ static inline struct acpi_data_node *to_acpi_data_node(struct fwnode_handle *fwn
        return NULL;
 }
 
+static inline bool acpi_data_node_match(struct fwnode_handle *fwnode,
+                                       const char *name)
+{
+       return false;
+}
+
 static inline struct fwnode_handle *acpi_fwnode_handle(struct acpi_device *adev)
 {
        return NULL;
index c7292e8ea080118b9d09542a875b95ebbddc31b3..8455741e313e75cff84b658d9896c54bf23f3571 100644 (file)
@@ -238,13 +238,6 @@ static inline unsigned long of_read_ulong(const __be32 *cell, int size)
 #define OF_ROOT_NODE_SIZE_CELLS_DEFAULT 1
 #endif
 
-/* Default string compare functions, Allow arch asm/prom.h to override */
-#if !defined(of_compat_cmp)
-#define of_compat_cmp(s1, s2, l)       strcasecmp((s1), (s2))
-#define of_prop_cmp(s1, s2)            strcmp((s1), (s2))
-#define of_node_cmp(s1, s2)            strcasecmp((s1), (s2))
-#endif
-
 #define OF_IS_DYNAMIC(x) test_bit(OF_DYNAMIC, &x->_flags)
 #define OF_MARK_DYNAMIC(x) set_bit(OF_DYNAMIC, &x->_flags)
 
@@ -726,6 +719,13 @@ static inline void of_property_clear_flag(struct property *p, unsigned long flag
 #define of_match_node(_matches, _node) NULL
 #endif /* CONFIG_OF */
 
+/* Default string compare functions, Allow arch asm/prom.h to override */
+#if !defined(of_compat_cmp)
+#define of_compat_cmp(s1, s2, l)       strcasecmp((s1), (s2))
+#define of_prop_cmp(s1, s2)            strcmp((s1), (s2))
+#define of_node_cmp(s1, s2)            strcasecmp((s1), (s2))
+#endif
+
 #if defined(CONFIG_OF) && defined(CONFIG_NUMA)
 extern int of_node_to_nid(struct device_node *np);
 #else
index ecab11e407942fcfea3b92d10dc938dd365460cd..3a2f9ae25c86c43827cdcd0c4602cd5e281a4cf9 100644 (file)
@@ -77,6 +77,9 @@ struct fwnode_handle *device_get_next_child_node(struct device *dev,
        for (child = device_get_next_child_node(dev, NULL); child;      \
             child = device_get_next_child_node(dev, child))
 
+struct fwnode_handle *device_get_named_child_node(struct device *dev,
+                                                 const char *childname);
+
 void fwnode_handle_put(struct fwnode_handle *fwnode);
 
 unsigned int device_get_child_node_count(struct device *dev);