]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - drivers/of/base.c
Merge tag 'mips_fixes_4.20_1' of git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux
[linux.git] / drivers / of / base.c
index 90bf7d9fa17b9adee52135b4ebe441ab4f2c0009..13ebb16be64e7bfe16669b0a9701f9e424914af3 100644 (file)
@@ -67,6 +67,7 @@ bool of_node_name_eq(const struct device_node *np, const char *name)
 
        return (strlen(name) == len) && (strncmp(node_name, name, len) == 0);
 }
+EXPORT_SYMBOL(of_node_name_eq);
 
 bool of_node_name_prefix(const struct device_node *np, const char *prefix)
 {
@@ -75,6 +76,7 @@ bool of_node_name_prefix(const struct device_node *np, const char *prefix)
 
        return strncmp(kbasename(np->full_name), prefix, strlen(prefix)) == 0;
 }
+EXPORT_SYMBOL(of_node_name_prefix);
 
 int of_n_addr_cells(struct device_node *np)
 {
@@ -330,6 +332,8 @@ static bool __of_find_n_match_cpu_property(struct device_node *cpun,
 
        ac = of_n_addr_cells(cpun);
        cell = of_get_property(cpun, prop_name, &prop_len);
+       if (!cell && !ac && arch_match_cpu_phys_id(cpu, 0))
+               return true;
        if (!cell || !ac)
                return false;
        prop_len /= sizeof(*cell) * ac;
@@ -390,7 +394,7 @@ struct device_node *of_get_cpu_node(int cpu, unsigned int *thread)
 {
        struct device_node *cpun;
 
-       for_each_node_by_type(cpun, "cpu") {
+       for_each_of_cpu_node(cpun) {
                if (arch_find_n_match_cpu_physical_id(cpun, cpu, thread))
                        return cpun;
        }
@@ -744,6 +748,45 @@ struct device_node *of_get_next_available_child(const struct device_node *node,
 }
 EXPORT_SYMBOL(of_get_next_available_child);
 
+/**
+ *     of_get_next_cpu_node - Iterate on cpu nodes
+ *     @prev:  previous child of the /cpus node, or NULL to get first
+ *
+ *     Returns a cpu node pointer with refcount incremented, use of_node_put()
+ *     on it when done. Returns NULL when prev is the last child. Decrements
+ *     the refcount of prev.
+ */
+struct device_node *of_get_next_cpu_node(struct device_node *prev)
+{
+       struct device_node *next = NULL;
+       unsigned long flags;
+       struct device_node *node;
+
+       if (!prev)
+               node = of_find_node_by_path("/cpus");
+
+       raw_spin_lock_irqsave(&devtree_lock, flags);
+       if (prev)
+               next = prev->sibling;
+       else if (node) {
+               next = node->child;
+               of_node_put(node);
+       }
+       for (; next; next = next->sibling) {
+               if (!(of_node_name_eq(next, "cpu") ||
+                     (next->type && !of_node_cmp(next->type, "cpu"))))
+                       continue;
+               if (!__of_device_is_available(next))
+                       continue;
+               if (of_node_get(next))
+                       break;
+       }
+       of_node_put(prev);
+       raw_spin_unlock_irqrestore(&devtree_lock, flags);
+       return next;
+}
+EXPORT_SYMBOL(of_get_next_cpu_node);
+
 /**
  * of_get_compatible_child - Find compatible child node
  * @parent:    parent node
@@ -2013,7 +2056,7 @@ struct device_node *of_find_next_cache_node(const struct device_node *np)
        /* OF on pmac has nodes instead of properties named "l2-cache"
         * beneath CPU nodes.
         */
-       if (!strcmp(np->type, "cpu"))
+       if (IS_ENABLED(CONFIG_PPC_PMAC) && !strcmp(np->type, "cpu"))
                for_each_child_of_node(np, child)
                        if (!strcmp(child->type, "cache"))
                                return child;