aboutsummaryrefslogtreecommitdiffstats
path: root/lib/vsprintf.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-07-07 13:37:54 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2017-07-07 13:37:54 -0400
commitdd6ec12f3bf83ca3c4e712a9f35960aec779f6f9 (patch)
tree8b6f9f187eb0ae621a64798270c420143c698484 /lib/vsprintf.c
parent21c19bc7ee256094aba74af8d91a824da4bc36af (diff)
parenta4485b545e2fad4d65732cb7c60089bf4246de5c (diff)
Merge tag 'devicetree-for-4.13' of git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux
Pull DeviceTree updates from Rob Herring: - vsprintf format specifier %pOF for device_node's. This will enable us to stop storing the full node names. Conversion of users will happen next cycle. - Update documentation to point to DT specification instead of ePAPR. - Split out graph and property functions to a separate file. - New of-graph functions for ALSA - Add vendor prefixes for RISC-V, Linksys, iWave Systems, Roofull, Itead, and BananaPi. - Improve dtx_diff utility filename printing. * tag 'devicetree-for-4.13' of git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux: (32 commits) of: document /sys/firmware/fdt dt-bindings: Add RISC-V vendor prefix vsprintf: Add %p extension "%pOF" for device tree of: find_node_by_full_name rewrite to compare each level of: use kbasename instead of open coding dt-bindings: thermal: add file extension to brcm,ns-thermal of: update ePAPR references to point to Devicetree Specification scripts/dtc: dtx_diff - Show real file names in diff header of: detect invalid phandle in overlay of: be consistent in form of file mode of: make __of_attach_node() static of: address.c header comment typo of: fdt.c header comment typo of: make of_fdt_is_compatible() static dt-bindings: display-timing.txt convert non-ascii characters to ascii Documentation: remove overlay-notes reference to non-existent file dt-bindings: usb: exynos-usb: Add missing required VDD properties dt-bindings: Add vendor prefix for Linksys MAINTAINERS: add device tree ABI documentation file of: Add vendor prefix for iWave Systems Technologies Pvt. Ltd ...
Diffstat (limited to 'lib/vsprintf.c')
-rw-r--r--lib/vsprintf.c136
1 files changed, 136 insertions, 0 deletions
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index 9f37d6208e99..86c3385b9eb3 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -31,6 +31,7 @@
31#include <linux/dcache.h> 31#include <linux/dcache.h>
32#include <linux/cred.h> 32#include <linux/cred.h>
33#include <linux/uuid.h> 33#include <linux/uuid.h>
34#include <linux/of.h>
34#include <net/addrconf.h> 35#include <net/addrconf.h>
35#ifdef CONFIG_BLOCK 36#ifdef CONFIG_BLOCK
36#include <linux/blkdev.h> 37#include <linux/blkdev.h>
@@ -1470,6 +1471,126 @@ char *flags_string(char *buf, char *end, void *flags_ptr, const char *fmt)
1470 return format_flags(buf, end, flags, names); 1471 return format_flags(buf, end, flags, names);
1471} 1472}
1472 1473
1474static const char *device_node_name_for_depth(const struct device_node *np, int depth)
1475{
1476 for ( ; np && depth; depth--)
1477 np = np->parent;
1478
1479 return kbasename(np->full_name);
1480}
1481
1482static noinline_for_stack
1483char *device_node_gen_full_name(const struct device_node *np, char *buf, char *end)
1484{
1485 int depth;
1486 const struct device_node *parent = np->parent;
1487 static const struct printf_spec strspec = {
1488 .field_width = -1,
1489 .precision = -1,
1490 };
1491
1492 /* special case for root node */
1493 if (!parent)
1494 return string(buf, end, "/", strspec);
1495
1496 for (depth = 0; parent->parent; depth++)
1497 parent = parent->parent;
1498
1499 for ( ; depth >= 0; depth--) {
1500 buf = string(buf, end, "/", strspec);
1501 buf = string(buf, end, device_node_name_for_depth(np, depth),
1502 strspec);
1503 }
1504 return buf;
1505}
1506
1507static noinline_for_stack
1508char *device_node_string(char *buf, char *end, struct device_node *dn,
1509 struct printf_spec spec, const char *fmt)
1510{
1511 char tbuf[sizeof("xxxx") + 1];
1512 const char *p;
1513 int ret;
1514 char *buf_start = buf;
1515 struct property *prop;
1516 bool has_mult, pass;
1517 static const struct printf_spec num_spec = {
1518 .flags = SMALL,
1519 .field_width = -1,
1520 .precision = -1,
1521 .base = 10,
1522 };
1523
1524 struct printf_spec str_spec = spec;
1525 str_spec.field_width = -1;
1526
1527 if (!IS_ENABLED(CONFIG_OF))
1528 return string(buf, end, "(!OF)", spec);
1529
1530 if ((unsigned long)dn < PAGE_SIZE)
1531 return string(buf, end, "(null)", spec);
1532
1533 /* simple case without anything any more format specifiers */
1534 fmt++;
1535 if (fmt[0] == '\0' || strcspn(fmt,"fnpPFcC") > 0)
1536 fmt = "f";
1537
1538 for (pass = false; strspn(fmt,"fnpPFcC"); fmt++, pass = true) {
1539 if (pass) {
1540 if (buf < end)
1541 *buf = ':';
1542 buf++;
1543 }
1544
1545 switch (*fmt) {
1546 case 'f': /* full_name */
1547 buf = device_node_gen_full_name(dn, buf, end);
1548 break;
1549 case 'n': /* name */
1550 buf = string(buf, end, dn->name, str_spec);
1551 break;
1552 case 'p': /* phandle */
1553 buf = number(buf, end, (unsigned int)dn->phandle, num_spec);
1554 break;
1555 case 'P': /* path-spec */
1556 p = kbasename(of_node_full_name(dn));
1557 if (!p[1])
1558 p = "/";
1559 buf = string(buf, end, p, str_spec);
1560 break;
1561 case 'F': /* flags */
1562 tbuf[0] = of_node_check_flag(dn, OF_DYNAMIC) ? 'D' : '-';
1563 tbuf[1] = of_node_check_flag(dn, OF_DETACHED) ? 'd' : '-';
1564 tbuf[2] = of_node_check_flag(dn, OF_POPULATED) ? 'P' : '-';
1565 tbuf[3] = of_node_check_flag(dn, OF_POPULATED_BUS) ? 'B' : '-';
1566 tbuf[4] = 0;
1567 buf = string(buf, end, tbuf, str_spec);
1568 break;
1569 case 'c': /* major compatible string */
1570 ret = of_property_read_string(dn, "compatible", &p);
1571 if (!ret)
1572 buf = string(buf, end, p, str_spec);
1573 break;
1574 case 'C': /* full compatible string */
1575 has_mult = false;
1576 of_property_for_each_string(dn, "compatible", prop, p) {
1577 if (has_mult)
1578 buf = string(buf, end, ",", str_spec);
1579 buf = string(buf, end, "\"", str_spec);
1580 buf = string(buf, end, p, str_spec);
1581 buf = string(buf, end, "\"", str_spec);
1582
1583 has_mult = true;
1584 }
1585 break;
1586 default:
1587 break;
1588 }
1589 }
1590
1591 return widen_string(buf, buf - buf_start, end, spec);
1592}
1593
1473int kptr_restrict __read_mostly; 1594int kptr_restrict __read_mostly;
1474 1595
1475/* 1596/*
@@ -1566,6 +1687,16 @@ int kptr_restrict __read_mostly;
1566 * p page flags (see struct page) given as pointer to unsigned long 1687 * p page flags (see struct page) given as pointer to unsigned long
1567 * g gfp flags (GFP_* and __GFP_*) given as pointer to gfp_t 1688 * g gfp flags (GFP_* and __GFP_*) given as pointer to gfp_t
1568 * v vma flags (VM_*) given as pointer to unsigned long 1689 * v vma flags (VM_*) given as pointer to unsigned long
1690 * - 'O' For a kobject based struct. Must be one of the following:
1691 * - 'OF[fnpPcCF]' For a device tree object
1692 * Without any optional arguments prints the full_name
1693 * f device node full_name
1694 * n device node name
1695 * p device node phandle
1696 * P device node path spec (name + @unit)
1697 * F device node flags
1698 * c major compatible string
1699 * C full compatible string
1569 * 1700 *
1570 * ** Please update also Documentation/printk-formats.txt when making changes ** 1701 * ** Please update also Documentation/printk-formats.txt when making changes **
1571 * 1702 *
@@ -1721,6 +1852,11 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr,
1721 1852
1722 case 'G': 1853 case 'G':
1723 return flags_string(buf, end, ptr, fmt); 1854 return flags_string(buf, end, ptr, fmt);
1855 case 'O':
1856 switch (fmt[1]) {
1857 case 'F':
1858 return device_node_string(buf, end, ptr, spec, fmt + 1);
1859 }
1724 } 1860 }
1725 spec.flags |= SMALL; 1861 spec.flags |= SMALL;
1726 if (spec.field_width == -1) { 1862 if (spec.field_width == -1) {