Commit 3bd32d6a authored by Sakari Ailus's avatar Sakari Ailus Committed by Rafael J. Wysocki

lib/vsprintf: Add %pfw conversion specifier for printing fwnode names

Add support for %pfw conversion specifier (with "f" and "P" modifiers) to
support printing full path of the node, including its name ("f") and only
the node's name ("P") in the printk family of functions. The two flags
have equivalent functionality to existing %pOF with the same two modifiers
("f" and "P") on OF based systems. The ability to do the same on ACPI
based systems is added by this patch.

On ACPI based systems the resulting strings look like

	\_SB.PCI0.CIO2.port@1.endpoint@0

where the nodes are separated by a dot (".") and the first three are
ACPI device nodes and the latter two ACPI data nodes.
Signed-off-by: default avatarSakari Ailus <sakari.ailus@linux.intel.com>
Reviewed-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Reviewed-by: default avatarPetr Mladek <pmladek@suse.com>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent 83abc5a7
...@@ -418,6 +418,30 @@ Examples:: ...@@ -418,6 +418,30 @@ Examples::
Passed by reference. Passed by reference.
Fwnode handles
--------------
::
%pfw[fP]
For printing information on fwnode handles. The default is to print the full
node name, including the path. The modifiers are functionally equivalent to
%pOF above.
- f - full name of the node, including the path
- P - the name of the node including an address (if there is one)
Examples (ACPI)::
%pfwf \_SB.PCI0.CIO2.port@1.endpoint@0 - Full node name
%pfwP endpoint@0 - Node name
Examples (OF)::
%pfwf /ocp@68000000/i2c@48072000/camera@10/port/endpoint - Full name
%pfwP endpoint - Node name
Time and date (struct rtc_time) Time and date (struct rtc_time)
------------------------------- -------------------------------
......
...@@ -1991,6 +1991,36 @@ char *device_node_string(char *buf, char *end, struct device_node *dn, ...@@ -1991,6 +1991,36 @@ char *device_node_string(char *buf, char *end, struct device_node *dn,
return widen_string(buf, buf - buf_start, end, spec); return widen_string(buf, buf - buf_start, end, spec);
} }
static noinline_for_stack
char *fwnode_string(char *buf, char *end, struct fwnode_handle *fwnode,
struct printf_spec spec, const char *fmt)
{
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 widen_string(buf, buf - buf_start, end, spec);
}
/* /*
* Show a '%p' thing. A kernel extension is that the '%p' is followed * Show a '%p' thing. A kernel extension is that the '%p' is followed
* by an extra set of alphanumeric characters that are extended format * by an extra set of alphanumeric characters that are extended format
...@@ -2095,6 +2125,10 @@ char *device_node_string(char *buf, char *end, struct device_node *dn, ...@@ -2095,6 +2125,10 @@ char *device_node_string(char *buf, char *end, struct device_node *dn,
* F device node flags * F device node flags
* c major compatible string * c major compatible string
* C full 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". * - 'x' For printing the address. Equivalent to "%lx".
* *
* ** When making changes please also update: * ** When making changes please also update:
...@@ -2170,6 +2204,8 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr, ...@@ -2170,6 +2204,8 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr,
return flags_string(buf, end, ptr, spec, fmt); return flags_string(buf, end, ptr, spec, fmt);
case 'O': case 'O':
return device_node_string(buf, end, ptr, spec, fmt + 1); return device_node_string(buf, end, ptr, spec, fmt + 1);
case 'f':
return fwnode_string(buf, end, ptr, spec, fmt + 1);
case 'x': case 'x':
return pointer_string(buf, end, ptr, spec); return pointer_string(buf, end, ptr, spec);
} }
......
...@@ -6015,14 +6015,18 @@ sub process { ...@@ -6015,14 +6015,18 @@ sub process {
for (my $count = $linenr; $count <= $lc; $count++) { for (my $count = $linenr; $count <= $lc; $count++) {
my $specifier; my $specifier;
my $extension; my $extension;
my $qualifier;
my $bad_specifier = ""; my $bad_specifier = "";
my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0)); my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0));
$fmt =~ s/%%//g; $fmt =~ s/%%//g;
while ($fmt =~ /(\%[\*\d\.]*p(\w))/g) { while ($fmt =~ /(\%[\*\d\.]*p(\w)(\w*))/g) {
$specifier = $1; $specifier = $1;
$extension = $2; $extension = $2;
if ($extension !~ /[SsBKRraEhMmIiUDdgVCbGNOxt]/) { $qualifier = $3;
if ($extension !~ /[SsBKRraEhMmIiUDdgVCbGNOxtf]/ ||
($extension eq "f" &&
defined $qualifier && $qualifier !~ /^w/)) {
$bad_specifier = $specifier; $bad_specifier = $specifier;
last; last;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment