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}