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}