@@ -57,6 +57,32 @@ impl FwNode {
5757 self . 0 . get ( )
5858 }
5959
60+ /// Returns an object that implements [`Display`](core::fmt::Display) for
61+ /// printing the name of a node.
62+ ///
63+ /// This is an alternative to the default `Display` implementation, which
64+ /// prints the full path.
65+ pub fn display_name ( & self ) -> impl core:: fmt:: Display + ' _ {
66+ struct FwNodeDisplayName < ' a > ( & ' a FwNode ) ;
67+
68+ impl core:: fmt:: Display for FwNodeDisplayName < ' _ > {
69+ fn fmt ( & self , f : & mut core:: fmt:: Formatter < ' _ > ) -> core:: fmt:: Result {
70+ // SAFETY: `self` is valid by its type invariant.
71+ let name = unsafe { bindings:: fwnode_get_name ( self . 0 . as_raw ( ) ) } ;
72+ if name. is_null ( ) {
73+ return Ok ( ( ) ) ;
74+ }
75+ // SAFETY:
76+ // - `fwnode_get_name` returns null or a valid C string.
77+ // - `name` was checked to be non-null.
78+ let name = unsafe { CStr :: from_char_ptr ( name) } ;
79+ write ! ( f, "{name}" )
80+ }
81+ }
82+
83+ FwNodeDisplayName ( self )
84+ }
85+
6086 /// Checks if property is present or not.
6187 pub fn property_present ( & self , name : & CStr ) -> bool {
6288 // SAFETY: By the invariant of `CStr`, `name` is null-terminated.
@@ -78,3 +104,53 @@ unsafe impl crate::types::AlwaysRefCounted for FwNode {
78104 unsafe { bindings:: fwnode_handle_put ( obj. cast ( ) . as_ptr ( ) ) }
79105 }
80106}
107+
108+ enum Node < ' a > {
109+ Borrowed ( & ' a FwNode ) ,
110+ Owned ( ARef < FwNode > ) ,
111+ }
112+
113+ impl core:: fmt:: Display for FwNode {
114+ fn fmt ( & self , f : & mut core:: fmt:: Formatter < ' _ > ) -> core:: fmt:: Result {
115+ // The logic here is the same as the one in lib/vsprintf.c
116+ // (fwnode_full_name_string).
117+
118+ // SAFETY: `self.as_raw()` is valid by its type invariant.
119+ let num_parents = unsafe { bindings:: fwnode_count_parents ( self . as_raw ( ) ) } ;
120+
121+ for depth in ( 0 ..=num_parents) . rev ( ) {
122+ let fwnode = if depth == 0 {
123+ Node :: Borrowed ( self )
124+ } else {
125+ // SAFETY: `self.as_raw()` is valid.
126+ let ptr = unsafe { bindings:: fwnode_get_nth_parent ( self . as_raw ( ) , depth) } ;
127+ // SAFETY:
128+ // - The depth passed to `fwnode_get_nth_parent` is
129+ // within the valid range, so the returned pointer is
130+ // not null.
131+ // - The reference count was incremented by
132+ // `fwnode_get_nth_parent`.
133+ // - That increment is relinquished to
134+ // `FwNode::from_raw`.
135+ Node :: Owned ( unsafe { FwNode :: from_raw ( ptr) } )
136+ } ;
137+ // Take a reference to the owned or borrowed `FwNode`.
138+ let fwnode: & FwNode = match & fwnode {
139+ Node :: Borrowed ( f) => f,
140+ Node :: Owned ( f) => f,
141+ } ;
142+
143+ // SAFETY: `fwnode` is valid by its type invariant.
144+ let prefix = unsafe { bindings:: fwnode_get_name_prefix ( fwnode. as_raw ( ) ) } ;
145+ if !prefix. is_null ( ) {
146+ // SAFETY: `fwnode_get_name_prefix` returns null or a
147+ // valid C string.
148+ let prefix = unsafe { CStr :: from_char_ptr ( prefix) } ;
149+ write ! ( f, "{prefix}" ) ?;
150+ }
151+ write ! ( f, "{}" , fwnode. display_name( ) ) ?;
152+ }
153+
154+ Ok ( ( ) )
155+ }
156+ }
0 commit comments