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 7 use core::{mem::MaybeUninit, ptr}; 8 9 use super::private::Sealed; 10 use 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)] 35 pub struct FwNode(Opaque<bindings::fwnode_handle>); 36 37 impl 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>`. from_raw(raw: *mut bindings::fwnode_handle) -> ARef<Self>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 *`. as_raw(&self) -> *mut bindings::fwnode_handle60 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. is_of_node(&self) -> bool65 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. display_name(&self) -> impl core::fmt::Display + '_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. property_present(&self, name: &CStr) -> bool98 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. property_read_bool(&self, name: &CStr) -> bool104 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`. property_match_string(&self, name: &CStr, match_str: &CStr) -> Result<usize>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`]. property_read_array_vec<'fwnode, 'name, T: PropertyInt>( &'fwnode self, name: &'name CStr, len: usize, ) -> Result<PropertyGuard<'fwnode, 'name, KVec<T>>>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`. property_count_elem<T: PropertyInt>(&self, name: &CStr) -> Result<usize>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 /// ``` property_read<'fwnode, 'name, T: Property>( &'fwnode self, name: &'name CStr, ) -> PropertyGuard<'fwnode, 'name, T>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. get_child_by_name(&self, name: &CStr) -> Option<ARef<Self>>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. children<'a>(&'a self) -> impl Iterator<Item = ARef<FwNode>> + 'a218 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. property_get_reference_args( &self, prop: &CStr, nargs: NArgs<'_>, index: u32, ) -> Result<FwNodeReferenceArgs>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`]. 299 pub 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)] 320 pub struct FwNodeReferenceArgs(bindings::fwnode_reference_args); 321 322 impl Drop for FwNodeReferenceArgs { drop(&mut self)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 335 impl FwNodeReferenceArgs { 336 /// Returns the slice of reference arguments. as_slice(&self) -> &[u64]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. len(&self) -> usize344 pub fn len(&self) -> usize { 345 self.0.nargs as usize 346 } 347 348 /// Returns `true` if there are no reference arguments. is_empty(&self) -> bool349 pub fn is_empty(&self) -> bool { 350 self.0.nargs == 0 351 } 352 } 353 354 impl core::fmt::Debug for FwNodeReferenceArgs { fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result355 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. 361 unsafe impl crate::types::AlwaysRefCounted for FwNode { inc_ref(&self)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 dec_ref(obj: ptr::NonNull<Self>)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 375 enum Node<'a> { 376 Borrowed(&'a FwNode), 377 Owned(ARef<FwNode>), 378 } 379 380 impl core::fmt::Display for FwNode { fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result381 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. 436 pub trait Property: Sized + Sealed { 437 /// Used to make [`FwNode::property_read`] generic. read_from_fwnode_property(fwnode: &FwNode, name: &CStr) -> Result<Self>438 fn read_from_fwnode_property(fwnode: &FwNode, name: &CStr) -> Result<Self>; 439 } 440 441 impl Sealed for CString {} 442 443 impl Property for CString { read_from_fwnode_property(fwnode: &FwNode, name: &CStr) -> Result<Self>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. 474 pub trait PropertyInt: Copy + Sealed { 475 /// Reads a property array. read_array_from_fwnode_property<'a>( fwnode: &FwNode, name: &CStr, out: &'a mut [MaybeUninit<Self>], ) -> Result<&'a mut [Self]>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. read_array_len_from_fwnode_property(fwnode: &FwNode, name: &CStr) -> Result<usize>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. 490 macro_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 } 563 impl_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. 580 pub 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 589 impl<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. required_by(self, dev: &super::Device) -> Result<T>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. optional(self) -> Option<T>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. or(self, default: T) -> T619 pub fn or(self, default: T) -> T { 620 self.inner.unwrap_or(default) 621 } 622 } 623 624 impl<T: Default> PropertyGuard<'_, '_, T> { 625 /// Access the property or a default value. 626 /// 627 /// Use [`Self::or`] to specify a custom default value. or_default(self) -> T628 pub fn or_default(self) -> T { 629 self.inner.unwrap_or_default() 630 } 631 } 632