xref: /linux/rust/kernel/device/property.rs (revision 22c5696e3fe029f4fc2decbe7cc6663b5d281223)
1 // SPDX-License-Identifier: GPL-2.0
2 
3 //! Unified device property interface.
4 //!
5 //! C header: [`include/linux/property.h`](srctree/include/linux/property.h)
6 
7 use core::{mem::MaybeUninit, ptr};
8 
9 use super::private::Sealed;
10 use crate::{
11     alloc::KVec,
12     bindings,
13     error::{to_result, Result},
14     prelude::*,
15     str::{CStr, CString},
16     types::{ARef, Opaque},
17 };
18 
19 /// A reference-counted fwnode_handle.
20 ///
21 /// This structure represents the Rust abstraction for a
22 /// C `struct fwnode_handle`. This implementation abstracts the usage of an
23 /// already existing C `struct fwnode_handle` within Rust code that we get
24 /// passed from the C side.
25 ///
26 /// # Invariants
27 ///
28 /// A `FwNode` instance represents a valid `struct fwnode_handle` created by the
29 /// C portion of the kernel.
30 ///
31 /// Instances of this type are always reference-counted, that is, a call to
32 /// `fwnode_handle_get` ensures that the allocation remains valid at least until
33 /// the matching call to `fwnode_handle_put`.
34 #[repr(transparent)]
35 pub struct FwNode(Opaque<bindings::fwnode_handle>);
36 
37 impl FwNode {
38     /// # Safety
39     ///
40     /// Callers must ensure that:
41     /// - The reference count was incremented at least once.
42     /// - They relinquish that increment. That is, if there is only one
43     ///   increment, callers must not use the underlying object anymore -- it is
44     ///   only safe to do so via the newly created `ARef<FwNode>`.
from_raw(raw: *mut bindings::fwnode_handle) -> ARef<Self>45     unsafe fn from_raw(raw: *mut bindings::fwnode_handle) -> ARef<Self> {
46         // SAFETY: As per the safety requirements of this function:
47         // - `NonNull::new_unchecked`:
48         //   - `raw` is not null.
49         // - `ARef::from_raw`:
50         //   - `raw` has an incremented refcount.
51         //   - that increment is relinquished, i.e. it won't be decremented
52         //     elsewhere.
53         // CAST: It is safe to cast from a `*mut fwnode_handle` to
54         // `*mut FwNode`, because `FwNode` is  defined as a
55         // `#[repr(transparent)]` wrapper around `fwnode_handle`.
56         unsafe { ARef::from_raw(ptr::NonNull::new_unchecked(raw.cast())) }
57     }
58 
59     /// Obtain the raw `struct fwnode_handle *`.
as_raw(&self) -> *mut bindings::fwnode_handle60     pub(crate) fn as_raw(&self) -> *mut bindings::fwnode_handle {
61         self.0.get()
62     }
63 
64     /// Returns `true` if `&self` is an OF node, `false` otherwise.
is_of_node(&self) -> bool65     pub fn is_of_node(&self) -> bool {
66         // SAFETY: The type invariant of `Self` guarantees that `self.as_raw() is a pointer to a
67         // valid `struct fwnode_handle`.
68         unsafe { bindings::is_of_node(self.as_raw()) }
69     }
70 
71     /// Returns an object that implements [`Display`](core::fmt::Display) for
72     /// printing the name of a node.
73     ///
74     /// This is an alternative to the default `Display` implementation, which
75     /// prints the full path.
display_name(&self) -> impl core::fmt::Display + '_76     pub fn display_name(&self) -> impl core::fmt::Display + '_ {
77         struct FwNodeDisplayName<'a>(&'a FwNode);
78 
79         impl core::fmt::Display for FwNodeDisplayName<'_> {
80             fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
81                 // SAFETY: `self` is valid by its type invariant.
82                 let name = unsafe { bindings::fwnode_get_name(self.0.as_raw()) };
83                 if name.is_null() {
84                     return Ok(());
85                 }
86                 // SAFETY:
87                 // - `fwnode_get_name` returns null or a valid C string.
88                 // - `name` was checked to be non-null.
89                 let name = unsafe { CStr::from_char_ptr(name) };
90                 write!(f, "{name}")
91             }
92         }
93 
94         FwNodeDisplayName(self)
95     }
96 
97     /// Checks if property is present or not.
property_present(&self, name: &CStr) -> bool98     pub fn property_present(&self, name: &CStr) -> bool {
99         // SAFETY: By the invariant of `CStr`, `name` is null-terminated.
100         unsafe { bindings::fwnode_property_present(self.as_raw().cast_const(), name.as_char_ptr()) }
101     }
102 
103     /// Returns firmware property `name` boolean value.
property_read_bool(&self, name: &CStr) -> bool104     pub fn property_read_bool(&self, name: &CStr) -> bool {
105         // SAFETY:
106         // - `name` is non-null and null-terminated.
107         // - `self.as_raw()` is valid because `self` is valid.
108         unsafe { bindings::fwnode_property_read_bool(self.as_raw(), name.as_char_ptr()) }
109     }
110 
111     /// Returns the index of matching string `match_str` for firmware string
112     /// property `name`.
property_match_string(&self, name: &CStr, match_str: &CStr) -> Result<usize>113     pub fn property_match_string(&self, name: &CStr, match_str: &CStr) -> Result<usize> {
114         // SAFETY:
115         // - `name` and `match_str` are non-null and null-terminated.
116         // - `self.as_raw` is valid because `self` is valid.
117         let ret = unsafe {
118             bindings::fwnode_property_match_string(
119                 self.as_raw(),
120                 name.as_char_ptr(),
121                 match_str.as_char_ptr(),
122             )
123         };
124         to_result(ret)?;
125         Ok(ret as usize)
126     }
127 
128     /// Returns firmware property `name` integer array values in a [`KVec`].
property_read_array_vec<'fwnode, 'name, T: PropertyInt>( &'fwnode self, name: &'name CStr, len: usize, ) -> Result<PropertyGuard<'fwnode, 'name, KVec<T>>>129     pub fn property_read_array_vec<'fwnode, 'name, T: PropertyInt>(
130         &'fwnode self,
131         name: &'name CStr,
132         len: usize,
133     ) -> Result<PropertyGuard<'fwnode, 'name, KVec<T>>> {
134         let mut val: KVec<T> = KVec::with_capacity(len, GFP_KERNEL)?;
135 
136         let res = T::read_array_from_fwnode_property(self, name, val.spare_capacity_mut());
137         let res = match res {
138             Ok(_) => {
139                 // SAFETY:
140                 // - `len` is equal to `val.capacity - val.len`, because
141                 //   `val.capacity` is `len` and `val.len` is zero.
142                 // - All elements within the interval [`0`, `len`) were initialized
143                 //   by `read_array_from_fwnode_property`.
144                 unsafe { val.inc_len(len) }
145                 Ok(val)
146             }
147             Err(e) => Err(e),
148         };
149         Ok(PropertyGuard {
150             inner: res,
151             fwnode: self,
152             name,
153         })
154     }
155 
156     /// Returns integer array length for firmware property `name`.
property_count_elem<T: PropertyInt>(&self, name: &CStr) -> Result<usize>157     pub fn property_count_elem<T: PropertyInt>(&self, name: &CStr) -> Result<usize> {
158         T::read_array_len_from_fwnode_property(self, name)
159     }
160 
161     /// Returns the value of firmware property `name`.
162     ///
163     /// This method is generic over the type of value to read. The types that
164     /// can be read are strings, integers and arrays of integers.
165     ///
166     /// Reading a [`KVec`] of integers is done with the separate
167     /// method [`Self::property_read_array_vec`], because it takes an
168     /// additional `len` argument.
169     ///
170     /// Reading a boolean is done with the separate method
171     /// [`Self::property_read_bool`], because this operation is infallible.
172     ///
173     /// For more precise documentation about what types can be read, see
174     /// the [implementors of Property][Property#implementors] and [its
175     /// implementations on foreign types][Property#foreign-impls].
176     ///
177     /// # Examples
178     ///
179     /// ```
180     /// # use kernel::{c_str, device::{Device, property::FwNode}, str::CString};
181     /// fn examples(dev: &Device) -> Result {
182     ///     let fwnode = dev.fwnode().ok_or(ENOENT)?;
183     ///     let b: u32 = fwnode.property_read(c_str!("some-number")).required_by(dev)?;
184     ///     if let Some(s) = fwnode.property_read::<CString>(c_str!("some-str")).optional() {
185     ///         // ...
186     ///     }
187     ///     Ok(())
188     /// }
189     /// ```
property_read<'fwnode, 'name, T: Property>( &'fwnode self, name: &'name CStr, ) -> PropertyGuard<'fwnode, 'name, T>190     pub fn property_read<'fwnode, 'name, T: Property>(
191         &'fwnode self,
192         name: &'name CStr,
193     ) -> PropertyGuard<'fwnode, 'name, T> {
194         PropertyGuard {
195             inner: T::read_from_fwnode_property(self, name),
196             fwnode: self,
197             name,
198         }
199     }
200 
201     /// Returns first matching named child node handle.
get_child_by_name(&self, name: &CStr) -> Option<ARef<Self>>202     pub fn get_child_by_name(&self, name: &CStr) -> Option<ARef<Self>> {
203         // SAFETY: `self` and `name` are valid by their type invariants.
204         let child =
205             unsafe { bindings::fwnode_get_named_child_node(self.as_raw(), name.as_char_ptr()) };
206         if child.is_null() {
207             return None;
208         }
209         // SAFETY:
210         // - `fwnode_get_named_child_node` returns a pointer with its refcount
211         //   incremented.
212         // - That increment is relinquished, i.e. the underlying object is not
213         //   used anymore except via the newly created `ARef`.
214         Some(unsafe { Self::from_raw(child) })
215     }
216 
217     /// Returns an iterator over a node's children.
children<'a>(&'a self) -> impl Iterator<Item = ARef<FwNode>> + 'a218     pub fn children<'a>(&'a self) -> impl Iterator<Item = ARef<FwNode>> + 'a {
219         let mut prev: Option<ARef<FwNode>> = None;
220 
221         core::iter::from_fn(move || {
222             let prev_ptr = match prev.take() {
223                 None => ptr::null_mut(),
224                 Some(prev) => {
225                     // We will pass `prev` to `fwnode_get_next_child_node`,
226                     // which decrements its refcount, so we use
227                     // `ARef::into_raw` to avoid decrementing the refcount
228                     // twice.
229                     let prev = ARef::into_raw(prev);
230                     prev.as_ptr().cast()
231                 }
232             };
233             // SAFETY:
234             // - `self.as_raw()` is valid by its type invariant.
235             // - `prev_ptr` may be null, which is allowed and corresponds to
236             //   getting the first child. Otherwise, `prev_ptr` is valid, as it
237             //   is the stored return value from the previous invocation.
238             // - `prev_ptr` has its refount incremented.
239             // - The increment of `prev_ptr` is relinquished, i.e. the
240             //   underlying object won't be used anymore.
241             let next = unsafe { bindings::fwnode_get_next_child_node(self.as_raw(), prev_ptr) };
242             if next.is_null() {
243                 return None;
244             }
245             // SAFETY:
246             // - `next` is valid because `fwnode_get_next_child_node` returns a
247             //   pointer with its refcount incremented.
248             // - That increment is relinquished, i.e. the underlying object
249             //   won't be used anymore, except via the newly created
250             //   `ARef<Self>`.
251             let next = unsafe { FwNode::from_raw(next) };
252             prev = Some(next.clone());
253             Some(next)
254         })
255     }
256 
257     /// Finds a reference with arguments.
property_get_reference_args( &self, prop: &CStr, nargs: NArgs<'_>, index: u32, ) -> Result<FwNodeReferenceArgs>258     pub fn property_get_reference_args(
259         &self,
260         prop: &CStr,
261         nargs: NArgs<'_>,
262         index: u32,
263     ) -> Result<FwNodeReferenceArgs> {
264         let mut out_args = FwNodeReferenceArgs::default();
265 
266         let (nargs_prop, nargs) = match nargs {
267             NArgs::Prop(nargs_prop) => (nargs_prop.as_char_ptr(), 0),
268             NArgs::N(nargs) => (ptr::null(), nargs),
269         };
270 
271         // SAFETY:
272         // - `self.0.get()` is valid.
273         // - `prop.as_char_ptr()` is valid and zero-terminated.
274         // - `nargs_prop` is valid and zero-terminated if `nargs`
275         //   is zero, otherwise it is allowed to be a null-pointer.
276         // - The function upholds the type invariants of `out_args`,
277         //   namely:
278         //   - It may fill the field `fwnode` with a valid pointer,
279         //     in which case its refcount is incremented.
280         //   - It may modify the field `nargs`, in which case it
281         //     initializes at least as many elements in `args`.
282         let ret = unsafe {
283             bindings::fwnode_property_get_reference_args(
284                 self.0.get(),
285                 prop.as_char_ptr(),
286                 nargs_prop,
287                 nargs,
288                 index,
289                 &mut out_args.0,
290             )
291         };
292         to_result(ret)?;
293 
294         Ok(out_args)
295     }
296 }
297 
298 /// The number of arguments to request [`FwNodeReferenceArgs`].
299 pub enum NArgs<'a> {
300     /// The name of the property of the reference indicating the number of
301     /// arguments.
302     Prop(&'a CStr),
303     /// The known number of arguments.
304     N(u32),
305 }
306 
307 /// The return value of [`FwNode::property_get_reference_args`].
308 ///
309 /// This structure represents the Rust abstraction for a C
310 /// `struct fwnode_reference_args` which was initialized by the C side.
311 ///
312 /// # Invariants
313 ///
314 /// If the field `fwnode` is valid, it owns an increment of its refcount.
315 ///
316 /// The field `args` contains at least as many initialized elements as indicated
317 /// by the field `nargs`.
318 #[repr(transparent)]
319 #[derive(Default)]
320 pub struct FwNodeReferenceArgs(bindings::fwnode_reference_args);
321 
322 impl Drop for FwNodeReferenceArgs {
drop(&mut self)323     fn drop(&mut self) {
324         if !self.0.fwnode.is_null() {
325             // SAFETY:
326             // - By the type invariants of `FwNodeReferenceArgs`, its field
327             //   `fwnode` owns an increment of its refcount.
328             // - That increment is relinquished. The underlying object won't be
329             //   used anymore because we are dropping it.
330             let _ = unsafe { FwNode::from_raw(self.0.fwnode) };
331         }
332     }
333 }
334 
335 impl FwNodeReferenceArgs {
336     /// Returns the slice of reference arguments.
as_slice(&self) -> &[u64]337     pub fn as_slice(&self) -> &[u64] {
338         // SAFETY: As per the safety invariant of `FwNodeReferenceArgs`, `nargs`
339         // is the minimum number of elements in `args` that is valid.
340         unsafe { core::slice::from_raw_parts(self.0.args.as_ptr(), self.0.nargs as usize) }
341     }
342 
343     /// Returns the number of reference arguments.
len(&self) -> usize344     pub fn len(&self) -> usize {
345         self.0.nargs as usize
346     }
347 
348     /// Returns `true` if there are no reference arguments.
is_empty(&self) -> bool349     pub fn is_empty(&self) -> bool {
350         self.0.nargs == 0
351     }
352 }
353 
354 impl core::fmt::Debug for FwNodeReferenceArgs {
fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result355     fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
356         write!(f, "{:?}", self.as_slice())
357     }
358 }
359 
360 // SAFETY: Instances of `FwNode` are always reference-counted.
361 unsafe impl crate::types::AlwaysRefCounted for FwNode {
inc_ref(&self)362     fn inc_ref(&self) {
363         // SAFETY: The existence of a shared reference guarantees that the
364         // refcount is non-zero.
365         unsafe { bindings::fwnode_handle_get(self.as_raw()) };
366     }
367 
dec_ref(obj: ptr::NonNull<Self>)368     unsafe fn dec_ref(obj: ptr::NonNull<Self>) {
369         // SAFETY: The safety requirements guarantee that the refcount is
370         // non-zero.
371         unsafe { bindings::fwnode_handle_put(obj.cast().as_ptr()) }
372     }
373 }
374 
375 enum Node<'a> {
376     Borrowed(&'a FwNode),
377     Owned(ARef<FwNode>),
378 }
379 
380 impl core::fmt::Display for FwNode {
fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result381     fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
382         // The logic here is the same as the one in lib/vsprintf.c
383         // (fwnode_full_name_string).
384 
385         // SAFETY: `self.as_raw()` is valid by its type invariant.
386         let num_parents = unsafe { bindings::fwnode_count_parents(self.as_raw()) };
387 
388         for depth in (0..=num_parents).rev() {
389             let fwnode = if depth == 0 {
390                 Node::Borrowed(self)
391             } else {
392                 // SAFETY: `self.as_raw()` is valid.
393                 let ptr = unsafe { bindings::fwnode_get_nth_parent(self.as_raw(), depth) };
394                 // SAFETY:
395                 // - The depth passed to `fwnode_get_nth_parent` is
396                 //   within the valid range, so the returned pointer is
397                 //   not null.
398                 // - The reference count was incremented by
399                 //   `fwnode_get_nth_parent`.
400                 // - That increment is relinquished to
401                 //   `FwNode::from_raw`.
402                 Node::Owned(unsafe { FwNode::from_raw(ptr) })
403             };
404             // Take a reference to the owned or borrowed `FwNode`.
405             let fwnode: &FwNode = match &fwnode {
406                 Node::Borrowed(f) => f,
407                 Node::Owned(f) => f,
408             };
409 
410             // SAFETY: `fwnode` is valid by its type invariant.
411             let prefix = unsafe { bindings::fwnode_get_name_prefix(fwnode.as_raw()) };
412             if !prefix.is_null() {
413                 // SAFETY: `fwnode_get_name_prefix` returns null or a
414                 // valid C string.
415                 let prefix = unsafe { CStr::from_char_ptr(prefix) };
416                 write!(f, "{prefix}")?;
417             }
418             write!(f, "{}", fwnode.display_name())?;
419         }
420 
421         Ok(())
422     }
423 }
424 
425 /// Implemented for types that can be read as properties.
426 ///
427 /// This is implemented for strings, integers and arrays of integers. It's used
428 /// to make [`FwNode::property_read`] generic over the type of property being
429 /// read. There are also two dedicated methods to read other types, because they
430 /// require more specialized function signatures:
431 /// - [`property_read_bool`](FwNode::property_read_bool)
432 /// - [`property_read_array_vec`](FwNode::property_read_array_vec)
433 ///
434 /// It must be public, because it appears in the signatures of other public
435 /// functions, but its methods shouldn't be used outside the kernel crate.
436 pub trait Property: Sized + Sealed {
437     /// Used to make [`FwNode::property_read`] generic.
read_from_fwnode_property(fwnode: &FwNode, name: &CStr) -> Result<Self>438     fn read_from_fwnode_property(fwnode: &FwNode, name: &CStr) -> Result<Self>;
439 }
440 
441 impl Sealed for CString {}
442 
443 impl Property for CString {
read_from_fwnode_property(fwnode: &FwNode, name: &CStr) -> Result<Self>444     fn read_from_fwnode_property(fwnode: &FwNode, name: &CStr) -> Result<Self> {
445         let mut str: *mut u8 = ptr::null_mut();
446         let pstr: *mut _ = &mut str;
447 
448         // SAFETY:
449         // - `name` is non-null and null-terminated.
450         // - `fwnode.as_raw` is valid because `fwnode` is valid.
451         let ret = unsafe {
452             bindings::fwnode_property_read_string(fwnode.as_raw(), name.as_char_ptr(), pstr.cast())
453         };
454         to_result(ret)?;
455 
456         // SAFETY:
457         // - `pstr` is a valid pointer to a NUL-terminated C string.
458         // - It is valid for at least as long as `fwnode`, but it's only used
459         //   within the current function.
460         // - The memory it points to is not mutated during that time.
461         let str = unsafe { CStr::from_char_ptr(*pstr) };
462         Ok(str.try_into()?)
463     }
464 }
465 
466 /// Implemented for all integers that can be read as properties.
467 ///
468 /// This helper trait is needed on top of the existing [`Property`]
469 /// trait to associate the integer types of various sizes with their
470 /// corresponding `fwnode_property_read_*_array` functions.
471 ///
472 /// It must be public, because it appears in the signatures of other public
473 /// functions, but its methods shouldn't be used outside the kernel crate.
474 pub trait PropertyInt: Copy + Sealed {
475     /// Reads a property array.
read_array_from_fwnode_property<'a>( fwnode: &FwNode, name: &CStr, out: &'a mut [MaybeUninit<Self>], ) -> Result<&'a mut [Self]>476     fn read_array_from_fwnode_property<'a>(
477         fwnode: &FwNode,
478         name: &CStr,
479         out: &'a mut [MaybeUninit<Self>],
480     ) -> Result<&'a mut [Self]>;
481 
482     /// Reads the length of a property array.
read_array_len_from_fwnode_property(fwnode: &FwNode, name: &CStr) -> Result<usize>483     fn read_array_len_from_fwnode_property(fwnode: &FwNode, name: &CStr) -> Result<usize>;
484 }
485 // This macro generates implementations of the traits `Property` and
486 // `PropertyInt` for integers of various sizes. Its input is a list
487 // of pairs separated by commas. The first element of the pair is the
488 // type of the integer, the second one is the name of its corresponding
489 // `fwnode_property_read_*_array` function.
490 macro_rules! impl_property_for_int {
491     ($($int:ty: $f:ident),* $(,)?) => { $(
492         impl Sealed for $int {}
493         impl<const N: usize> Sealed for [$int; N] {}
494 
495         impl PropertyInt for $int {
496             fn read_array_from_fwnode_property<'a>(
497                 fwnode: &FwNode,
498                 name: &CStr,
499                 out: &'a mut [MaybeUninit<Self>],
500             ) -> Result<&'a mut [Self]> {
501                 // SAFETY:
502                 // - `fwnode`, `name` and `out` are all valid by their type
503                 //   invariants.
504                 // - `out.len()` is a valid bound for the memory pointed to by
505                 //   `out.as_mut_ptr()`.
506                 // CAST: It's ok to cast from `*mut MaybeUninit<$int>` to a
507                 // `*mut $int` because they have the same memory layout.
508                 let ret = unsafe {
509                     bindings::$f(
510                         fwnode.as_raw(),
511                         name.as_char_ptr(),
512                         out.as_mut_ptr().cast(),
513                         out.len(),
514                     )
515                 };
516                 to_result(ret)?;
517                 // SAFETY: Transmuting from `&'a mut [MaybeUninit<Self>]` to
518                 // `&'a mut [Self]` is sound, because the previous call to a
519                 // `fwnode_property_read_*_array` function (which didn't fail)
520                 // fully initialized the slice.
521                 Ok(unsafe { core::mem::transmute::<&mut [MaybeUninit<Self>], &mut [Self]>(out) })
522             }
523 
524             fn read_array_len_from_fwnode_property(fwnode: &FwNode, name: &CStr) -> Result<usize> {
525                 // SAFETY:
526                 // - `fwnode` and `name` are valid by their type invariants.
527                 // - It's ok to pass a null pointer to the
528                 //   `fwnode_property_read_*_array` functions if `nval` is zero.
529                 //   This will return the length of the array.
530                 let ret = unsafe {
531                     bindings::$f(
532                         fwnode.as_raw(),
533                         name.as_char_ptr(),
534                         ptr::null_mut(),
535                         0,
536                     )
537                 };
538                 to_result(ret)?;
539                 Ok(ret as usize)
540             }
541         }
542 
543         impl Property for $int {
544             fn read_from_fwnode_property(fwnode: &FwNode, name: &CStr) -> Result<Self> {
545                 let val: [_; 1] = <[$int; 1]>::read_from_fwnode_property(fwnode, name)?;
546                 Ok(val[0])
547             }
548         }
549 
550         impl<const N: usize> Property for [$int; N] {
551             fn read_from_fwnode_property(fwnode: &FwNode, name: &CStr) -> Result<Self> {
552                 let mut val: [MaybeUninit<$int>; N] = [const { MaybeUninit::uninit() }; N];
553 
554                 <$int>::read_array_from_fwnode_property(fwnode, name, &mut val)?;
555 
556                 // SAFETY: `val` is always initialized when
557                 // `fwnode_property_read_*_array` is successful.
558                 Ok(val.map(|v| unsafe { v.assume_init() }))
559             }
560         }
561     )* };
562 }
563 impl_property_for_int! {
564     u8: fwnode_property_read_u8_array,
565     u16: fwnode_property_read_u16_array,
566     u32: fwnode_property_read_u32_array,
567     u64: fwnode_property_read_u64_array,
568     i8: fwnode_property_read_u8_array,
569     i16: fwnode_property_read_u16_array,
570     i32: fwnode_property_read_u32_array,
571     i64: fwnode_property_read_u64_array,
572 }
573 
574 /// A helper for reading device properties.
575 ///
576 /// Use [`Self::required_by`] if a missing property is considered a bug and
577 /// [`Self::optional`] otherwise.
578 ///
579 /// For convenience, [`Self::or`] and [`Self::or_default`] are provided.
580 pub struct PropertyGuard<'fwnode, 'name, T> {
581     /// The result of reading the property.
582     inner: Result<T>,
583     /// The fwnode of the property, used for logging in the "required" case.
584     fwnode: &'fwnode FwNode,
585     /// The name of the property, used for logging in the "required" case.
586     name: &'name CStr,
587 }
588 
589 impl<T> PropertyGuard<'_, '_, T> {
590     /// Access the property, indicating it is required.
591     ///
592     /// If the property is not present, the error is automatically logged. If a
593     /// missing property is not an error, use [`Self::optional`] instead. The
594     /// device is required to associate the log with it.
required_by(self, dev: &super::Device) -> Result<T>595     pub fn required_by(self, dev: &super::Device) -> Result<T> {
596         if self.inner.is_err() {
597             dev_err!(
598                 dev,
599                 "{}: property '{}' is missing\n",
600                 self.fwnode,
601                 self.name
602             );
603         }
604         self.inner
605     }
606 
607     /// Access the property, indicating it is optional.
608     ///
609     /// In contrast to [`Self::required_by`], no error message is logged if
610     /// the property is not present.
optional(self) -> Option<T>611     pub fn optional(self) -> Option<T> {
612         self.inner.ok()
613     }
614 
615     /// Access the property or the specified default value.
616     ///
617     /// Do not pass a sentinel value as default to detect a missing property.
618     /// Use [`Self::required_by`] or [`Self::optional`] instead.
or(self, default: T) -> T619     pub fn or(self, default: T) -> T {
620         self.inner.unwrap_or(default)
621     }
622 }
623 
624 impl<T: Default> PropertyGuard<'_, '_, T> {
625     /// Access the property or a default value.
626     ///
627     /// Use [`Self::or`] to specify a custom default value.
or_default(self) -> T628     pub fn or_default(self) -> T {
629         self.inner.unwrap_or_default()
630     }
631 }
632