kernel/device/
property.rs

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
7use core::{mem::MaybeUninit, ptr};
8
9use super::private::Sealed;
10use 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)]
35pub struct FwNode(Opaque<bindings::fwnode_handle>);
36
37impl 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>`.
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 *`.
60    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.
65    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.
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.
98    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.
104    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`.
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`].
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`.
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    /// ```
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.
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.
218    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.
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`].
299pub 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)]
320pub struct FwNodeReferenceArgs(bindings::fwnode_reference_args);
321
322impl Drop for FwNodeReferenceArgs {
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
335impl FwNodeReferenceArgs {
336    /// Returns the slice of reference arguments.
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.
344    pub fn len(&self) -> usize {
345        self.0.nargs as usize
346    }
347
348    /// Returns `true` if there are no reference arguments.
349    pub fn is_empty(&self) -> bool {
350        self.0.nargs == 0
351    }
352}
353
354impl core::fmt::Debug for FwNodeReferenceArgs {
355    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.
361unsafe impl crate::types::AlwaysRefCounted for FwNode {
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
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
375enum Node<'a> {
376    Borrowed(&'a FwNode),
377    Owned(ARef<FwNode>),
378}
379
380impl core::fmt::Display for FwNode {
381    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.
436pub trait Property: Sized + Sealed {
437    /// Used to make [`FwNode::property_read`] generic.
438    fn read_from_fwnode_property(fwnode: &FwNode, name: &CStr) -> Result<Self>;
439}
440
441impl Sealed for CString {}
442
443impl Property for CString {
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.
474pub trait PropertyInt: Copy + Sealed {
475    /// Reads a property array.
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.
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.
490macro_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}
563impl_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.
580pub 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
589impl<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.
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.
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.
619    pub fn or(self, default: T) -> T {
620        self.inner.unwrap_or(default)
621    }
622}
623
624impl<T: Default> PropertyGuard<'_, '_, T> {
625    /// Access the property or a default value.
626    ///
627    /// Use [`Self::or`] to specify a custom default value.
628    pub fn or_default(self) -> T {
629        self.inner.unwrap_or_default()
630    }
631}