ath10k: miscellaneous checkpatch fixes
[cascardo/linux.git] / drivers / of / base.c
index b986480..d8574ad 100644 (file)
@@ -17,6 +17,7 @@
  *      as published by the Free Software Foundation; either version
  *      2 of the License, or (at your option) any later version.
  */
+#include <linux/console.h>
 #include <linux/ctype.h>
 #include <linux/cpu.h>
 #include <linux/module.h>
@@ -35,15 +36,17 @@ struct device_node *of_allnodes;
 EXPORT_SYMBOL(of_allnodes);
 struct device_node *of_chosen;
 struct device_node *of_aliases;
-static struct device_node *of_stdout;
+struct device_node *of_stdout;
 
-static struct kset *of_kset;
+struct kset *of_kset;
 
 /*
- * Used to protect the of_aliases; but also overloaded to hold off addition of
- * nodes to sysfs
+ * Used to protect the of_aliases, to hold off addition of nodes to sysfs.
+ * This mutex must be held whenever modifications are being made to the
+ * device tree. The of_{attach,detach}_node() and
+ * of_{add,remove,update}_property() helpers make sure this happens.
  */
-DEFINE_MUTEX(of_aliases_mutex);
+DEFINE_MUTEX(of_mutex);
 
 /* use when traversing tree through the allnext, child, sibling,
  * or parent members of struct device_node.
@@ -89,79 +92,7 @@ int __weak of_node_to_nid(struct device_node *np)
 }
 #endif
 
-#if defined(CONFIG_OF_DYNAMIC)
-/**
- *     of_node_get - Increment refcount of a node
- *     @node:  Node to inc refcount, NULL is supported to
- *             simplify writing of callers
- *
- *     Returns node.
- */
-struct device_node *of_node_get(struct device_node *node)
-{
-       if (node)
-               kobject_get(&node->kobj);
-       return node;
-}
-EXPORT_SYMBOL(of_node_get);
-
-static inline struct device_node *kobj_to_device_node(struct kobject *kobj)
-{
-       return container_of(kobj, struct device_node, kobj);
-}
-
-/**
- *     of_node_release - release a dynamically allocated node
- *     @kref:  kref element of the node to be released
- *
- *     In of_node_put() this function is passed to kref_put()
- *     as the destructor.
- */
-static void of_node_release(struct kobject *kobj)
-{
-       struct device_node *node = kobj_to_device_node(kobj);
-       struct property *prop = node->properties;
-
-       /* We should never be releasing nodes that haven't been detached. */
-       if (!of_node_check_flag(node, OF_DETACHED)) {
-               pr_err("ERROR: Bad of_node_put() on %s\n", node->full_name);
-               dump_stack();
-               return;
-       }
-
-       if (!of_node_check_flag(node, OF_DYNAMIC))
-               return;
-
-       while (prop) {
-               struct property *next = prop->next;
-               kfree(prop->name);
-               kfree(prop->value);
-               kfree(prop);
-               prop = next;
-
-               if (!prop) {
-                       prop = node->deadprops;
-                       node->deadprops = NULL;
-               }
-       }
-       kfree(node->full_name);
-       kfree(node->data);
-       kfree(node);
-}
-
-/**
- *     of_node_put - Decrement refcount of a node
- *     @node:  Node to dec refcount, NULL is supported to
- *             simplify writing of callers
- *
- */
-void of_node_put(struct device_node *node)
-{
-       if (node)
-               kobject_put(&node->kobj);
-}
-EXPORT_SYMBOL(of_node_put);
-#else
+#ifndef CONFIG_OF_DYNAMIC
 static void of_node_release(struct kobject *kobj)
 {
        /* Without CONFIG_OF_DYNAMIC, no nodes gets freed */
@@ -200,13 +131,16 @@ static const char *safe_name(struct kobject *kobj, const char *orig_name)
        return name;
 }
 
-static int __of_add_property_sysfs(struct device_node *np, struct property *pp)
+int __of_add_property_sysfs(struct device_node *np, struct property *pp)
 {
        int rc;
 
        /* Important: Don't leak passwords */
        bool secure = strncmp(pp->name, "security-", 9) == 0;
 
+       if (!of_kset || !of_node_is_attached(np))
+               return 0;
+
        sysfs_bin_attr_init(&pp->attr);
        pp->attr.attr.name = safe_name(&np->kobj, pp->name);
        pp->attr.attr.mode = secure ? S_IRUSR : S_IRUGO;
@@ -218,12 +152,15 @@ static int __of_add_property_sysfs(struct device_node *np, struct property *pp)
        return rc;
 }
 
-static int __of_node_add(struct device_node *np)
+int __of_attach_node_sysfs(struct device_node *np)
 {
        const char *name;
        struct property *pp;
        int rc;
 
+       if (!of_kset)
+               return 0;
+
        np->kobj.kset = of_kset;
        if (!np->parent) {
                /* Nodes without parents are new top level trees */
@@ -245,59 +182,20 @@ static int __of_node_add(struct device_node *np)
        return 0;
 }
 
-int of_node_add(struct device_node *np)
-{
-       int rc = 0;
-
-       BUG_ON(!of_node_is_initialized(np));
-
-       /*
-        * Grab the mutex here so that in a race condition between of_init() and
-        * of_node_add(), node addition will still be consistent.
-        */
-       mutex_lock(&of_aliases_mutex);
-       if (of_kset)
-               rc = __of_node_add(np);
-       else
-               /* This scenario may be perfectly valid, but report it anyway */
-               pr_info("of_node_add(%s) before of_init()\n", np->full_name);
-       mutex_unlock(&of_aliases_mutex);
-       return rc;
-}
-
-#if defined(CONFIG_OF_DYNAMIC)
-static void of_node_remove(struct device_node *np)
-{
-       struct property *pp;
-
-       BUG_ON(!of_node_is_initialized(np));
-
-       /* only remove properties if on sysfs */
-       if (of_node_is_attached(np)) {
-               for_each_property_of_node(np, pp)
-                       sysfs_remove_bin_file(&np->kobj, &pp->attr);
-               kobject_del(&np->kobj);
-       }
-
-       /* finally remove the kobj_init ref */
-       of_node_put(np);
-}
-#endif
-
 static int __init of_init(void)
 {
        struct device_node *np;
 
        /* Create the kset, and register existing nodes */
-       mutex_lock(&of_aliases_mutex);
+       mutex_lock(&of_mutex);
        of_kset = kset_create_and_add("devicetree", NULL, firmware_kobj);
        if (!of_kset) {
-               mutex_unlock(&of_aliases_mutex);
+               mutex_unlock(&of_mutex);
                return -ENOMEM;
        }
        for_each_of_allnodes(np)
-               __of_node_add(np);
-       mutex_unlock(&of_aliases_mutex);
+               __of_attach_node_sysfs(np);
+       mutex_unlock(&of_mutex);
 
        /* Symlink in /proc as required by userspace ABI */
        if (of_allnodes)
@@ -369,8 +267,8 @@ EXPORT_SYMBOL(of_find_all_nodes);
  * Find a property with a given name for a given node
  * and return the value.
  */
-static const void *__of_get_property(const struct device_node *np,
-                                    const char *name, int *lenp)
+const void *__of_get_property(const struct device_node *np,
+                             const char *name, int *lenp)
 {
        struct property *pp = __of_find_property(np, name, lenp);
 
@@ -1748,32 +1646,10 @@ int of_count_phandle_with_args(const struct device_node *np, const char *list_na
 }
 EXPORT_SYMBOL(of_count_phandle_with_args);
 
-#if defined(CONFIG_OF_DYNAMIC)
-static int of_property_notify(int action, struct device_node *np,
-                             struct property *prop)
-{
-       struct of_prop_reconfig pr;
-
-       /* only call notifiers if the node is attached */
-       if (!of_node_is_attached(np))
-               return 0;
-
-       pr.dn = np;
-       pr.prop = prop;
-       return of_reconfig_notify(action, &pr);
-}
-#else
-static int of_property_notify(int action, struct device_node *np,
-                             struct property *prop)
-{
-       return 0;
-}
-#endif
-
 /**
  * __of_add_property - Add a property to a node without lock operations
  */
-static int __of_add_property(struct device_node *np, struct property *prop)
+int __of_add_property(struct device_node *np, struct property *prop)
 {
        struct property **next;
 
@@ -1799,22 +1675,49 @@ int of_add_property(struct device_node *np, struct property *prop)
        unsigned long flags;
        int rc;
 
-       rc = of_property_notify(OF_RECONFIG_ADD_PROPERTY, np, prop);
-       if (rc)
-               return rc;
+       mutex_lock(&of_mutex);
 
        raw_spin_lock_irqsave(&devtree_lock, flags);
        rc = __of_add_property(np, prop);
        raw_spin_unlock_irqrestore(&devtree_lock, flags);
-       if (rc)
-               return rc;
 
-       if (of_node_is_attached(np))
+       if (!rc)
                __of_add_property_sysfs(np, prop);
 
+       mutex_unlock(&of_mutex);
+
+       if (!rc)
+               of_property_notify(OF_RECONFIG_ADD_PROPERTY, np, prop, NULL);
+
        return rc;
 }
 
+int __of_remove_property(struct device_node *np, struct property *prop)
+{
+       struct property **next;
+
+       for (next = &np->properties; *next; next = &(*next)->next) {
+               if (*next == prop)
+                       break;
+       }
+       if (*next == NULL)
+               return -ENODEV;
+
+       /* found the node */
+       *next = prop->next;
+       prop->next = np->deadprops;
+       np->deadprops = prop;
+
+       return 0;
+}
+
+void __of_remove_property_sysfs(struct device_node *np, struct property *prop)
+{
+       /* at early boot, bail here and defer setup to of_init() */
+       if (of_kset && of_node_is_attached(np))
+               sysfs_remove_bin_file(&np->kobj, &prop->attr);
+}
+
 /**
  * of_remove_property - Remove a property from a node.
  *
@@ -1825,211 +1728,98 @@ int of_add_property(struct device_node *np, struct property *prop)
  */
 int of_remove_property(struct device_node *np, struct property *prop)
 {
-       struct property **next;
        unsigned long flags;
-       int found = 0;
        int rc;
 
-       rc = of_property_notify(OF_RECONFIG_REMOVE_PROPERTY, np, prop);
-       if (rc)
-               return rc;
+       mutex_lock(&of_mutex);
 
        raw_spin_lock_irqsave(&devtree_lock, flags);
-       next = &np->properties;
-       while (*next) {
-               if (*next == prop) {
-                       /* found the node */
-                       *next = prop->next;
-                       prop->next = np->deadprops;
-                       np->deadprops = prop;
-                       found = 1;
-                       break;
-               }
-               next = &(*next)->next;
-       }
+       rc = __of_remove_property(np, prop);
        raw_spin_unlock_irqrestore(&devtree_lock, flags);
 
-       if (!found)
-               return -ENODEV;
+       if (!rc)
+               __of_remove_property_sysfs(np, prop);
 
-       /* at early boot, bail hear and defer setup to of_init() */
-       if (!of_kset)
-               return 0;
+       mutex_unlock(&of_mutex);
 
-       sysfs_remove_bin_file(&np->kobj, &prop->attr);
+       if (!rc)
+               of_property_notify(OF_RECONFIG_REMOVE_PROPERTY, np, prop, NULL);
 
-       return 0;
+       return rc;
 }
 
-/*
- * of_update_property - Update a property in a node, if the property does
- * not exist, add it.
- *
- * Note that we don't actually remove it, since we have given out
- * who-knows-how-many pointers to the data using get-property.
- * Instead we just move the property to the "dead properties" list,
- * and add the new property to the property list
- */
-int of_update_property(struct device_node *np, struct property *newprop)
+int __of_update_property(struct device_node *np, struct property *newprop,
+               struct property **oldpropp)
 {
        struct property **next, *oldprop;
-       unsigned long flags;
-       int rc;
-
-       rc = of_property_notify(OF_RECONFIG_UPDATE_PROPERTY, np, newprop);
-       if (rc)
-               return rc;
 
-       if (!newprop->name)
-               return -EINVAL;
+       for (next = &np->properties; *next; next = &(*next)->next) {
+               if (of_prop_cmp((*next)->name, newprop->name) == 0)
+                       break;
+       }
+       *oldpropp = oldprop = *next;
 
-       raw_spin_lock_irqsave(&devtree_lock, flags);
-       next = &np->properties;
-       oldprop = __of_find_property(np, newprop->name, NULL);
-       if (!oldprop) {
-               /* add the new node */
-               rc = __of_add_property(np, newprop);
-       } else while (*next) {
+       if (oldprop) {
                /* replace the node */
-               if (*next == oldprop) {
-                       newprop->next = oldprop->next;
-                       *next = newprop;
-                       oldprop->next = np->deadprops;
-                       np->deadprops = oldprop;
-                       break;
-               }
-               next = &(*next)->next;
+               newprop->next = oldprop->next;
+               *next = newprop;
+               oldprop->next = np->deadprops;
+               np->deadprops = oldprop;
+       } else {
+               /* new node */
+               newprop->next = NULL;
+               *next = newprop;
        }
-       raw_spin_unlock_irqrestore(&devtree_lock, flags);
-       if (rc)
-               return rc;
 
+       return 0;
+}
+
+void __of_update_property_sysfs(struct device_node *np, struct property *newprop,
+               struct property *oldprop)
+{
        /* At early boot, bail out and defer setup to of_init() */
        if (!of_kset)
-               return 0;
+               return;
 
-       /* Update the sysfs attribute */
        if (oldprop)
                sysfs_remove_bin_file(&np->kobj, &oldprop->attr);
        __of_add_property_sysfs(np, newprop);
-
-       return 0;
 }
 
-#if defined(CONFIG_OF_DYNAMIC)
 /*
- * Support for dynamic device trees.
+ * of_update_property - Update a property in a node, if the property does
+ * not exist, add it.
  *
- * On some platforms, the device tree can be manipulated at runtime.
- * The routines in this section support adding, removing and changing
- * device tree nodes.
- */
-
-static BLOCKING_NOTIFIER_HEAD(of_reconfig_chain);
-
-int of_reconfig_notifier_register(struct notifier_block *nb)
-{
-       return blocking_notifier_chain_register(&of_reconfig_chain, nb);
-}
-EXPORT_SYMBOL_GPL(of_reconfig_notifier_register);
-
-int of_reconfig_notifier_unregister(struct notifier_block *nb)
-{
-       return blocking_notifier_chain_unregister(&of_reconfig_chain, nb);
-}
-EXPORT_SYMBOL_GPL(of_reconfig_notifier_unregister);
-
-int of_reconfig_notify(unsigned long action, void *p)
-{
-       int rc;
-
-       rc = blocking_notifier_call_chain(&of_reconfig_chain, action, p);
-       return notifier_to_errno(rc);
-}
-
-/**
- * of_attach_node - Plug a device node into the tree and global list.
+ * Note that we don't actually remove it, since we have given out
+ * who-knows-how-many pointers to the data using get-property.
+ * Instead we just move the property to the "dead properties" list,
+ * and add the new property to the property list
  */
-int of_attach_node(struct device_node *np)
+int of_update_property(struct device_node *np, struct property *newprop)
 {
+       struct property *oldprop;
        unsigned long flags;
        int rc;
 
-       rc = of_reconfig_notify(OF_RECONFIG_ATTACH_NODE, np);
-       if (rc)
-               return rc;
-
-       raw_spin_lock_irqsave(&devtree_lock, flags);
-       np->sibling = np->parent->child;
-       np->allnext = np->parent->allnext;
-       np->parent->allnext = np;
-       np->parent->child = np;
-       of_node_clear_flag(np, OF_DETACHED);
-       raw_spin_unlock_irqrestore(&devtree_lock, flags);
-
-       of_node_add(np);
-       return 0;
-}
-
-/**
- * of_detach_node - "Unplug" a node from the device tree.
- *
- * The caller must hold a reference to the node.  The memory associated with
- * the node is not freed until its refcount goes to zero.
- */
-int of_detach_node(struct device_node *np)
-{
-       struct device_node *parent;
-       unsigned long flags;
-       int rc = 0;
+       if (!newprop->name)
+               return -EINVAL;
 
-       rc = of_reconfig_notify(OF_RECONFIG_DETACH_NODE, np);
-       if (rc)
-               return rc;
+       mutex_lock(&of_mutex);
 
        raw_spin_lock_irqsave(&devtree_lock, flags);
+       rc = __of_update_property(np, newprop, &oldprop);
+       raw_spin_unlock_irqrestore(&devtree_lock, flags);
 
-       if (of_node_check_flag(np, OF_DETACHED)) {
-               /* someone already detached it */
-               raw_spin_unlock_irqrestore(&devtree_lock, flags);
-               return rc;
-       }
-
-       parent = np->parent;
-       if (!parent) {
-               raw_spin_unlock_irqrestore(&devtree_lock, flags);
-               return rc;
-       }
+       if (!rc)
+               __of_update_property_sysfs(np, newprop, oldprop);
 
-       if (of_allnodes == np)
-               of_allnodes = np->allnext;
-       else {
-               struct device_node *prev;
-               for (prev = of_allnodes;
-                    prev->allnext != np;
-                    prev = prev->allnext)
-                       ;
-               prev->allnext = np->allnext;
-       }
+       mutex_unlock(&of_mutex);
 
-       if (parent->child == np)
-               parent->child = np->sibling;
-       else {
-               struct device_node *prevsib;
-               for (prevsib = np->parent->child;
-                    prevsib->sibling != np;
-                    prevsib = prevsib->sibling)
-                       ;
-               prevsib->sibling = np->sibling;
-       }
-
-       of_node_set_flag(np, OF_DETACHED);
-       raw_spin_unlock_irqrestore(&devtree_lock, flags);
+       if (!rc)
+               of_property_notify(OF_RECONFIG_UPDATE_PROPERTY, np, newprop, oldprop);
 
-       of_node_remove(np);
        return rc;
 }
-#endif /* defined(CONFIG_OF_DYNAMIC) */
 
 static void of_alias_add(struct alias_prop *ap, struct device_node *np,
                         int id, const char *stem, int stem_len)
@@ -2062,9 +1852,12 @@ void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align))
                of_chosen = of_find_node_by_path("/chosen@0");
 
        if (of_chosen) {
+               /* linux,stdout-path and /aliases/stdout are for legacy compatibility */
                const char *name = of_get_property(of_chosen, "stdout-path", NULL);
                if (!name)
                        name = of_get_property(of_chosen, "linux,stdout-path", NULL);
+               if (IS_ENABLED(CONFIG_PPC) && !name)
+                       name = of_get_property(of_aliases, "stdout", NULL);
                if (name)
                        of_stdout = of_find_node_by_path(name);
        }
@@ -2122,7 +1915,7 @@ int of_alias_get_id(struct device_node *np, const char *stem)
        struct alias_prop *app;
        int id = -ENODEV;
 
-       mutex_lock(&of_aliases_mutex);
+       mutex_lock(&of_mutex);
        list_for_each_entry(app, &aliases_lookup, link) {
                if (strcmp(app->stem, stem) != 0)
                        continue;
@@ -2132,7 +1925,7 @@ int of_alias_get_id(struct device_node *np, const char *stem)
                        break;
                }
        }
-       mutex_unlock(&of_aliases_mutex);
+       mutex_unlock(&of_mutex);
 
        return id;
 }
@@ -2180,20 +1973,22 @@ const char *of_prop_next_string(struct property *prop, const char *cur)
 EXPORT_SYMBOL_GPL(of_prop_next_string);
 
 /**
- * of_device_is_stdout_path - check if a device node matches the
- *                            linux,stdout-path property
- *
- * Check if this device node matches the linux,stdout-path property
- * in the chosen node. return true if yes, false otherwise.
+ * of_console_check() - Test and setup console for DT setup
+ * @dn - Pointer to device node
+ * @name - Name to use for preferred console without index. ex. "ttyS"
+ * @index - Index to use for preferred console.
+ *
+ * Check if the given device node matches the stdout-path property in the
+ * /chosen node. If it does then register it as the preferred console and return
+ * TRUE. Otherwise return FALSE.
  */
-int of_device_is_stdout_path(struct device_node *dn)
+bool of_console_check(struct device_node *dn, char *name, int index)
 {
-       if (!of_stdout)
+       if (!dn || dn != of_stdout || console_set_on_cmdline)
                return false;
-
-       return of_stdout == dn;
+       return add_preferred_console(name, index, NULL);
 }
-EXPORT_SYMBOL_GPL(of_device_is_stdout_path);
+EXPORT_SYMBOL_GPL(of_console_check);
 
 /**
  *     of_find_next_cache_node - Find a node's subsidiary cache