Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

rust: device: Introduce PropertyGuard

This abstraction is a way to force users to specify whether a property
is supposed to be required or not. This allows us to move error
logging of missing required properties into core, preventing a lot of
boilerplate in drivers.

It will be used by upcoming methods for reading device properties.

Tested-by: Dirk Behme <dirk.behme@de.bosch.com>
Signed-off-by: Remo Senekowitsch <remo@buenzli.dev>
Link: https://lore.kernel.org/r/20250611102908.212514-6-remo@buenzli.dev
[ Use prelude::* to avoid build failure; move PropertyGuard below Display
impl of FwNode. - Danilo ]
Signed-off-by: Danilo Krummrich <dakr@kernel.org>

authored by

Remo Senekowitsch and committed by
Danilo Krummrich
9bd791d9 ecea2459

+60
+60
rust/kernel/device/property.rs
··· 8 8 9 9 use crate::{ 10 10 bindings, 11 + prelude::*, 11 12 str::CStr, 12 13 types::{ARef, Opaque}, 13 14 }; ··· 153 152 } 154 153 155 154 Ok(()) 155 + } 156 + } 157 + 158 + /// A helper for reading device properties. 159 + /// 160 + /// Use [`Self::required_by`] if a missing property is considered a bug and 161 + /// [`Self::optional`] otherwise. 162 + /// 163 + /// For convenience, [`Self::or`] and [`Self::or_default`] are provided. 164 + pub struct PropertyGuard<'fwnode, 'name, T> { 165 + /// The result of reading the property. 166 + inner: Result<T>, 167 + /// The fwnode of the property, used for logging in the "required" case. 168 + fwnode: &'fwnode FwNode, 169 + /// The name of the property, used for logging in the "required" case. 170 + name: &'name CStr, 171 + } 172 + 173 + impl<T> PropertyGuard<'_, '_, T> { 174 + /// Access the property, indicating it is required. 175 + /// 176 + /// If the property is not present, the error is automatically logged. If a 177 + /// missing property is not an error, use [`Self::optional`] instead. The 178 + /// device is required to associate the log with it. 179 + pub fn required_by(self, dev: &super::Device) -> Result<T> { 180 + if self.inner.is_err() { 181 + dev_err!( 182 + dev, 183 + "{}: property '{}' is missing\n", 184 + self.fwnode, 185 + self.name 186 + ); 187 + } 188 + self.inner 189 + } 190 + 191 + /// Access the property, indicating it is optional. 192 + /// 193 + /// In contrast to [`Self::required_by`], no error message is logged if 194 + /// the property is not present. 195 + pub fn optional(self) -> Option<T> { 196 + self.inner.ok() 197 + } 198 + 199 + /// Access the property or the specified default value. 200 + /// 201 + /// Do not pass a sentinel value as default to detect a missing property. 202 + /// Use [`Self::required_by`] or [`Self::optional`] instead. 203 + pub fn or(self, default: T) -> T { 204 + self.inner.unwrap_or(default) 205 + } 206 + } 207 + 208 + impl<T: Default> PropertyGuard<'_, '_, T> { 209 + /// Access the property or a default value. 210 + /// 211 + /// Use [`Self::or`] to specify a custom default value. 212 + pub fn or_default(self) -> T { 213 + self.inner.unwrap_or_default() 156 214 } 157 215 }