[PATCH v5 2/9] rust: device: Enable accessing the FwNode of a Device

Remo Senekowitsch posted 9 patches 7 months ago
There is a newer version of this series
[PATCH v5 2/9] rust: device: Enable accessing the FwNode of a Device
Posted by Remo Senekowitsch 7 months ago
Subsequent patches will add methods for reading properties to FwNode.
The first step to accessing these methods will be to access the "root"
FwNode of a Device.

Add the method `fwnode` to `Device`.

Signed-off-by: Remo Senekowitsch <remo@buenzli.dev>
---
 rust/kernel/device.rs | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/rust/kernel/device.rs b/rust/kernel/device.rs
index d8619d4485fb4..b4b7056eb80f8 100644
--- a/rust/kernel/device.rs
+++ b/rust/kernel/device.rs
@@ -186,6 +186,21 @@ unsafe fn printk(&self, klevel: &[u8], msg: fmt::Arguments<'_>) {
         };
     }
 
+    /// Obtain the [`FwNode`](property::FwNode) corresponding to the device.
+    pub fn fwnode(&self) -> Option<&property::FwNode> {
+        // SAFETY: `self` is valid.
+        let fwnode_handle = unsafe { bindings::__dev_fwnode(self.as_raw()) };
+        if fwnode_handle.is_null() {
+            return None;
+        }
+        // SAFETY: `fwnode_handle` is valid. Its lifetime is tied to `&self`. We
+        // return a reference instead of an `ARef<FwNode>` because `dev_fwnode()`
+        // doesn't increment the refcount. It is safe to cast from a
+        // `struct fwnode_handle*` to a `*const FwNode` because `FwNode` is
+        // defined as a `#[repr(transparent)]` wrapper around `fwnode_handle`.
+        Some(unsafe { &*fwnode_handle.cast() })
+    }
+
     /// 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.
-- 
2.49.0
Re: [PATCH v5 2/9] rust: device: Enable accessing the FwNode of a Device
Posted by Greg Kroah-Hartman 7 months ago
On Tue, May 20, 2025 at 10:00:17PM +0200, Remo Senekowitsch wrote:
> Subsequent patches will add methods for reading properties to FwNode.
> The first step to accessing these methods will be to access the "root"
> FwNode of a Device.
> 
> Add the method `fwnode` to `Device`.
> 
> Signed-off-by: Remo Senekowitsch <remo@buenzli.dev>
> ---
>  rust/kernel/device.rs | 15 +++++++++++++++
>  1 file changed, 15 insertions(+)
> 
> diff --git a/rust/kernel/device.rs b/rust/kernel/device.rs
> index d8619d4485fb4..b4b7056eb80f8 100644
> --- a/rust/kernel/device.rs
> +++ b/rust/kernel/device.rs
> @@ -186,6 +186,21 @@ unsafe fn printk(&self, klevel: &[u8], msg: fmt::Arguments<'_>) {
>          };
>      }
>  
> +    /// Obtain the [`FwNode`](property::FwNode) corresponding to the device.
> +    pub fn fwnode(&self) -> Option<&property::FwNode> {
> +        // SAFETY: `self` is valid.
> +        let fwnode_handle = unsafe { bindings::__dev_fwnode(self.as_raw()) };

Why isn't this calling __dev_fwnode_const()?  And there's no way to just
use dev_fwnode() directly?  Ugh, it's a macro...

thanks,

greg k-h
Re: [PATCH v5 2/9] rust: device: Enable accessing the FwNode of a Device
Posted by Remo Senekowitsch 7 months ago
On Wed May 21, 2025 at 1:59 PM CEST, Greg Kroah-Hartman wrote:
> On Tue, May 20, 2025 at 10:00:17PM +0200, Remo Senekowitsch wrote:
>> Subsequent patches will add methods for reading properties to FwNode.
>> The first step to accessing these methods will be to access the "root"
>> FwNode of a Device.
>> 
>> Add the method `fwnode` to `Device`.
>> 
>> Signed-off-by: Remo Senekowitsch <remo@buenzli.dev>
>> ---
>>  rust/kernel/device.rs | 15 +++++++++++++++
>>  1 file changed, 15 insertions(+)
>> 
>> diff --git a/rust/kernel/device.rs b/rust/kernel/device.rs
>> index d8619d4485fb4..b4b7056eb80f8 100644
>> --- a/rust/kernel/device.rs
>> +++ b/rust/kernel/device.rs
>> @@ -186,6 +186,21 @@ unsafe fn printk(&self, klevel: &[u8], msg: fmt::Arguments<'_>) {
>>          };
>>      }
>>  
>> +    /// Obtain the [`FwNode`](property::FwNode) corresponding to the device.
>> +    pub fn fwnode(&self) -> Option<&property::FwNode> {
>> +        // SAFETY: `self` is valid.
>> +        let fwnode_handle = unsafe { bindings::__dev_fwnode(self.as_raw()) };
>
> Why isn't this calling __dev_fwnode_const()?  And there's no way to just
> use dev_fwnode() directly?  Ugh, it's a macro...

I think I had that in earlier versions of the patch series. There was
a helper to call the macro from Rust. It was pointed out that this is
not clearly expressing the intent - whether fwnode is mutated or not.
And I think someone said the fwnode can be mutated so __dev_fwnode() is
semantically correct.