Documentation/admin-guide/cgroup-v2.rst: document why inactive_X + active_X may not...
[linux-2.6-microblaze.git] / lib / vsprintf.c
index e78017a..dee8fc4 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/build_bug.h>
 #include <linux/clk.h>
 #include <linux/clk-provider.h>
+#include <linux/errname.h>
 #include <linux/module.h>      /* for KSYM_SYMBOL_LEN */
 #include <linux/types.h>
 #include <linux/string.h>
@@ -38,6 +39,7 @@
 #include <net/addrconf.h>
 #include <linux/siphash.h>
 #include <linux/compiler.h>
+#include <linux/property.h>
 #ifdef CONFIG_BLOCK
 #include <linux/blkdev.h>
 #endif
@@ -613,6 +615,25 @@ static char *string_nocheck(char *buf, char *end, const char *s,
        return widen_string(buf, len, end, spec);
 }
 
+static char *err_ptr(char *buf, char *end, void *ptr,
+                    struct printf_spec spec)
+{
+       int err = PTR_ERR(ptr);
+       const char *sym = errname(err);
+
+       if (sym)
+               return string_nocheck(buf, end, sym, spec);
+
+       /*
+        * Somebody passed ERR_PTR(-1234) or some other non-existing
+        * Efoo - or perhaps CONFIG_SYMBOLIC_ERRNAME=n. Fall back to
+        * printing it as its decimal representation.
+        */
+       spec.flags |= SIGN;
+       spec.base = 10;
+       return number(buf, end, err, spec);
+}
+
 /* Be careful: error messages must fit into the given buffer. */
 static char *error_string(char *buf, char *end, const char *s,
                          struct printf_spec spec)
@@ -918,7 +939,7 @@ char *symbol_string(char *buf, char *end, void *ptr,
 #ifdef CONFIG_KALLSYMS
        if (*fmt == 'B')
                sprint_backtrace(sym, value);
-       else if (*fmt != 'f' && *fmt != 's')
+       else if (*fmt != 's')
                sprint_symbol(sym, value);
        else
                sprint_symbol_no_offset(sym, value);
@@ -1872,32 +1893,25 @@ char *flags_string(char *buf, char *end, void *flags_ptr,
        return format_flags(buf, end, flags, names);
 }
 
-static const char *device_node_name_for_depth(const struct device_node *np, int depth)
-{
-       for ( ; np && depth; depth--)
-               np = np->parent;
-
-       return kbasename(np->full_name);
-}
-
 static noinline_for_stack
-char *device_node_gen_full_name(const struct device_node *np, char *buf, char *end)
+char *fwnode_full_name_string(struct fwnode_handle *fwnode, char *buf,
+                             char *end)
 {
        int depth;
-       const struct device_node *parent = np->parent;
 
-       /* special case for root node */
-       if (!parent)
-               return string_nocheck(buf, end, "/", default_str_spec);
+       /* Loop starting from the root node to the current node. */
+       for (depth = fwnode_count_parents(fwnode); depth >= 0; depth--) {
+               struct fwnode_handle *__fwnode =
+                       fwnode_get_nth_parent(fwnode, depth);
 
-       for (depth = 0; parent->parent; depth++)
-               parent = parent->parent;
-
-       for ( ; depth >= 0; depth--) {
-               buf = string_nocheck(buf, end, "/", default_str_spec);
-               buf = string(buf, end, device_node_name_for_depth(np, depth),
+               buf = string(buf, end, fwnode_get_name_prefix(__fwnode),
+                            default_str_spec);
+               buf = string(buf, end, fwnode_get_name(__fwnode),
                             default_str_spec);
+
+               fwnode_handle_put(__fwnode);
        }
+
        return buf;
 }
 
@@ -1921,6 +1935,9 @@ char *device_node_string(char *buf, char *end, struct device_node *dn,
        struct printf_spec str_spec = spec;
        str_spec.field_width = -1;
 
+       if (fmt[0] != 'F')
+               return error_string(buf, end, "(%pO?)", spec);
+
        if (!IS_ENABLED(CONFIG_OF))
                return error_string(buf, end, "(%pOF?)", spec);
 
@@ -1942,10 +1959,11 @@ char *device_node_string(char *buf, char *end, struct device_node *dn,
 
                switch (*fmt) {
                case 'f':       /* full_name */
-                       buf = device_node_gen_full_name(dn, buf, end);
+                       buf = fwnode_full_name_string(of_fwnode_handle(dn), buf,
+                                                     end);
                        break;
                case 'n':       /* name */
-                       p = kbasename(of_node_full_name(dn));
+                       p = fwnode_get_name(of_fwnode_handle(dn));
                        precision = str_spec.precision;
                        str_spec.precision = strchrnul(p, '@') - p;
                        buf = string(buf, end, p, str_spec);
@@ -1955,7 +1973,7 @@ char *device_node_string(char *buf, char *end, struct device_node *dn,
                        buf = number(buf, end, (unsigned int)dn->phandle, num_spec);
                        break;
                case 'P':       /* path-spec */
-                       p = kbasename(of_node_full_name(dn));
+                       p = fwnode_get_name(of_fwnode_handle(dn));
                        if (!p[1])
                                p = "/";
                        buf = string(buf, end, p, str_spec);
@@ -1993,15 +2011,34 @@ char *device_node_string(char *buf, char *end, struct device_node *dn,
        return widen_string(buf, buf - buf_start, end, spec);
 }
 
-static char *kobject_string(char *buf, char *end, void *ptr,
-                           struct printf_spec spec, const char *fmt)
+static noinline_for_stack
+char *fwnode_string(char *buf, char *end, struct fwnode_handle *fwnode,
+                   struct printf_spec spec, const char *fmt)
 {
-       switch (fmt[1]) {
-       case 'F':
-               return device_node_string(buf, end, ptr, spec, fmt + 1);
+       struct printf_spec str_spec = spec;
+       char *buf_start = buf;
+
+       str_spec.field_width = -1;
+
+       if (*fmt != 'w')
+               return error_string(buf, end, "(%pf?)", spec);
+
+       if (check_pointer(&buf, end, fwnode, spec))
+               return buf;
+
+       fmt++;
+
+       switch (*fmt) {
+       case 'P':       /* name */
+               buf = string(buf, end, fwnode_get_name(fwnode), str_spec);
+               break;
+       case 'f':       /* full_name */
+       default:
+               buf = fwnode_full_name_string(fwnode, buf, end);
+               break;
        }
 
-       return error_string(buf, end, "(%pO?)", spec);
+       return widen_string(buf, buf - buf_start, end, spec);
 }
 
 /*
@@ -2016,9 +2053,9 @@ static char *kobject_string(char *buf, char *end, void *ptr,
  *
  * - 'S' For symbolic direct pointers (or function descriptors) with offset
  * - 's' For symbolic direct pointers (or function descriptors) without offset
- * - 'F' Same as 'S'
- * - 'f' Same as 's'
- * - '[FfSs]R' as above with __builtin_extract_return_addr() translation
+ * - '[Ss]R' as above with __builtin_extract_return_addr() translation
+ * - '[Ff]' %pf and %pF were obsoleted and later removed in favor of
+ *         %ps and %pS. Be careful when re-using these specifiers.
  * - 'B' For backtraced symbolic direct pointers with offset
  * - 'R' For decoded struct resource, e.g., [mem 0x0-0x1f 64bit pref]
  * - 'r' For raw struct resource, e.g., [mem 0x0-0x1f flags 0x201]
@@ -2108,6 +2145,10 @@ static char *kobject_string(char *buf, char *end, void *ptr,
  *                  F device node flags
  *                  c major compatible string
  *                  C full compatible string
+ * - 'fw[fP]'  For a firmware node (struct fwnode_handle) pointer
+ *             Without an option prints the full name of the node
+ *             f full name
+ *             P node name, including a possible unit address
  * - 'x' For printing the address. Equivalent to "%lx".
  *
  * ** When making changes please also update:
@@ -2121,8 +2162,6 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr,
              struct printf_spec spec)
 {
        switch (*fmt) {
-       case 'F':
-       case 'f':
        case 'S':
        case 's':
                ptr = dereference_symbol_descriptor(ptr);
@@ -2184,9 +2223,16 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr,
        case 'G':
                return flags_string(buf, end, ptr, spec, fmt);
        case 'O':
-               return kobject_string(buf, end, ptr, spec, fmt);
+               return device_node_string(buf, end, ptr, spec, fmt + 1);
+       case 'f':
+               return fwnode_string(buf, end, ptr, spec, fmt + 1);
        case 'x':
                return pointer_string(buf, end, ptr, spec);
+       case 'e':
+               /* %pe with a non-ERR_PTR gets treated as plain %p */
+               if (!IS_ERR(ptr))
+                       break;
+               return err_ptr(buf, end, ptr, spec);
        }
 
        /* default is to _not_ leak addresses, hash before printing */
@@ -2819,10 +2865,9 @@ int vbin_printf(u32 *bin_buf, size_t size, const char *fmt, va_list args)
                        /* Dereference of functions is still OK */
                        case 'S':
                        case 's':
-                       case 'F':
-                       case 'f':
                        case 'x':
                        case 'K':
+                       case 'e':
                                save_arg(void *);
                                break;
                        default:
@@ -2999,6 +3044,7 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf)
                        case 'f':
                        case 'x':
                        case 'K':
+                       case 'e':
                                process = true;
                                break;
                        default: