Something went wrong. Try again.
Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634// SPDX-License-Identifier: GPL-2.0
//! Unified device property interface.//!//! C header: [`include/linux/property.h`](srctree/include/linux/property.h)
use core::{mem::MaybeUninit, ptr};
use super::private::Sealed;use crate::{ alloc::KVec, bindings, error::{to_result, Result}, fmt, prelude::*, str::{CStr, CString}, sync::aref::ARef, types::Opaque,};
/// A reference-counted fwnode_handle.////// This structure represents the Rust abstraction for a/// C `struct fwnode_handle`. This implementation abstracts the usage of an/// already existing C `struct fwnode_handle` within Rust code that we get/// passed from the C side.////// # Invariants////// A `FwNode` instance represents a valid `struct fwnode_handle` created by the/// C portion of the kernel.////// Instances of this type are always reference-counted, that is, a call to/// `fwnode_handle_get` ensures that the allocation remains valid at least until/// the matching call to `fwnode_handle_put`.#[repr(transparent)]pub struct FwNode(Opaque<bindings::fwnode_handle>);
impl FwNode { /// # Safety /// /// Callers must ensure that: /// - The reference count was incremented at least once. /// - They relinquish that increment. That is, if there is only one /// increment, callers must not use the underlying object anymore -- it is /// only safe to do so via the newly created `ARef<FwNode>`. unsafe fn from_raw(raw: *mut bindings::fwnode_handle) -> ARef<Self> { // SAFETY: As per the safety requirements of this function: // - `NonNull::new_unchecked`: // - `raw` is not null. // - `ARef::from_raw`: // - `raw` has an incremented refcount. // - that increment is relinquished, i.e. it won't be decremented // elsewhere. // CAST: It is safe to cast from a `*mut fwnode_handle` to // `*mut FwNode`, because `FwNode` is defined as a // `#[repr(transparent)]` wrapper around `fwnode_handle`. unsafe { ARef::from_raw(ptr::NonNull::new_unchecked(raw.cast())) } }
/// Obtain the raw `struct fwnode_handle *`. pub(crate) fn as_raw(&self) -> *mut bindings::fwnode_handle { self.0.get() }
/// Returns `true` if `&self` is an OF node, `false` otherwise. pub fn is_of_node(&self) -> bool { // SAFETY: The type invariant of `Self` guarantees that `self.as_raw() is a pointer to a // valid `struct fwnode_handle`. unsafe { bindings::is_of_node(self.as_raw()) } }
/// Returns an object that implements [`Display`](fmt::Display) for /// printing the name of a node. /// /// This is an alternative to the default `Display` implementation, which /// prints the full path. pub fn display_name(&self) -> impl fmt::Display + '_ { struct FwNodeDisplayName<'a>(&'a FwNode);
impl fmt::Display for FwNodeDisplayName<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { // SAFETY: `self` is valid by its type invariant. let name = unsafe { bindings::fwnode_get_name(self.0.as_raw()) }; if name.is_null() { return Ok(()); } // SAFETY: // - `fwnode_get_name` returns null or a valid C string. // - `name` was checked to be non-null. let name = unsafe { CStr::from_char_ptr(name) }; fmt::Display::fmt(name, f) } }
FwNodeDisplayName(self) }
/// Checks if property is present or not. pub fn property_present(&self, name: &CStr) -> bool { // SAFETY: By the invariant of `CStr`, `name` is null-terminated. unsafe { bindings::fwnode_property_present(self.as_raw().cast_const(), name.as_char_ptr()) } }
/// Returns firmware property `name` boolean value. pub fn property_read_bool(&self, name: &CStr) -> bool { // SAFETY: // - `name` is non-null and null-terminated. // - `self.as_raw()` is valid because `self` is valid. unsafe { bindings::fwnode_property_read_bool(self.as_raw(), name.as_char_ptr()) } }
/// Returns the index of matching string `match_str` for firmware string /// property `name`. pub fn property_match_string(&self, name: &CStr, match_str: &CStr) -> Result<usize> { // SAFETY: // - `name` and `match_str` are non-null and null-terminated. // - `self.as_raw` is valid because `self` is valid. let ret = unsafe { bindings::fwnode_property_match_string( self.as_raw(), name.as_char_ptr(), match_str.as_char_ptr(), ) }; to_result(ret)?; Ok(ret as usize) }
/// Returns firmware property `name` integer array values in a [`KVec`]. pub fn property_read_array_vec<'fwnode, 'name, T: PropertyInt>( &'fwnode self, name: &'name CStr, len: usize, ) -> Result<PropertyGuard<'fwnode, 'name, KVec<T>>> { let mut val: KVec<T> = KVec::with_capacity(len, GFP_KERNEL)?;
let res = T::read_array_from_fwnode_property(self, name, val.spare_capacity_mut()); let res = match res { Ok(_) => { // SAFETY: // - `len` is equal to `val.capacity - val.len`, because // `val.capacity` is `len` and `val.len` is zero. // - All elements within the interval [`0`, `len`) were initialized // by `read_array_from_fwnode_property`. unsafe { val.inc_len(len) } Ok(val) } Err(e) => Err(e), }; Ok(PropertyGuard { inner: res, fwnode: self, name, }) }
/// Returns integer array length for firmware property `name`. pub fn property_count_elem<T: PropertyInt>(&self, name: &CStr) -> Result<usize> { T::read_array_len_from_fwnode_property(self, name) }
/// Returns the value of firmware property `name`. /// /// This method is generic over the type of value to read. The types that /// can be read are strings, integers and arrays of integers. /// /// Reading a [`KVec`] of integers is done with the separate /// method [`Self::property_read_array_vec`], because it takes an /// additional `len` argument. /// /// Reading a boolean is done with the separate method /// [`Self::property_read_bool`], because this operation is infallible. /// /// For more precise documentation about what types can be read, see /// the [implementors of Property][Property#implementors] and [its /// implementations on foreign types][Property#foreign-impls]. /// /// # Examples /// /// ``` /// # use kernel::{device::{Device, property::FwNode}, str::CString}; /// fn examples(dev: &Device) -> Result { /// let fwnode = dev.fwnode().ok_or(ENOENT)?; /// let b: u32 = fwnode.property_read(c"some-number").required_by(dev)?; /// if let Some(s) = fwnode.property_read::<CString>(c"some-str").optional() { /// // ... /// } /// Ok(()) /// } /// ``` pub fn property_read<'fwnode, 'name, T: Property>( &'fwnode self, name: &'name CStr, ) -> PropertyGuard<'fwnode, 'name, T> { PropertyGuard { inner: T::read_from_fwnode_property(self, name), fwnode: self, name, } }
/// Returns first matching named child node handle. pub fn get_child_by_name(&self, name: &CStr) -> Option<ARef<Self>> { // SAFETY: `self` and `name` are valid by their type invariants. let child = unsafe { bindings::fwnode_get_named_child_node(self.as_raw(), name.as_char_ptr()) }; if child.is_null() { return None; } // SAFETY: // - `fwnode_get_named_child_node` returns a pointer with its refcount // incremented. // - That increment is relinquished, i.e. the underlying object is not // used anymore except via the newly created `ARef`. Some(unsafe { Self::from_raw(child) }) }
/// Returns an iterator over a node's children. pub fn children<'a>(&'a self) -> impl Iterator<Item = ARef<FwNode>> + 'a { let mut prev: Option<ARef<FwNode>> = None;
core::iter::from_fn(move || { let prev_ptr = match prev.take() { None => ptr::null_mut(), Some(prev) => { // We will pass `prev` to `fwnode_get_next_child_node`, // which decrements its refcount, so we use // `ARef::into_raw` to avoid decrementing the refcount // twice. let prev = ARef::into_raw(prev); prev.as_ptr().cast() } }; // SAFETY: // - `self.as_raw()` is valid by its type invariant. // - `prev_ptr` may be null, which is allowed and corresponds to // getting the first child. Otherwise, `prev_ptr` is valid, as it // is the stored return value from the previous invocation. // - `prev_ptr` has its refount incremented. // - The increment of `prev_ptr` is relinquished, i.e. the // underlying object won't be used anymore. let next = unsafe { bindings::fwnode_get_next_child_node(self.as_raw(), prev_ptr) }; if next.is_null() { return None; } // SAFETY: // - `next` is valid because `fwnode_get_next_child_node` returns a // pointer with its refcount incremented. // - That increment is relinquished, i.e. the underlying object // won't be used anymore, except via the newly created // `ARef<Self>`. let next = unsafe { FwNode::from_raw(next) }; prev = Some(next.clone()); Some(next) }) }
/// Finds a reference with arguments. pub fn property_get_reference_args( &self, prop: &CStr, nargs: NArgs<'_>, index: u32, ) -> Result<FwNodeReferenceArgs> { let mut out_args = FwNodeReferenceArgs::default();
let (nargs_prop, nargs) = match nargs { NArgs::Prop(nargs_prop) => (nargs_prop.as_char_ptr(), 0), NArgs::N(nargs) => (ptr::null(), nargs), };
// SAFETY: // - `self.0.get()` is valid. // - `prop.as_char_ptr()` is valid and zero-terminated. // - `nargs_prop` is valid and zero-terminated if `nargs` // is zero, otherwise it is allowed to be a null-pointer. // - The function upholds the type invariants of `out_args`, // namely: // - It may fill the field `fwnode` with a valid pointer, // in which case its refcount is incremented. // - It may modify the field `nargs`, in which case it // initializes at least as many elements in `args`. let ret = unsafe { bindings::fwnode_property_get_reference_args( self.0.get(), prop.as_char_ptr(), nargs_prop, nargs, index, &mut out_args.0, ) }; to_result(ret)?;
Ok(out_args) }}
/// The number of arguments to request [`FwNodeReferenceArgs`].pub enum NArgs<'a> { /// The name of the property of the reference indicating the number of /// arguments. Prop(&'a CStr), /// The known number of arguments. N(u32),}
/// The return value of [`FwNode::property_get_reference_args`].////// This structure represents the Rust abstraction for a C/// `struct fwnode_reference_args` which was initialized by the C side.////// # Invariants////// If the field `fwnode` is valid, it owns an increment of its refcount.////// The field `args` contains at least as many initialized elements as indicated/// by the field `nargs`.#[repr(transparent)]#[derive(Default)]pub struct FwNodeReferenceArgs(bindings::fwnode_reference_args);
impl Drop for FwNodeReferenceArgs { fn drop(&mut self) { if !self.0.fwnode.is_null() { // SAFETY: // - By the type invariants of `FwNodeReferenceArgs`, its field // `fwnode` owns an increment of its refcount. // - That increment is relinquished. The underlying object won't be // used anymore because we are dropping it. let _ = unsafe { FwNode::from_raw(self.0.fwnode) }; } }}
impl FwNodeReferenceArgs { /// Returns the slice of reference arguments. pub fn as_slice(&self) -> &[u64] { // SAFETY: As per the safety invariant of `FwNodeReferenceArgs`, `nargs` // is the minimum number of elements in `args` that is valid. unsafe { core::slice::from_raw_parts(self.0.args.as_ptr(), self.0.nargs as usize) } }
/// Returns the number of reference arguments. pub fn len(&self) -> usize { self.0.nargs as usize }
/// Returns `true` if there are no reference arguments. pub fn is_empty(&self) -> bool { self.0.nargs == 0 }}
impl fmt::Debug for FwNodeReferenceArgs { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{:?}", self.as_slice()) }}
// SAFETY: Instances of `FwNode` are always reference-counted.unsafe impl crate::sync::aref::AlwaysRefCounted for FwNode { fn inc_ref(&self) { // SAFETY: The existence of a shared reference guarantees that the // refcount is non-zero. unsafe { bindings::fwnode_handle_get(self.as_raw()) }; }
unsafe fn dec_ref(obj: ptr::NonNull<Self>) { // SAFETY: The safety requirements guarantee that the refcount is // non-zero. unsafe { bindings::fwnode_handle_put(obj.cast().as_ptr()) } }}
enum Node<'a> { Borrowed(&'a FwNode), Owned(ARef<FwNode>),}
impl fmt::Display for FwNode { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { // The logic here is the same as the one in lib/vsprintf.c // (fwnode_full_name_string).
// SAFETY: `self.as_raw()` is valid by its type invariant. let num_parents = unsafe { bindings::fwnode_count_parents(self.as_raw()) };
for depth in (0..=num_parents).rev() { let fwnode = if depth == 0 { Node::Borrowed(self) } else { // SAFETY: `self.as_raw()` is valid. let ptr = unsafe { bindings::fwnode_get_nth_parent(self.as_raw(), depth) }; // SAFETY: // - The depth passed to `fwnode_get_nth_parent` is // within the valid range, so the returned pointer is // not null. // - The reference count was incremented by // `fwnode_get_nth_parent`. // - That increment is relinquished to // `FwNode::from_raw`. Node::Owned(unsafe { FwNode::from_raw(ptr) }) }; // Take a reference to the owned or borrowed `FwNode`. let fwnode: &FwNode = match &fwnode { Node::Borrowed(f) => f, Node::Owned(f) => f, };
// SAFETY: `fwnode` is valid by its type invariant. let prefix = unsafe { bindings::fwnode_get_name_prefix(fwnode.as_raw()) }; if !prefix.is_null() { // SAFETY: `fwnode_get_name_prefix` returns null or a // valid C string. let prefix = unsafe { CStr::from_char_ptr(prefix) }; fmt::Display::fmt(prefix, f)?; } fmt::Display::fmt(&fwnode.display_name(), f)?; }
Ok(()) }}
/// Implemented for types that can be read as properties.////// This is implemented for strings, integers and arrays of integers. It's used/// to make [`FwNode::property_read`] generic over the type of property being/// read. There are also two dedicated methods to read other types, because they/// require more specialized function signatures:/// - [`property_read_bool`](FwNode::property_read_bool)/// - [`property_read_array_vec`](FwNode::property_read_array_vec)////// It must be public, because it appears in the signatures of other public/// functions, but its methods shouldn't be used outside the kernel crate.pub trait Property: Sized + Sealed { /// Used to make [`FwNode::property_read`] generic. fn read_from_fwnode_property(fwnode: &FwNode, name: &CStr) -> Result<Self>;}
impl Sealed for CString {}
impl Property for CString { fn read_from_fwnode_property(fwnode: &FwNode, name: &CStr) -> Result<Self> { let mut str: *mut u8 = ptr::null_mut(); let pstr: *mut _ = &mut str;
// SAFETY: // - `name` is non-null and null-terminated. // - `fwnode.as_raw` is valid because `fwnode` is valid. let ret = unsafe { bindings::fwnode_property_read_string(fwnode.as_raw(), name.as_char_ptr(), pstr.cast()) }; to_result(ret)?;
// SAFETY: // - `pstr` is a valid pointer to a NUL-terminated C string. // - It is valid for at least as long as `fwnode`, but it's only used // within the current function. // - The memory it points to is not mutated during that time. let str = unsafe { CStr::from_char_ptr(*pstr) }; Ok(str.try_into()?) }}
/// Implemented for all integers that can be read as properties.////// This helper trait is needed on top of the existing [`Property`]/// trait to associate the integer types of various sizes with their/// corresponding `fwnode_property_read_*_array` functions.////// It must be public, because it appears in the signatures of other public/// functions, but its methods shouldn't be used outside the kernel crate.pub trait PropertyInt: Copy + Sealed { /// Reads a property array. fn read_array_from_fwnode_property<'a>( fwnode: &FwNode, name: &CStr, out: &'a mut [MaybeUninit<Self>], ) -> Result<&'a mut [Self]>;
/// Reads the length of a property array. fn read_array_len_from_fwnode_property(fwnode: &FwNode, name: &CStr) -> Result<usize>;}// This macro generates implementations of the traits `Property` and// `PropertyInt` for integers of various sizes. Its input is a list// of pairs separated by commas. The first element of the pair is the// type of the integer, the second one is the name of its corresponding// `fwnode_property_read_*_array` function.macro_rules! impl_property_for_int { ($($int:ty: $f:ident),* $(,)?) => { $( impl Sealed for $int {} impl<const N: usize> Sealed for [$int; N] {}
impl PropertyInt for $int { fn read_array_from_fwnode_property<'a>( fwnode: &FwNode, name: &CStr, out: &'a mut [MaybeUninit<Self>], ) -> Result<&'a mut [Self]> { // SAFETY: // - `fwnode`, `name` and `out` are all valid by their type // invariants. // - `out.len()` is a valid bound for the memory pointed to by // `out.as_mut_ptr()`. // CAST: It's ok to cast from `*mut MaybeUninit<$int>` to a // `*mut $int` because they have the same memory layout. let ret = unsafe { bindings::$f( fwnode.as_raw(), name.as_char_ptr(), out.as_mut_ptr().cast(), out.len(), ) }; to_result(ret)?; // SAFETY: Transmuting from `&'a mut [MaybeUninit<Self>]` to // `&'a mut [Self]` is sound, because the previous call to a // `fwnode_property_read_*_array` function (which didn't fail) // fully initialized the slice. Ok(unsafe { core::mem::transmute::<&mut [MaybeUninit<Self>], &mut [Self]>(out) }) }
fn read_array_len_from_fwnode_property(fwnode: &FwNode, name: &CStr) -> Result<usize> { // SAFETY: // - `fwnode` and `name` are valid by their type invariants. // - It's ok to pass a null pointer to the // `fwnode_property_read_*_array` functions if `nval` is zero. // This will return the length of the array. let ret = unsafe { bindings::$f( fwnode.as_raw(), name.as_char_ptr(), ptr::null_mut(), 0, ) }; to_result(ret)?; Ok(ret as usize) } }
impl Property for $int { fn read_from_fwnode_property(fwnode: &FwNode, name: &CStr) -> Result<Self> { let val: [_; 1] = <[$int; 1]>::read_from_fwnode_property(fwnode, name)?; Ok(val[0]) } }
impl<const N: usize> Property for [$int; N] { fn read_from_fwnode_property(fwnode: &FwNode, name: &CStr) -> Result<Self> { let mut val: [MaybeUninit<$int>; N] = [const { MaybeUninit::uninit() }; N];
<$int>::read_array_from_fwnode_property(fwnode, name, &mut val)?;
// SAFETY: `val` is always initialized when // `fwnode_property_read_*_array` is successful. Ok(val.map(|v| unsafe { v.assume_init() })) } } )* };}impl_property_for_int! { u8: fwnode_property_read_u8_array, u16: fwnode_property_read_u16_array, u32: fwnode_property_read_u32_array, u64: fwnode_property_read_u64_array, i8: fwnode_property_read_u8_array, i16: fwnode_property_read_u16_array, i32: fwnode_property_read_u32_array, i64: fwnode_property_read_u64_array,}
/// A helper for reading device properties.////// Use [`Self::required_by`] if a missing property is considered a bug and/// [`Self::optional`] otherwise.////// For convenience, [`Self::or`] and [`Self::or_default`] are provided.pub struct PropertyGuard<'fwnode, 'name, T> { /// The result of reading the property. inner: Result<T>, /// The fwnode of the property, used for logging in the "required" case. fwnode: &'fwnode FwNode, /// The name of the property, used for logging in the "required" case. name: &'name CStr,}
impl<T> PropertyGuard<'_, '_, T> { /// Access the property, indicating it is required. /// /// If the property is not present, the error is automatically logged. If a /// missing property is not an error, use [`Self::optional`] instead. The /// device is required to associate the log with it. pub fn required_by(self, dev: &super::Device) -> Result<T> { if self.inner.is_err() { dev_err!( dev, "{}: property '{}' is missing\n", self.fwnode, self.name ); } self.inner }
/// Access the property, indicating it is optional. /// /// In contrast to [`Self::required_by`], no error message is logged if /// the property is not present. pub fn optional(self) -> Option<T> { self.inner.ok() }
/// Access the property or the specified default value. /// /// Do not pass a sentinel value as default to detect a missing property. /// Use [`Self::required_by`] or [`Self::optional`] instead. pub fn or(self, default: T) -> T { self.inner.unwrap_or(default) }}
impl<T: Default> PropertyGuard<'_, '_, T> { /// Access the property or a default value. /// /// Use [`Self::or`] to specify a custom default value. pub fn or_default(self) -> T { self.inner.unwrap_or_default() }}