// SPDX-License-Identifier: GPL-2.012//! Unified device property interface.3//!4//! C header: [`include/linux/property.h`](srctree/include/linux/property.h)56use core::{mem::MaybeUninit, ptr};78use super::private::Sealed;9use crate::{10alloc::KVec,11bindings,12error::{to_result, Result},13fmt,14prelude::*,15str::{CStr, CString},16types::{ARef, Opaque},17};1819/// A reference-counted fwnode_handle.20///21/// This structure represents the Rust abstraction for a22/// C `struct fwnode_handle`. This implementation abstracts the usage of an23/// already existing C `struct fwnode_handle` within Rust code that we get24/// passed from the C side.25///26/// # Invariants27///28/// A `FwNode` instance represents a valid `struct fwnode_handle` created by the29/// C portion of the kernel.30///31/// Instances of this type are always reference-counted, that is, a call to32/// `fwnode_handle_get` ensures that the allocation remains valid at least until33/// the matching call to `fwnode_handle_put`.34#[repr(transparent)]35pub struct FwNode(Opaque<bindings::fwnode_handle>);3637impl FwNode {38/// # Safety39///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 one43/// increment, callers must not use the underlying object anymore -- it is44/// only safe to do so via the newly created `ARef<FwNode>`.45unsafe 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 decremented52// elsewhere.53// CAST: It is safe to cast from a `*mut fwnode_handle` to54// `*mut FwNode`, because `FwNode` is defined as a55// `#[repr(transparent)]` wrapper around `fwnode_handle`.56unsafe { ARef::from_raw(ptr::NonNull::new_unchecked(raw.cast())) }57}5859/// Obtain the raw `struct fwnode_handle *`.60pub(crate) fn as_raw(&self) -> *mut bindings::fwnode_handle {61self.0.get()62}6364/// Returns `true` if `&self` is an OF node, `false` otherwise.65pub fn is_of_node(&self) -> bool {66// SAFETY: The type invariant of `Self` guarantees that `self.as_raw() is a pointer to a67// valid `struct fwnode_handle`.68unsafe { bindings::is_of_node(self.as_raw()) }69}7071/// Returns an object that implements [`Display`](fmt::Display) for72/// printing the name of a node.73///74/// This is an alternative to the default `Display` implementation, which75/// prints the full path.76pub fn display_name(&self) -> impl fmt::Display + '_ {77struct FwNodeDisplayName<'a>(&'a FwNode);7879impl fmt::Display for FwNodeDisplayName<'_> {80fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {81// SAFETY: `self` is valid by its type invariant.82let name = unsafe { bindings::fwnode_get_name(self.0.as_raw()) };83if name.is_null() {84return Ok(());85}86// SAFETY:87// - `fwnode_get_name` returns null or a valid C string.88// - `name` was checked to be non-null.89let name = unsafe { CStr::from_char_ptr(name) };90fmt::Display::fmt(name, f)91}92}9394FwNodeDisplayName(self)95}9697/// Checks if property is present or not.98pub fn property_present(&self, name: &CStr) -> bool {99// SAFETY: By the invariant of `CStr`, `name` is null-terminated.100unsafe { bindings::fwnode_property_present(self.as_raw().cast_const(), name.as_char_ptr()) }101}102103/// Returns firmware property `name` boolean value.104pub 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.108unsafe { bindings::fwnode_property_read_bool(self.as_raw(), name.as_char_ptr()) }109}110111/// Returns the index of matching string `match_str` for firmware string112/// property `name`.113pub 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.117let ret = unsafe {118bindings::fwnode_property_match_string(119self.as_raw(),120name.as_char_ptr(),121match_str.as_char_ptr(),122)123};124to_result(ret)?;125Ok(ret as usize)126}127128/// Returns firmware property `name` integer array values in a [`KVec`].129pub fn property_read_array_vec<'fwnode, 'name, T: PropertyInt>(130&'fwnode self,131name: &'name CStr,132len: usize,133) -> Result<PropertyGuard<'fwnode, 'name, KVec<T>>> {134let mut val: KVec<T> = KVec::with_capacity(len, GFP_KERNEL)?;135136let res = T::read_array_from_fwnode_property(self, name, val.spare_capacity_mut());137let res = match res {138Ok(_) => {139// SAFETY:140// - `len` is equal to `val.capacity - val.len`, because141// `val.capacity` is `len` and `val.len` is zero.142// - All elements within the interval [`0`, `len`) were initialized143// by `read_array_from_fwnode_property`.144unsafe { val.inc_len(len) }145Ok(val)146}147Err(e) => Err(e),148};149Ok(PropertyGuard {150inner: res,151fwnode: self,152name,153})154}155156/// Returns integer array length for firmware property `name`.157pub fn property_count_elem<T: PropertyInt>(&self, name: &CStr) -> Result<usize> {158T::read_array_len_from_fwnode_property(self, name)159}160161/// Returns the value of firmware property `name`.162///163/// This method is generic over the type of value to read. The types that164/// can be read are strings, integers and arrays of integers.165///166/// Reading a [`KVec`] of integers is done with the separate167/// method [`Self::property_read_array_vec`], because it takes an168/// additional `len` argument.169///170/// Reading a boolean is done with the separate method171/// [`Self::property_read_bool`], because this operation is infallible.172///173/// For more precise documentation about what types can be read, see174/// the [implementors of Property][Property#implementors] and [its175/// implementations on foreign types][Property#foreign-impls].176///177/// # Examples178///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/// ```190pub fn property_read<'fwnode, 'name, T: Property>(191&'fwnode self,192name: &'name CStr,193) -> PropertyGuard<'fwnode, 'name, T> {194PropertyGuard {195inner: T::read_from_fwnode_property(self, name),196fwnode: self,197name,198}199}200201/// Returns first matching named child node handle.202pub fn get_child_by_name(&self, name: &CStr) -> Option<ARef<Self>> {203// SAFETY: `self` and `name` are valid by their type invariants.204let child =205unsafe { bindings::fwnode_get_named_child_node(self.as_raw(), name.as_char_ptr()) };206if child.is_null() {207return None;208}209// SAFETY:210// - `fwnode_get_named_child_node` returns a pointer with its refcount211// incremented.212// - That increment is relinquished, i.e. the underlying object is not213// used anymore except via the newly created `ARef`.214Some(unsafe { Self::from_raw(child) })215}216217/// Returns an iterator over a node's children.218pub fn children<'a>(&'a self) -> impl Iterator<Item = ARef<FwNode>> + 'a {219let mut prev: Option<ARef<FwNode>> = None;220221core::iter::from_fn(move || {222let prev_ptr = match prev.take() {223None => ptr::null_mut(),224Some(prev) => {225// We will pass `prev` to `fwnode_get_next_child_node`,226// which decrements its refcount, so we use227// `ARef::into_raw` to avoid decrementing the refcount228// twice.229let prev = ARef::into_raw(prev);230prev.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 to236// getting the first child. Otherwise, `prev_ptr` is valid, as it237// 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. the240// underlying object won't be used anymore.241let next = unsafe { bindings::fwnode_get_next_child_node(self.as_raw(), prev_ptr) };242if next.is_null() {243return None;244}245// SAFETY:246// - `next` is valid because `fwnode_get_next_child_node` returns a247// pointer with its refcount incremented.248// - That increment is relinquished, i.e. the underlying object249// won't be used anymore, except via the newly created250// `ARef<Self>`.251let next = unsafe { FwNode::from_raw(next) };252prev = Some(next.clone());253Some(next)254})255}256257/// Finds a reference with arguments.258pub fn property_get_reference_args(259&self,260prop: &CStr,261nargs: NArgs<'_>,262index: u32,263) -> Result<FwNodeReferenceArgs> {264let mut out_args = FwNodeReferenceArgs::default();265266let (nargs_prop, nargs) = match nargs {267NArgs::Prop(nargs_prop) => (nargs_prop.as_char_ptr(), 0),268NArgs::N(nargs) => (ptr::null(), nargs),269};270271// 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 it281// initializes at least as many elements in `args`.282let ret = unsafe {283bindings::fwnode_property_get_reference_args(284self.0.get(),285prop.as_char_ptr(),286nargs_prop,287nargs,288index,289&mut out_args.0,290)291};292to_result(ret)?;293294Ok(out_args)295}296}297298/// The number of arguments to request [`FwNodeReferenceArgs`].299pub enum NArgs<'a> {300/// The name of the property of the reference indicating the number of301/// arguments.302Prop(&'a CStr),303/// The known number of arguments.304N(u32),305}306307/// The return value of [`FwNode::property_get_reference_args`].308///309/// This structure represents the Rust abstraction for a C310/// `struct fwnode_reference_args` which was initialized by the C side.311///312/// # Invariants313///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 indicated317/// by the field `nargs`.318#[repr(transparent)]319#[derive(Default)]320pub struct FwNodeReferenceArgs(bindings::fwnode_reference_args);321322impl Drop for FwNodeReferenceArgs {323fn drop(&mut self) {324if !self.0.fwnode.is_null() {325// SAFETY:326// - By the type invariants of `FwNodeReferenceArgs`, its field327// `fwnode` owns an increment of its refcount.328// - That increment is relinquished. The underlying object won't be329// used anymore because we are dropping it.330let _ = unsafe { FwNode::from_raw(self.0.fwnode) };331}332}333}334335impl FwNodeReferenceArgs {336/// Returns the slice of reference arguments.337pub 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.340unsafe { core::slice::from_raw_parts(self.0.args.as_ptr(), self.0.nargs as usize) }341}342343/// Returns the number of reference arguments.344pub fn len(&self) -> usize {345self.0.nargs as usize346}347348/// Returns `true` if there are no reference arguments.349pub fn is_empty(&self) -> bool {350self.0.nargs == 0351}352}353354impl fmt::Debug for FwNodeReferenceArgs {355fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {356write!(f, "{:?}", self.as_slice())357}358}359360// SAFETY: Instances of `FwNode` are always reference-counted.361unsafe impl crate::types::AlwaysRefCounted for FwNode {362fn inc_ref(&self) {363// SAFETY: The existence of a shared reference guarantees that the364// refcount is non-zero.365unsafe { bindings::fwnode_handle_get(self.as_raw()) };366}367368unsafe fn dec_ref(obj: ptr::NonNull<Self>) {369// SAFETY: The safety requirements guarantee that the refcount is370// non-zero.371unsafe { bindings::fwnode_handle_put(obj.cast().as_ptr()) }372}373}374375enum Node<'a> {376Borrowed(&'a FwNode),377Owned(ARef<FwNode>),378}379380impl fmt::Display for FwNode {381fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {382// The logic here is the same as the one in lib/vsprintf.c383// (fwnode_full_name_string).384385// SAFETY: `self.as_raw()` is valid by its type invariant.386let num_parents = unsafe { bindings::fwnode_count_parents(self.as_raw()) };387388for depth in (0..=num_parents).rev() {389let fwnode = if depth == 0 {390Node::Borrowed(self)391} else {392// SAFETY: `self.as_raw()` is valid.393let ptr = unsafe { bindings::fwnode_get_nth_parent(self.as_raw(), depth) };394// SAFETY:395// - The depth passed to `fwnode_get_nth_parent` is396// within the valid range, so the returned pointer is397// not null.398// - The reference count was incremented by399// `fwnode_get_nth_parent`.400// - That increment is relinquished to401// `FwNode::from_raw`.402Node::Owned(unsafe { FwNode::from_raw(ptr) })403};404// Take a reference to the owned or borrowed `FwNode`.405let fwnode: &FwNode = match &fwnode {406Node::Borrowed(f) => f,407Node::Owned(f) => f,408};409410// SAFETY: `fwnode` is valid by its type invariant.411let prefix = unsafe { bindings::fwnode_get_name_prefix(fwnode.as_raw()) };412if !prefix.is_null() {413// SAFETY: `fwnode_get_name_prefix` returns null or a414// valid C string.415let prefix = unsafe { CStr::from_char_ptr(prefix) };416fmt::Display::fmt(prefix, f)?;417}418fmt::Display::fmt(&fwnode.display_name(), f)?;419}420421Ok(())422}423}424425/// Implemented for types that can be read as properties.426///427/// This is implemented for strings, integers and arrays of integers. It's used428/// to make [`FwNode::property_read`] generic over the type of property being429/// read. There are also two dedicated methods to read other types, because they430/// 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 public435/// 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.438fn read_from_fwnode_property(fwnode: &FwNode, name: &CStr) -> Result<Self>;439}440441impl Sealed for CString {}442443impl Property for CString {444fn read_from_fwnode_property(fwnode: &FwNode, name: &CStr) -> Result<Self> {445let mut str: *mut u8 = ptr::null_mut();446let pstr: *mut _ = &mut str;447448// SAFETY:449// - `name` is non-null and null-terminated.450// - `fwnode.as_raw` is valid because `fwnode` is valid.451let ret = unsafe {452bindings::fwnode_property_read_string(fwnode.as_raw(), name.as_char_ptr(), pstr.cast())453};454to_result(ret)?;455456// 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 used459// within the current function.460// - The memory it points to is not mutated during that time.461let str = unsafe { CStr::from_char_ptr(*pstr) };462Ok(str.try_into()?)463}464}465466/// 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 their470/// corresponding `fwnode_property_read_*_array` functions.471///472/// It must be public, because it appears in the signatures of other public473/// functions, but its methods shouldn't be used outside the kernel crate.474pub trait PropertyInt: Copy + Sealed {475/// Reads a property array.476fn read_array_from_fwnode_property<'a>(477fwnode: &FwNode,478name: &CStr,479out: &'a mut [MaybeUninit<Self>],480) -> Result<&'a mut [Self]>;481482/// Reads the length of a property array.483fn read_array_len_from_fwnode_property(fwnode: &FwNode, name: &CStr) -> Result<usize>;484}485// This macro generates implementations of the traits `Property` and486// `PropertyInt` for integers of various sizes. Its input is a list487// of pairs separated by commas. The first element of the pair is the488// type of the integer, the second one is the name of its corresponding489// `fwnode_property_read_*_array` function.490macro_rules! impl_property_for_int {491($($int:ty: $f:ident),* $(,)?) => { $(492impl Sealed for $int {}493impl<const N: usize> Sealed for [$int; N] {}494495impl PropertyInt for $int {496fn read_array_from_fwnode_property<'a>(497fwnode: &FwNode,498name: &CStr,499out: &'a mut [MaybeUninit<Self>],500) -> Result<&'a mut [Self]> {501// SAFETY:502// - `fwnode`, `name` and `out` are all valid by their type503// invariants.504// - `out.len()` is a valid bound for the memory pointed to by505// `out.as_mut_ptr()`.506// CAST: It's ok to cast from `*mut MaybeUninit<$int>` to a507// `*mut $int` because they have the same memory layout.508let ret = unsafe {509bindings::$f(510fwnode.as_raw(),511name.as_char_ptr(),512out.as_mut_ptr().cast(),513out.len(),514)515};516to_result(ret)?;517// SAFETY: Transmuting from `&'a mut [MaybeUninit<Self>]` to518// `&'a mut [Self]` is sound, because the previous call to a519// `fwnode_property_read_*_array` function (which didn't fail)520// fully initialized the slice.521Ok(unsafe { core::mem::transmute::<&mut [MaybeUninit<Self>], &mut [Self]>(out) })522}523524fn 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 the528// `fwnode_property_read_*_array` functions if `nval` is zero.529// This will return the length of the array.530let ret = unsafe {531bindings::$f(532fwnode.as_raw(),533name.as_char_ptr(),534ptr::null_mut(),5350,536)537};538to_result(ret)?;539Ok(ret as usize)540}541}542543impl Property for $int {544fn read_from_fwnode_property(fwnode: &FwNode, name: &CStr) -> Result<Self> {545let val: [_; 1] = <[$int; 1]>::read_from_fwnode_property(fwnode, name)?;546Ok(val[0])547}548}549550impl<const N: usize> Property for [$int; N] {551fn read_from_fwnode_property(fwnode: &FwNode, name: &CStr) -> Result<Self> {552let mut val: [MaybeUninit<$int>; N] = [const { MaybeUninit::uninit() }; N];553554<$int>::read_array_from_fwnode_property(fwnode, name, &mut val)?;555556// SAFETY: `val` is always initialized when557// `fwnode_property_read_*_array` is successful.558Ok(val.map(|v| unsafe { v.assume_init() }))559}560}561)* };562}563impl_property_for_int! {564u8: fwnode_property_read_u8_array,565u16: fwnode_property_read_u16_array,566u32: fwnode_property_read_u32_array,567u64: fwnode_property_read_u64_array,568i8: fwnode_property_read_u8_array,569i16: fwnode_property_read_u16_array,570i32: fwnode_property_read_u32_array,571i64: fwnode_property_read_u64_array,572}573574/// A helper for reading device properties.575///576/// Use [`Self::required_by`] if a missing property is considered a bug and577/// [`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.582inner: Result<T>,583/// The fwnode of the property, used for logging in the "required" case.584fwnode: &'fwnode FwNode,585/// The name of the property, used for logging in the "required" case.586name: &'name CStr,587}588589impl<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 a593/// missing property is not an error, use [`Self::optional`] instead. The594/// device is required to associate the log with it.595pub fn required_by(self, dev: &super::Device) -> Result<T> {596if self.inner.is_err() {597dev_err!(598dev,599"{}: property '{}' is missing\n",600self.fwnode,601self.name602);603}604self.inner605}606607/// Access the property, indicating it is optional.608///609/// In contrast to [`Self::required_by`], no error message is logged if610/// the property is not present.611pub fn optional(self) -> Option<T> {612self.inner.ok()613}614615/// 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.619pub fn or(self, default: T) -> T {620self.inner.unwrap_or(default)621}622}623624impl<T: Default> PropertyGuard<'_, '_, T> {625/// Access the property or a default value.626///627/// Use [`Self::or`] to specify a custom default value.628pub fn or_default(self) -> T {629self.inner.unwrap_or_default()630}631}632633634