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 an object that implements [`Display`](core::fmt::Display) for
65    /// printing the name of a node.
66    ///
67    /// This is an alternative to the default `Display` implementation, which
68    /// prints the full path.
69    pub fn display_name(&self) -> impl core::fmt::Display + '_ {
70        struct FwNodeDisplayName<'a>(&'a FwNode);
71
72        impl core::fmt::Display for FwNodeDisplayName<'_> {
73            fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
74                // SAFETY: `self` is valid by its type invariant.
75                let name = unsafe { bindings::fwnode_get_name(self.0.as_raw()) };
76                if name.is_null() {
77                    return Ok(());
78                }
79                // SAFETY:
80                // - `fwnode_get_name` returns null or a valid C string.
81                // - `name` was checked to be non-null.
82                let name = unsafe { CStr::from_char_ptr(name) };
83                write!(f, "{name}")
84            }
85        }
86
87        FwNodeDisplayName(self)
88    }
89
90    /// Checks if property is present or not.
91    pub fn property_present(&self, name: &CStr) -> bool {
92        // SAFETY: By the invariant of `CStr`, `name` is null-terminated.
93        unsafe { bindings::fwnode_property_present(self.as_raw().cast_const(), name.as_char_ptr()) }
94    }
95
96    /// Returns firmware property `name` boolean value.
97    pub fn property_read_bool(&self, name: &CStr) -> bool {
98        // SAFETY:
99        // - `name` is non-null and null-terminated.
100        // - `self.as_raw()` is valid because `self` is valid.
101        unsafe { bindings::fwnode_property_read_bool(self.as_raw(), name.as_char_ptr()) }
102    }
103
104    /// Returns the index of matching string `match_str` for firmware string
105    /// property `name`.
106    pub fn property_match_string(&self, name: &CStr, match_str: &CStr) -> Result<usize> {
107        // SAFETY:
108        // - `name` and `match_str` are non-null and null-terminated.
109        // - `self.as_raw` is valid because `self` is valid.
110        let ret = unsafe {
111            bindings::fwnode_property_match_string(
112                self.as_raw(),
113                name.as_char_ptr(),
114                match_str.as_char_ptr(),
115            )
116        };
117        to_result(ret)?;
118        Ok(ret as usize)
119    }
120
121    /// Returns firmware property `name` integer array values in a [`KVec`].
122    pub fn property_read_array_vec<'fwnode, 'name, T: PropertyInt>(
123        &'fwnode self,
124        name: &'name CStr,
125        len: usize,
126    ) -> Result<PropertyGuard<'fwnode, 'name, KVec<T>>> {
127        let mut val: KVec<T> = KVec::with_capacity(len, GFP_KERNEL)?;
128
129        let res = T::read_array_from_fwnode_property(self, name, val.spare_capacity_mut());
130        let res = match res {
131            Ok(_) => {
132                // SAFETY:
133                // - `len` is equal to `val.capacity - val.len`, because
134                //   `val.capacity` is `len` and `val.len` is zero.
135                // - All elements within the interval [`0`, `len`) were initialized
136                //   by `read_array_from_fwnode_property`.
137                unsafe { val.inc_len(len) }
138                Ok(val)
139            }
140            Err(e) => Err(e),
141        };
142        Ok(PropertyGuard {
143            inner: res,
144            fwnode: self,
145            name,
146        })
147    }
148
149    /// Returns integer array length for firmware property `name`.
150    pub fn property_count_elem<T: PropertyInt>(&self, name: &CStr) -> Result<usize> {
151        T::read_array_len_from_fwnode_property(self, name)
152    }
153
154    /// Returns the value of firmware property `name`.
155    ///
156    /// This method is generic over the type of value to read. The types that
157    /// can be read are strings, integers and arrays of integers.
158    ///
159    /// Reading a [`KVec`] of integers is done with the separate
160    /// method [`Self::property_read_array_vec`], because it takes an
161    /// additional `len` argument.
162    ///
163    /// Reading a boolean is done with the separate method
164    /// [`Self::property_read_bool`], because this operation is infallible.
165    ///
166    /// For more precise documentation about what types can be read, see
167    /// the [implementors of Property][Property#implementors] and [its
168    /// implementations on foreign types][Property#foreign-impls].
169    ///
170    /// # Examples
171    ///
172    /// ```
173    /// # use kernel::{c_str, device::{Device, property::FwNode}, str::CString};
174    /// fn examples(dev: &Device) -> Result {
175    ///     let fwnode = dev.fwnode().ok_or(ENOENT)?;
176    ///     let b: u32 = fwnode.property_read(c_str!("some-number")).required_by(dev)?;
177    ///     if let Some(s) = fwnode.property_read::<CString>(c_str!("some-str")).optional() {
178    ///         // ...
179    ///     }
180    ///     Ok(())
181    /// }
182    /// ```
183    pub fn property_read<'fwnode, 'name, T: Property>(
184        &'fwnode self,
185        name: &'name CStr,
186    ) -> PropertyGuard<'fwnode, 'name, T> {
187        PropertyGuard {
188            inner: T::read_from_fwnode_property(self, name),
189            fwnode: self,
190            name,
191        }
192    }
193}
194
195// SAFETY: Instances of `FwNode` are always reference-counted.
196unsafe impl crate::types::AlwaysRefCounted for FwNode {
197    fn inc_ref(&self) {
198        // SAFETY: The existence of a shared reference guarantees that the
199        // refcount is non-zero.
200        unsafe { bindings::fwnode_handle_get(self.as_raw()) };
201    }
202
203    unsafe fn dec_ref(obj: ptr::NonNull<Self>) {
204        // SAFETY: The safety requirements guarantee that the refcount is
205        // non-zero.
206        unsafe { bindings::fwnode_handle_put(obj.cast().as_ptr()) }
207    }
208}
209
210enum Node<'a> {
211    Borrowed(&'a FwNode),
212    Owned(ARef<FwNode>),
213}
214
215impl core::fmt::Display for FwNode {
216    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
217        // The logic here is the same as the one in lib/vsprintf.c
218        // (fwnode_full_name_string).
219
220        // SAFETY: `self.as_raw()` is valid by its type invariant.
221        let num_parents = unsafe { bindings::fwnode_count_parents(self.as_raw()) };
222
223        for depth in (0..=num_parents).rev() {
224            let fwnode = if depth == 0 {
225                Node::Borrowed(self)
226            } else {
227                // SAFETY: `self.as_raw()` is valid.
228                let ptr = unsafe { bindings::fwnode_get_nth_parent(self.as_raw(), depth) };
229                // SAFETY:
230                // - The depth passed to `fwnode_get_nth_parent` is
231                //   within the valid range, so the returned pointer is
232                //   not null.
233                // - The reference count was incremented by
234                //   `fwnode_get_nth_parent`.
235                // - That increment is relinquished to
236                //   `FwNode::from_raw`.
237                Node::Owned(unsafe { FwNode::from_raw(ptr) })
238            };
239            // Take a reference to the owned or borrowed `FwNode`.
240            let fwnode: &FwNode = match &fwnode {
241                Node::Borrowed(f) => f,
242                Node::Owned(f) => f,
243            };
244
245            // SAFETY: `fwnode` is valid by its type invariant.
246            let prefix = unsafe { bindings::fwnode_get_name_prefix(fwnode.as_raw()) };
247            if !prefix.is_null() {
248                // SAFETY: `fwnode_get_name_prefix` returns null or a
249                // valid C string.
250                let prefix = unsafe { CStr::from_char_ptr(prefix) };
251                write!(f, "{prefix}")?;
252            }
253            write!(f, "{}", fwnode.display_name())?;
254        }
255
256        Ok(())
257    }
258}
259
260/// Implemented for types that can be read as properties.
261///
262/// This is implemented for strings, integers and arrays of integers. It's used
263/// to make [`FwNode::property_read`] generic over the type of property being
264/// read. There are also two dedicated methods to read other types, because they
265/// require more specialized function signatures:
266/// - [`property_read_bool`](FwNode::property_read_bool)
267/// - [`property_read_array_vec`](FwNode::property_read_array_vec)
268///
269/// It must be public, because it appears in the signatures of other public
270/// functions, but its methods shouldn't be used outside the kernel crate.
271pub trait Property: Sized + Sealed {
272    /// Used to make [`FwNode::property_read`] generic.
273    fn read_from_fwnode_property(fwnode: &FwNode, name: &CStr) -> Result<Self>;
274}
275
276impl Sealed for CString {}
277
278impl Property for CString {
279    fn read_from_fwnode_property(fwnode: &FwNode, name: &CStr) -> Result<Self> {
280        let mut str: *mut u8 = ptr::null_mut();
281        let pstr: *mut _ = &mut str;
282
283        // SAFETY:
284        // - `name` is non-null and null-terminated.
285        // - `fwnode.as_raw` is valid because `fwnode` is valid.
286        let ret = unsafe {
287            bindings::fwnode_property_read_string(fwnode.as_raw(), name.as_char_ptr(), pstr.cast())
288        };
289        to_result(ret)?;
290
291        // SAFETY:
292        // - `pstr` is a valid pointer to a NUL-terminated C string.
293        // - It is valid for at least as long as `fwnode`, but it's only used
294        //   within the current function.
295        // - The memory it points to is not mutated during that time.
296        let str = unsafe { CStr::from_char_ptr(*pstr) };
297        Ok(str.try_into()?)
298    }
299}
300
301/// Implemented for all integers that can be read as properties.
302///
303/// This helper trait is needed on top of the existing [`Property`]
304/// trait to associate the integer types of various sizes with their
305/// corresponding `fwnode_property_read_*_array` functions.
306///
307/// It must be public, because it appears in the signatures of other public
308/// functions, but its methods shouldn't be used outside the kernel crate.
309pub trait PropertyInt: Copy + Sealed {
310    /// Reads a property array.
311    fn read_array_from_fwnode_property<'a>(
312        fwnode: &FwNode,
313        name: &CStr,
314        out: &'a mut [MaybeUninit<Self>],
315    ) -> Result<&'a mut [Self]>;
316
317    /// Reads the length of a property array.
318    fn read_array_len_from_fwnode_property(fwnode: &FwNode, name: &CStr) -> Result<usize>;
319}
320// This macro generates implementations of the traits `Property` and
321// `PropertyInt` for integers of various sizes. Its input is a list
322// of pairs separated by commas. The first element of the pair is the
323// type of the integer, the second one is the name of its corresponding
324// `fwnode_property_read_*_array` function.
325macro_rules! impl_property_for_int {
326    ($($int:ty: $f:ident),* $(,)?) => { $(
327        impl Sealed for $int {}
328        impl<const N: usize> Sealed for [$int; N] {}
329
330        impl PropertyInt for $int {
331            fn read_array_from_fwnode_property<'a>(
332                fwnode: &FwNode,
333                name: &CStr,
334                out: &'a mut [MaybeUninit<Self>],
335            ) -> Result<&'a mut [Self]> {
336                // SAFETY:
337                // - `fwnode`, `name` and `out` are all valid by their type
338                //   invariants.
339                // - `out.len()` is a valid bound for the memory pointed to by
340                //   `out.as_mut_ptr()`.
341                // CAST: It's ok to cast from `*mut MaybeUninit<$int>` to a
342                // `*mut $int` because they have the same memory layout.
343                let ret = unsafe {
344                    bindings::$f(
345                        fwnode.as_raw(),
346                        name.as_char_ptr(),
347                        out.as_mut_ptr().cast(),
348                        out.len(),
349                    )
350                };
351                to_result(ret)?;
352                // SAFETY: Transmuting from `&'a mut [MaybeUninit<Self>]` to
353                // `&'a mut [Self]` is sound, because the previous call to a
354                // `fwnode_property_read_*_array` function (which didn't fail)
355                // fully initialized the slice.
356                Ok(unsafe { core::mem::transmute::<&mut [MaybeUninit<Self>], &mut [Self]>(out) })
357            }
358
359            fn read_array_len_from_fwnode_property(fwnode: &FwNode, name: &CStr) -> Result<usize> {
360                // SAFETY:
361                // - `fwnode` and `name` are valid by their type invariants.
362                // - It's ok to pass a null pointer to the
363                //   `fwnode_property_read_*_array` functions if `nval` is zero.
364                //   This will return the length of the array.
365                let ret = unsafe {
366                    bindings::$f(
367                        fwnode.as_raw(),
368                        name.as_char_ptr(),
369                        ptr::null_mut(),
370                        0,
371                    )
372                };
373                to_result(ret)?;
374                Ok(ret as usize)
375            }
376        }
377
378        impl Property for $int {
379            fn read_from_fwnode_property(fwnode: &FwNode, name: &CStr) -> Result<Self> {
380                let val: [_; 1] = <[$int; 1]>::read_from_fwnode_property(fwnode, name)?;
381                Ok(val[0])
382            }
383        }
384
385        impl<const N: usize> Property for [$int; N] {
386            fn read_from_fwnode_property(fwnode: &FwNode, name: &CStr) -> Result<Self> {
387                let mut val: [MaybeUninit<$int>; N] = [const { MaybeUninit::uninit() }; N];
388
389                <$int>::read_array_from_fwnode_property(fwnode, name, &mut val)?;
390
391                // SAFETY: `val` is always initialized when
392                // `fwnode_property_read_*_array` is successful.
393                Ok(val.map(|v| unsafe { v.assume_init() }))
394            }
395        }
396    )* };
397}
398impl_property_for_int! {
399    u8: fwnode_property_read_u8_array,
400    u16: fwnode_property_read_u16_array,
401    u32: fwnode_property_read_u32_array,
402    u64: fwnode_property_read_u64_array,
403    i8: fwnode_property_read_u8_array,
404    i16: fwnode_property_read_u16_array,
405    i32: fwnode_property_read_u32_array,
406    i64: fwnode_property_read_u64_array,
407}
408
409/// A helper for reading device properties.
410///
411/// Use [`Self::required_by`] if a missing property is considered a bug and
412/// [`Self::optional`] otherwise.
413///
414/// For convenience, [`Self::or`] and [`Self::or_default`] are provided.
415pub struct PropertyGuard<'fwnode, 'name, T> {
416    /// The result of reading the property.
417    inner: Result<T>,
418    /// The fwnode of the property, used for logging in the "required" case.
419    fwnode: &'fwnode FwNode,
420    /// The name of the property, used for logging in the "required" case.
421    name: &'name CStr,
422}
423
424impl<T> PropertyGuard<'_, '_, T> {
425    /// Access the property, indicating it is required.
426    ///
427    /// If the property is not present, the error is automatically logged. If a
428    /// missing property is not an error, use [`Self::optional`] instead. The
429    /// device is required to associate the log with it.
430    pub fn required_by(self, dev: &super::Device) -> Result<T> {
431        if self.inner.is_err() {
432            dev_err!(
433                dev,
434                "{}: property '{}' is missing\n",
435                self.fwnode,
436                self.name
437            );
438        }
439        self.inner
440    }
441
442    /// Access the property, indicating it is optional.
443    ///
444    /// In contrast to [`Self::required_by`], no error message is logged if
445    /// the property is not present.
446    pub fn optional(self) -> Option<T> {
447        self.inner.ok()
448    }
449
450    /// Access the property or the specified default value.
451    ///
452    /// Do not pass a sentinel value as default to detect a missing property.
453    /// Use [`Self::required_by`] or [`Self::optional`] instead.
454    pub fn or(self, default: T) -> T {
455        self.inner.unwrap_or(default)
456    }
457}
458
459impl<T: Default> PropertyGuard<'_, '_, T> {
460    /// Access the property or a default value.
461    ///
462    /// Use [`Self::or`] to specify a custom default value.
463    pub fn or_default(self) -> T {
464        self.inner.unwrap_or_default()
465    }
466}