Pull fsys_gettimeofday into release branch
[pandora-kernel.git] / drivers / of / base.c
index 9377f3b..80c9dec 100644 (file)
@@ -137,6 +137,31 @@ struct device_node *of_get_parent(const struct device_node *node)
 }
 EXPORT_SYMBOL(of_get_parent);
 
+/**
+ *     of_get_next_parent - Iterate to a node's parent
+ *     @node:  Node to get parent of
+ *
+ *     This is like of_get_parent() except that it drops the
+ *     refcount on the passed node, making it suitable for iterating
+ *     through a node's parents.
+ *
+ *     Returns a node pointer with refcount incremented, use
+ *     of_node_put() on it when done.
+ */
+struct device_node *of_get_next_parent(struct device_node *node)
+{
+       struct device_node *parent;
+
+       if (!node)
+               return NULL;
+
+       read_lock(&devtree_lock);
+       parent = of_node_get(node->parent);
+       of_node_put(node);
+       read_unlock(&devtree_lock);
+       return parent;
+}
+
 /**
  *     of_get_next_child - Iterate a node childs
  *     @node:  parent node
@@ -273,3 +298,61 @@ struct device_node *of_find_compatible_node(struct device_node *from,
        return np;
 }
 EXPORT_SYMBOL(of_find_compatible_node);
+
+/**
+ * of_match_node - Tell if an device_node has a matching of_match structure
+ *     @matches:       array of of device match structures to search in
+ *     @node:          the of device structure to match against
+ *
+ *     Low level utility function used by device matching.
+ */
+const struct of_device_id *of_match_node(const struct of_device_id *matches,
+                                        const struct device_node *node)
+{
+       while (matches->name[0] || matches->type[0] || matches->compatible[0]) {
+               int match = 1;
+               if (matches->name[0])
+                       match &= node->name
+                               && !strcmp(matches->name, node->name);
+               if (matches->type[0])
+                       match &= node->type
+                               && !strcmp(matches->type, node->type);
+               if (matches->compatible[0])
+                       match &= of_device_is_compatible(node,
+                                               matches->compatible);
+               if (match)
+                       return matches;
+               matches++;
+       }
+       return NULL;
+}
+EXPORT_SYMBOL(of_match_node);
+
+/**
+ *     of_find_matching_node - 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. of_node_put() will be called on it
+ *     @matches:       array of of device match structures to search in
+ *
+ *     Returns a node pointer with refcount incremented, use
+ *     of_node_put() on it when done.
+ */
+struct device_node *of_find_matching_node(struct device_node *from,
+                                         const struct of_device_id *matches)
+{
+       struct device_node *np;
+
+       read_lock(&devtree_lock);
+       np = from ? from->allnext : allnodes;
+       for (; np; np = np->allnext) {
+               if (of_match_node(matches, np) && of_node_get(np))
+                       break;
+       }
+       of_node_put(from);
+       read_unlock(&devtree_lock);
+       return np;
+}
+EXPORT_SYMBOL(of_find_matching_node);