linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v1 0/3] Add Rust bindings for device property child nodes and reference args
@ 2025-06-16 15:45 Remo Senekowitsch
  2025-06-16 15:45 ` [PATCH v1 1/3] rust: device: Add child accessor and iterator Remo Senekowitsch
                   ` (3 more replies)
  0 siblings, 4 replies; 14+ messages in thread
From: Remo Senekowitsch @ 2025-06-16 15:45 UTC (permalink / raw)
  To: Rob Herring, Saravana Kannan, Greg Kroah-Hartman,
	Rafael J. Wysocki, Danilo Krummrich, Miguel Ojeda, Alex Gaynor,
	Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin,
	Andreas Hindborg, Alice Ryhl, Trevor Gross, Mark Brown,
	Dirk Behme, Remo Senekowitsch
  Cc: devicetree, linux-kernel, rust-for-linux

This patch series was split-off from an earlier one. [1]

changes in v1 (compared to previous patch series):
* Fix resource leak of `FwNodeReferenceArgs`.
* Improve documentation of the type invariants of `FwNodeReferenceArgs`
  and how they are upheld at crate-internal use-sites.
* Remove derived implementation of `Clone` of `FwNodeReferenceArgs`.
  It would be unsafe according to the new type invariants.
* Add `Debug` implementation for `FwNodeReferenceArgs`.
* Add examples.

Best regards,
Remo

[1] https://lore.kernel.org/lkml/20250611102908.212514-1-remo@buenzli.dev/

Remo Senekowitsch (3):
  rust: device: Add child accessor and iterator
  rust: device: Add property_get_reference_args
  samples: rust: platform: Add property child and reference args
    examples

 drivers/of/unittest-data/tests-platform.dtsi |   7 +
 rust/kernel/device/property.rs               | 158 +++++++++++++++++++
 samples/rust/rust_driver_platform.rs         |  13 +-
 3 files changed, 177 insertions(+), 1 deletion(-)

-- 
2.49.0


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v1 1/3] rust: device: Add child accessor and iterator
  2025-06-16 15:45 [PATCH v1 0/3] Add Rust bindings for device property child nodes and reference args Remo Senekowitsch
@ 2025-06-16 15:45 ` Remo Senekowitsch
  2025-06-16 15:45 ` [PATCH v1 2/3] rust: device: Add property_get_reference_args Remo Senekowitsch
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 14+ messages in thread
From: Remo Senekowitsch @ 2025-06-16 15:45 UTC (permalink / raw)
  To: Rob Herring, Saravana Kannan, Greg Kroah-Hartman,
	Rafael J. Wysocki, Danilo Krummrich, Miguel Ojeda, Alex Gaynor,
	Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin,
	Andreas Hindborg, Alice Ryhl, Trevor Gross, Mark Brown,
	Dirk Behme, Remo Senekowitsch
  Cc: devicetree, linux-kernel, rust-for-linux

Allow Rust drivers to access children of a fwnode either by name or by
iterating over all of them.

In C, there is the function `fwnode_get_next_child_node` for iteration
and the macro `fwnode_for_each_child_node` that helps with handling the
pointers. Instead of a macro, a native iterator is used in Rust such
that regular for-loops can be used.

Tested-by: Dirk Behme <dirk.behme@de.bosch.com>
Signed-off-by: Remo Senekowitsch <remo@buenzli.dev>
---
 rust/kernel/device/property.rs | 56 ++++++++++++++++++++++++++++++++++
 1 file changed, 56 insertions(+)

diff --git a/rust/kernel/device/property.rs b/rust/kernel/device/property.rs
index 838509111e57..04a13d05785a 100644
--- a/rust/kernel/device/property.rs
+++ b/rust/kernel/device/property.rs
@@ -190,6 +190,62 @@ pub fn property_read<'fwnode, 'name, T: Property>(
             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)
+        })
+    }
 }
 
 // SAFETY: Instances of `FwNode` are always reference-counted.
-- 
2.49.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v1 2/3] rust: device: Add property_get_reference_args
  2025-06-16 15:45 [PATCH v1 0/3] Add Rust bindings for device property child nodes and reference args Remo Senekowitsch
  2025-06-16 15:45 ` [PATCH v1 1/3] rust: device: Add child accessor and iterator Remo Senekowitsch
@ 2025-06-16 15:45 ` Remo Senekowitsch
  2025-06-16 15:45 ` [PATCH v1 3/3] samples: rust: platform: Add property child and reference args examples Remo Senekowitsch
  2025-06-25 16:08 ` [PATCH v1 0/3] Add Rust bindings for device property child nodes and reference args Danilo Krummrich
  3 siblings, 0 replies; 14+ messages in thread
From: Remo Senekowitsch @ 2025-06-16 15:45 UTC (permalink / raw)
  To: Rob Herring, Saravana Kannan, Greg Kroah-Hartman,
	Rafael J. Wysocki, Danilo Krummrich, Miguel Ojeda, Alex Gaynor,
	Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin,
	Andreas Hindborg, Alice Ryhl, Trevor Gross, Mark Brown,
	Dirk Behme, Remo Senekowitsch
  Cc: devicetree, linux-kernel, rust-for-linux

Allow Rust code to read reference args from device properties. The
wrapper type `FwNodeReferenceArgs` allows callers to access the buffer
of read args safely.

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

diff --git a/rust/kernel/device/property.rs b/rust/kernel/device/property.rs
index 04a13d05785a..f56ffbd43a94 100644
--- a/rust/kernel/device/property.rs
+++ b/rust/kernel/device/property.rs
@@ -246,6 +246,99 @@ pub fn children<'a>(&'a self) -> impl Iterator<Item = ARef<FwNode>> + 'a {
             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 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 core::fmt::Debug for FwNodeReferenceArgs {
+    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+        write!(f, "{:?}", self.as_slice())
+    }
 }
 
 // SAFETY: Instances of `FwNode` are always reference-counted.
@@ -462,6 +555,15 @@ fn read_from_fwnode_property(fwnode: &FwNode, name: &CStr) -> Result<Self> {
     i64: fwnode_property_read_u64_array,
 }
 
+/// The number of arguments of a reference.
+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),
+}
+
 /// A helper for reading device properties.
 ///
 /// Use [`Self::required_by`] if a missing property is considered a bug and
-- 
2.49.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v1 3/3] samples: rust: platform: Add property child and reference args examples
  2025-06-16 15:45 [PATCH v1 0/3] Add Rust bindings for device property child nodes and reference args Remo Senekowitsch
  2025-06-16 15:45 ` [PATCH v1 1/3] rust: device: Add child accessor and iterator Remo Senekowitsch
  2025-06-16 15:45 ` [PATCH v1 2/3] rust: device: Add property_get_reference_args Remo Senekowitsch
@ 2025-06-16 15:45 ` Remo Senekowitsch
  2025-06-17 13:01   ` Rob Herring
  2025-06-25 16:08 ` [PATCH v1 0/3] Add Rust bindings for device property child nodes and reference args Danilo Krummrich
  3 siblings, 1 reply; 14+ messages in thread
From: Remo Senekowitsch @ 2025-06-16 15:45 UTC (permalink / raw)
  To: Rob Herring, Saravana Kannan, Greg Kroah-Hartman,
	Rafael J. Wysocki, Danilo Krummrich, Miguel Ojeda, Alex Gaynor,
	Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin,
	Andreas Hindborg, Alice Ryhl, Trevor Gross, Mark Brown,
	Dirk Behme, Remo Senekowitsch
  Cc: devicetree, linux-kernel, rust-for-linux

Add some example usage of the device property methods for reading
DT/ACPI/swnode child nodes and reference args.

Signed-off-by: Remo Senekowitsch <remo@buenzli.dev>
---
 drivers/of/unittest-data/tests-platform.dtsi |  7 +++++++
 samples/rust/rust_driver_platform.rs         | 13 ++++++++++++-
 2 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/drivers/of/unittest-data/tests-platform.dtsi b/drivers/of/unittest-data/tests-platform.dtsi
index 50a51f38afb6..509eb614ab2b 100644
--- a/drivers/of/unittest-data/tests-platform.dtsi
+++ b/drivers/of/unittest-data/tests-platform.dtsi
@@ -40,6 +40,13 @@ test-device@2 {
 
 				test,u32-prop = <0xdeadbeef>;
 				test,i16-array = /bits/ 16 <1 2 (-3) (-4)>;
+
+				ref_child_0: child@0 {
+					test,ref-arg = <&ref_child_1 0x20 0x32>;
+				};
+				ref_child_1: child@1 {
+					test,ref-arg = <&ref_child_0 0x10 0x64>;
+				};
 			};
 		};
 
diff --git a/samples/rust/rust_driver_platform.rs b/samples/rust/rust_driver_platform.rs
index c0abf78d0683..4dcedb22a4bb 100644
--- a/samples/rust/rust_driver_platform.rs
+++ b/samples/rust/rust_driver_platform.rs
@@ -4,7 +4,11 @@
 
 use kernel::{
     c_str,
-    device::{self, Core},
+    device::{
+        self,
+        property::{FwNodeReferenceArgs, NArgs},
+        Core,
+    },
     of, platform,
     prelude::*,
     str::CString,
@@ -91,6 +95,13 @@ fn properties_parse(dev: &device::Device) -> Result {
         let prop: KVec<i16> = fwnode.property_read_array_vec(name, 4)?.required_by(dev)?;
         dev_info!(dev, "'{name}'='{prop:?}' (KVec)\n");
 
+        for child in fwnode.children() {
+            let name = c_str!("test,ref-arg");
+            let nargs = NArgs::N(2);
+            let prop: FwNodeReferenceArgs = child.property_get_reference_args(name, nargs, 0)?;
+            dev_info!(dev, "'{name}'='{prop:?}'\n");
+        }
+
         Ok(())
     }
 }
-- 
2.49.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH v1 3/3] samples: rust: platform: Add property child and reference args examples
  2025-06-16 15:45 ` [PATCH v1 3/3] samples: rust: platform: Add property child and reference args examples Remo Senekowitsch
@ 2025-06-17 13:01   ` Rob Herring
  2025-06-17 13:11     ` Danilo Krummrich
  2025-06-20 22:37     ` Danilo Krummrich
  0 siblings, 2 replies; 14+ messages in thread
From: Rob Herring @ 2025-06-17 13:01 UTC (permalink / raw)
  To: Remo Senekowitsch
  Cc: Saravana Kannan, Greg Kroah-Hartman, Rafael J. Wysocki,
	Danilo Krummrich, Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
	Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
	Trevor Gross, Mark Brown, Dirk Behme, devicetree, linux-kernel,
	rust-for-linux

On Mon, Jun 16, 2025 at 10:45 AM Remo Senekowitsch <remo@buenzli.dev> wrote:
>
> Add some example usage of the device property methods for reading
> DT/ACPI/swnode child nodes and reference args.
>
> Signed-off-by: Remo Senekowitsch <remo@buenzli.dev>
> ---
>  drivers/of/unittest-data/tests-platform.dtsi |  7 +++++++
>  samples/rust/rust_driver_platform.rs         | 13 ++++++++++++-
>  2 files changed, 19 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/of/unittest-data/tests-platform.dtsi b/drivers/of/unittest-data/tests-platform.dtsi
> index 50a51f38afb6..509eb614ab2b 100644
> --- a/drivers/of/unittest-data/tests-platform.dtsi
> +++ b/drivers/of/unittest-data/tests-platform.dtsi
> @@ -40,6 +40,13 @@ test-device@2 {
>
>                                 test,u32-prop = <0xdeadbeef>;
>                                 test,i16-array = /bits/ 16 <1 2 (-3) (-4)>;
> +
> +                               ref_child_0: child@0 {

child-0 or you need to add 'reg' property if you keep the unit-address.

> +                                       test,ref-arg = <&ref_child_1 0x20 0x32>;
> +                               };
> +                               ref_child_1: child@1 {
> +                                       test,ref-arg = <&ref_child_0 0x10 0x64>;
> +                               };
>                         };
>                 };
>
> diff --git a/samples/rust/rust_driver_platform.rs b/samples/rust/rust_driver_platform.rs
> index c0abf78d0683..4dcedb22a4bb 100644
> --- a/samples/rust/rust_driver_platform.rs
> +++ b/samples/rust/rust_driver_platform.rs
> @@ -4,7 +4,11 @@
>
>  use kernel::{
>      c_str,
> -    device::{self, Core},
> +    device::{
> +        self,
> +        property::{FwNodeReferenceArgs, NArgs},
> +        Core,
> +    },
>      of, platform,
>      prelude::*,
>      str::CString,
> @@ -91,6 +95,13 @@ fn properties_parse(dev: &device::Device) -> Result {
>          let prop: KVec<i16> = fwnode.property_read_array_vec(name, 4)?.required_by(dev)?;
>          dev_info!(dev, "'{name}'='{prop:?}' (KVec)\n");
>
> +        for child in fwnode.children() {
> +            let name = c_str!("test,ref-arg");
> +            let nargs = NArgs::N(2);
> +            let prop: FwNodeReferenceArgs = child.property_get_reference_args(name, nargs, 0)?;

Is there some reason we can just pass 2 in rather than nargs? Seems
overly verbose for my tastes.

> +            dev_info!(dev, "'{name}'='{prop:?}'\n");
> +        }
> +
>          Ok(())
>      }
>  }
> --
> 2.49.0
>

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v1 3/3] samples: rust: platform: Add property child and reference args examples
  2025-06-17 13:01   ` Rob Herring
@ 2025-06-17 13:11     ` Danilo Krummrich
  2025-06-18 11:37       ` Remo Senekowitsch
  2025-06-20 22:37     ` Danilo Krummrich
  1 sibling, 1 reply; 14+ messages in thread
From: Danilo Krummrich @ 2025-06-17 13:11 UTC (permalink / raw)
  To: Rob Herring
  Cc: Remo Senekowitsch, Saravana Kannan, Greg Kroah-Hartman,
	Rafael J. Wysocki, Miguel Ojeda, Alex Gaynor, Boqun Feng,
	Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg,
	Alice Ryhl, Trevor Gross, Mark Brown, Dirk Behme, devicetree,
	linux-kernel, rust-for-linux

On Tue, Jun 17, 2025 at 08:01:08AM -0500, Rob Herring wrote:
> On Mon, Jun 16, 2025 at 10:45 AM Remo Senekowitsch <remo@buenzli.dev> wrote:
> > @@ -91,6 +95,13 @@ fn properties_parse(dev: &device::Device) -> Result {
> >          let prop: KVec<i16> = fwnode.property_read_array_vec(name, 4)?.required_by(dev)?;
> >          dev_info!(dev, "'{name}'='{prop:?}' (KVec)\n");
> >
> > +        for child in fwnode.children() {
> > +            let name = c_str!("test,ref-arg");
> > +            let nargs = NArgs::N(2);
> > +            let prop: FwNodeReferenceArgs = child.property_get_reference_args(name, nargs, 0)?;
> 
> Is there some reason we can just pass 2 in rather than nargs? Seems
> overly verbose for my tastes.

It's because you could also pass NArgs::Prop("foo-bar") to indicate the the
name of the property telling the number of arguments.

NArgs is defined as

	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),
	}

and FwNode::property_get_reference_args() can match against the corresponding
enum variant to cover both cases.

> > +            dev_info!(dev, "'{name}'='{prop:?}'\n");
> > +        }
> > +
> >          Ok(())
> >      }
> >  }
> > --
> > 2.49.0
> >

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v1 3/3] samples: rust: platform: Add property child and reference args examples
  2025-06-17 13:11     ` Danilo Krummrich
@ 2025-06-18 11:37       ` Remo Senekowitsch
  2025-06-18 13:31         ` Rob Herring
  0 siblings, 1 reply; 14+ messages in thread
From: Remo Senekowitsch @ 2025-06-18 11:37 UTC (permalink / raw)
  To: Danilo Krummrich, Rob Herring
  Cc: Saravana Kannan, Greg Kroah-Hartman, Rafael J. Wysocki,
	Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
	Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
	Trevor Gross, Mark Brown, Dirk Behme, devicetree, linux-kernel,
	rust-for-linux

On Tue Jun 17, 2025 at 3:11 PM CEST, Danilo Krummrich wrote:
> On Tue, Jun 17, 2025 at 08:01:08AM -0500, Rob Herring wrote:
>> On Mon, Jun 16, 2025 at 10:45 AM Remo Senekowitsch <remo@buenzli.dev> wrote:
>> > @@ -91,6 +95,13 @@ fn properties_parse(dev: &device::Device) -> Result {
>> >          let prop: KVec<i16> = fwnode.property_read_array_vec(name, 4)?.required_by(dev)?;
>> >          dev_info!(dev, "'{name}'='{prop:?}' (KVec)\n");
>> >
>> > +        for child in fwnode.children() {
>> > +            let name = c_str!("test,ref-arg");
>> > +            let nargs = NArgs::N(2);
>> > +            let prop: FwNodeReferenceArgs = child.property_get_reference_args(name, nargs, 0)?;
>> 
>> Is there some reason we can just pass 2 in rather than nargs? Seems
>> overly verbose for my tastes.
>
> It's because you could also pass NArgs::Prop("foo-bar") to indicate the the
> name of the property telling the number of arguments.
>
> NArgs is defined as
>
> 	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),
> 	}
>
> and FwNode::property_get_reference_args() can match against the corresponding
> enum variant to cover both cases.

I guess we could make the function generic if that's deemed worth it?
A trait and an implementation for `u32` and `&CStr` each. Similar to how
we made `property_read` generic.

>> > +            dev_info!(dev, "'{name}'='{prop:?}'\n");
>> > +        }
>> > +
>> >          Ok(())
>> >      }
>> >  }
>> > --
>> > 2.49.0
>> >


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v1 3/3] samples: rust: platform: Add property child and reference args examples
  2025-06-18 11:37       ` Remo Senekowitsch
@ 2025-06-18 13:31         ` Rob Herring
  2025-06-18 14:16           ` Danilo Krummrich
  0 siblings, 1 reply; 14+ messages in thread
From: Rob Herring @ 2025-06-18 13:31 UTC (permalink / raw)
  To: Remo Senekowitsch
  Cc: Danilo Krummrich, Saravana Kannan, Greg Kroah-Hartman,
	Rafael J. Wysocki, Miguel Ojeda, Alex Gaynor, Boqun Feng,
	Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg,
	Alice Ryhl, Trevor Gross, Mark Brown, Dirk Behme, devicetree,
	linux-kernel, rust-for-linux

On Wed, Jun 18, 2025 at 01:37:08PM +0200, Remo Senekowitsch wrote:
> On Tue Jun 17, 2025 at 3:11 PM CEST, Danilo Krummrich wrote:
> > On Tue, Jun 17, 2025 at 08:01:08AM -0500, Rob Herring wrote:
> >> On Mon, Jun 16, 2025 at 10:45 AM Remo Senekowitsch <remo@buenzli.dev> wrote:
> >> > @@ -91,6 +95,13 @@ fn properties_parse(dev: &device::Device) -> Result {
> >> >          let prop: KVec<i16> = fwnode.property_read_array_vec(name, 4)?.required_by(dev)?;
> >> >          dev_info!(dev, "'{name}'='{prop:?}' (KVec)\n");
> >> >
> >> > +        for child in fwnode.children() {
> >> > +            let name = c_str!("test,ref-arg");
> >> > +            let nargs = NArgs::N(2);
> >> > +            let prop: FwNodeReferenceArgs = child.property_get_reference_args(name, nargs, 0)?;
> >> 
> >> Is there some reason we can just pass 2 in rather than nargs? Seems
> >> overly verbose for my tastes.
> >
> > It's because you could also pass NArgs::Prop("foo-bar") to indicate the the
> > name of the property telling the number of arguments.
> >
> > NArgs is defined as
> >
> > 	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),
> > 	}
> >
> > and FwNode::property_get_reference_args() can match against the corresponding
> > enum variant to cover both cases.
> 
> I guess we could make the function generic if that's deemed worth it?
> A trait and an implementation for `u32` and `&CStr` each. Similar to how
> we made `property_read` generic.

There is a case where the cells property is optional and we fallback to 
0 cells if not found. #msi-cells is an example. I imagine NArgs could 
express that while a generic could not? In any case, I don't expect 
drivers to have to deal with that as it would be subsystem code handling 
it.

As-is is fine I think. This function isn't too widely used that it could 
be changed later if we change our minds.

Rob

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v1 3/3] samples: rust: platform: Add property child and reference args examples
  2025-06-18 13:31         ` Rob Herring
@ 2025-06-18 14:16           ` Danilo Krummrich
  0 siblings, 0 replies; 14+ messages in thread
From: Danilo Krummrich @ 2025-06-18 14:16 UTC (permalink / raw)
  To: Rob Herring
  Cc: Remo Senekowitsch, Saravana Kannan, Greg Kroah-Hartman,
	Rafael J. Wysocki, Miguel Ojeda, Alex Gaynor, Boqun Feng,
	Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg,
	Alice Ryhl, Trevor Gross, Mark Brown, Dirk Behme, devicetree,
	linux-kernel, rust-for-linux

On Wed, Jun 18, 2025 at 08:31:55AM -0500, Rob Herring wrote:
> On Wed, Jun 18, 2025 at 01:37:08PM +0200, Remo Senekowitsch wrote:
> > On Tue Jun 17, 2025 at 3:11 PM CEST, Danilo Krummrich wrote:
> > > On Tue, Jun 17, 2025 at 08:01:08AM -0500, Rob Herring wrote:
> > >> On Mon, Jun 16, 2025 at 10:45 AM Remo Senekowitsch <remo@buenzli.dev> wrote:
> > >> > @@ -91,6 +95,13 @@ fn properties_parse(dev: &device::Device) -> Result {
> > >> >          let prop: KVec<i16> = fwnode.property_read_array_vec(name, 4)?.required_by(dev)?;
> > >> >          dev_info!(dev, "'{name}'='{prop:?}' (KVec)\n");
> > >> >
> > >> > +        for child in fwnode.children() {
> > >> > +            let name = c_str!("test,ref-arg");
> > >> > +            let nargs = NArgs::N(2);
> > >> > +            let prop: FwNodeReferenceArgs = child.property_get_reference_args(name, nargs, 0)?;
> > >> 
> > >> Is there some reason we can just pass 2 in rather than nargs? Seems
> > >> overly verbose for my tastes.
> > >
> > > It's because you could also pass NArgs::Prop("foo-bar") to indicate the the
> > > name of the property telling the number of arguments.
> > >
> > > NArgs is defined as
> > >
> > > 	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),
> > > 	}
> > >
> > > and FwNode::property_get_reference_args() can match against the corresponding
> > > enum variant to cover both cases.
> > 
> > I guess we could make the function generic if that's deemed worth it?
> > A trait and an implementation for `u32` and `&CStr` each. Similar to how
> > we made `property_read` generic.

I don't think that's worth it; I think the current version is fine as it is.

> There is a case where the cells property is optional and we fallback to 
> 0 cells if not found. #msi-cells is an example. I imagine NArgs could 
> express that while a generic could not? In any case, I don't expect 
> drivers to have to deal with that as it would be subsystem code handling 
> it.
> 
> As-is is fine I think. This function isn't too widely used that it could 
> be changed later if we change our minds.

Agreed.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v1 3/3] samples: rust: platform: Add property child and reference args examples
  2025-06-17 13:01   ` Rob Herring
  2025-06-17 13:11     ` Danilo Krummrich
@ 2025-06-20 22:37     ` Danilo Krummrich
  2025-06-25 14:39       ` Rob Herring
  1 sibling, 1 reply; 14+ messages in thread
From: Danilo Krummrich @ 2025-06-20 22:37 UTC (permalink / raw)
  To: Rob Herring
  Cc: Remo Senekowitsch, Saravana Kannan, Greg Kroah-Hartman,
	Rafael J. Wysocki, Miguel Ojeda, Alex Gaynor, Boqun Feng,
	Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg,
	Alice Ryhl, Trevor Gross, Mark Brown, Dirk Behme, devicetree,
	linux-kernel, rust-for-linux

On Tue, Jun 17, 2025 at 08:01:08AM -0500, Rob Herring wrote:
> On Mon, Jun 16, 2025 at 10:45 AM Remo Senekowitsch <remo@buenzli.dev> wrote:
> >
> > Add some example usage of the device property methods for reading
> > DT/ACPI/swnode child nodes and reference args.
> >
> > Signed-off-by: Remo Senekowitsch <remo@buenzli.dev>
> > ---
> >  drivers/of/unittest-data/tests-platform.dtsi |  7 +++++++
> >  samples/rust/rust_driver_platform.rs         | 13 ++++++++++++-
> >  2 files changed, 19 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/of/unittest-data/tests-platform.dtsi b/drivers/of/unittest-data/tests-platform.dtsi
> > index 50a51f38afb6..509eb614ab2b 100644
> > --- a/drivers/of/unittest-data/tests-platform.dtsi
> > +++ b/drivers/of/unittest-data/tests-platform.dtsi
> > @@ -40,6 +40,13 @@ test-device@2 {
> >
> >                                 test,u32-prop = <0xdeadbeef>;
> >                                 test,i16-array = /bits/ 16 <1 2 (-3) (-4)>;
> > +
> > +                               ref_child_0: child@0 {
> 
> child-0 or you need to add 'reg' property if you keep the unit-address.

Adding child nodes here creates the following dt-test failues.

	[    1.031239] ### dt-test ### FAIL of_unittest_platform_populate():1862 Could not create device for node 'child'
	[    1.031647] ### dt-test ### FAIL of_unittest_platform_populate():1862 Could not create device for node 'child'

@Rob: What do you suggest?

> 
> > +                                       test,ref-arg = <&ref_child_1 0x20 0x32>;
> > +                               };
> > +                               ref_child_1: child@1 {
> > +                                       test,ref-arg = <&ref_child_0 0x10 0x64>;
> > +                               };
> >                         };
> >                 };

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v1 3/3] samples: rust: platform: Add property child and reference args examples
  2025-06-20 22:37     ` Danilo Krummrich
@ 2025-06-25 14:39       ` Rob Herring
  2025-06-25 15:09         ` Danilo Krummrich
  0 siblings, 1 reply; 14+ messages in thread
From: Rob Herring @ 2025-06-25 14:39 UTC (permalink / raw)
  To: Danilo Krummrich
  Cc: Remo Senekowitsch, Saravana Kannan, Greg Kroah-Hartman,
	Rafael J. Wysocki, Miguel Ojeda, Alex Gaynor, Boqun Feng,
	Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg,
	Alice Ryhl, Trevor Gross, Mark Brown, Dirk Behme, devicetree,
	linux-kernel, rust-for-linux

On Sat, Jun 21, 2025 at 12:37:27AM +0200, Danilo Krummrich wrote:
> On Tue, Jun 17, 2025 at 08:01:08AM -0500, Rob Herring wrote:
> > On Mon, Jun 16, 2025 at 10:45 AM Remo Senekowitsch <remo@buenzli.dev> wrote:
> > >
> > > Add some example usage of the device property methods for reading
> > > DT/ACPI/swnode child nodes and reference args.
> > >
> > > Signed-off-by: Remo Senekowitsch <remo@buenzli.dev>
> > > ---
> > >  drivers/of/unittest-data/tests-platform.dtsi |  7 +++++++
> > >  samples/rust/rust_driver_platform.rs         | 13 ++++++++++++-
> > >  2 files changed, 19 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/drivers/of/unittest-data/tests-platform.dtsi b/drivers/of/unittest-data/tests-platform.dtsi
> > > index 50a51f38afb6..509eb614ab2b 100644
> > > --- a/drivers/of/unittest-data/tests-platform.dtsi
> > > +++ b/drivers/of/unittest-data/tests-platform.dtsi
> > > @@ -40,6 +40,13 @@ test-device@2 {
> > >
> > >                                 test,u32-prop = <0xdeadbeef>;
> > >                                 test,i16-array = /bits/ 16 <1 2 (-3) (-4)>;
> > > +
> > > +                               ref_child_0: child@0 {
> > 
> > child-0 or you need to add 'reg' property if you keep the unit-address.
> 
> Adding child nodes here creates the following dt-test failues.
> 
> 	[    1.031239] ### dt-test ### FAIL of_unittest_platform_populate():1862 Could not create device for node 'child'
> 	[    1.031647] ### dt-test ### FAIL of_unittest_platform_populate():1862 Could not create device for node 'child'
> 
> @Rob: What do you suggest?

This should fix it:

index eeb370e0f507..e3503ec20f6c 100644
--- a/drivers/of/unittest.c
+++ b/drivers/of/unittest.c
@@ -1856,6 +1856,8 @@ static void __init of_unittest_platform_populate(void)
        of_platform_populate(np, match, NULL, &test_bus->dev);
        for_each_child_of_node(np, child) {
                for_each_child_of_node(child, grandchild) {
+                       if (!of_property_present(grandchild, "compatible"))
+                               continue;
                        pdev = of_find_device_by_node(grandchild);
                        unittest(pdev,
                                 "Could not create device for node '%pOFn'\n",


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH v1 3/3] samples: rust: platform: Add property child and reference args examples
  2025-06-25 14:39       ` Rob Herring
@ 2025-06-25 15:09         ` Danilo Krummrich
  2025-06-25 15:12           ` Rob Herring
  0 siblings, 1 reply; 14+ messages in thread
From: Danilo Krummrich @ 2025-06-25 15:09 UTC (permalink / raw)
  To: Rob Herring
  Cc: Remo Senekowitsch, Saravana Kannan, Greg Kroah-Hartman,
	Rafael J. Wysocki, Miguel Ojeda, Alex Gaynor, Boqun Feng,
	Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg,
	Alice Ryhl, Trevor Gross, Mark Brown, Dirk Behme, devicetree,
	linux-kernel, rust-for-linux

On 6/25/25 4:39 PM, Rob Herring wrote:
> On Sat, Jun 21, 2025 at 12:37:27AM +0200, Danilo Krummrich wrote:
>> On Tue, Jun 17, 2025 at 08:01:08AM -0500, Rob Herring wrote:
>>> On Mon, Jun 16, 2025 at 10:45 AM Remo Senekowitsch <remo@buenzli.dev> wrote:
>>>>
>>>> Add some example usage of the device property methods for reading
>>>> DT/ACPI/swnode child nodes and reference args.
>>>>
>>>> Signed-off-by: Remo Senekowitsch <remo@buenzli.dev>
>>>> ---
>>>>   drivers/of/unittest-data/tests-platform.dtsi |  7 +++++++
>>>>   samples/rust/rust_driver_platform.rs         | 13 ++++++++++++-
>>>>   2 files changed, 19 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/drivers/of/unittest-data/tests-platform.dtsi b/drivers/of/unittest-data/tests-platform.dtsi
>>>> index 50a51f38afb6..509eb614ab2b 100644
>>>> --- a/drivers/of/unittest-data/tests-platform.dtsi
>>>> +++ b/drivers/of/unittest-data/tests-platform.dtsi
>>>> @@ -40,6 +40,13 @@ test-device@2 {
>>>>
>>>>                                  test,u32-prop = <0xdeadbeef>;
>>>>                                  test,i16-array = /bits/ 16 <1 2 (-3) (-4)>;
>>>> +
>>>> +                               ref_child_0: child@0 {
>>>
>>> child-0 or you need to add 'reg' property if you keep the unit-address.
>>
>> Adding child nodes here creates the following dt-test failues.
>>
>> 	[    1.031239] ### dt-test ### FAIL of_unittest_platform_populate():1862 Could not create device for node 'child'
>> 	[    1.031647] ### dt-test ### FAIL of_unittest_platform_populate():1862 Could not create device for node 'child'
>>
>> @Rob: What do you suggest?
> 
> This should fix it:
> 
> index eeb370e0f507..e3503ec20f6c 100644
> --- a/drivers/of/unittest.c
> +++ b/drivers/of/unittest.c
> @@ -1856,6 +1856,8 @@ static void __init of_unittest_platform_populate(void)
>          of_platform_populate(np, match, NULL, &test_bus->dev);
>          for_each_child_of_node(np, child) {
>                  for_each_child_of_node(child, grandchild) {
> +                       if (!of_property_present(grandchild, "compatible"))
> +                               continue;
>                          pdev = of_find_device_by_node(grandchild);
>                          unittest(pdev,
>                                   "Could not create device for node '%pOFn'\n",
> 

Do you want this to be a separate patch? Otherwise, I'd fine just adding it to
this one.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v1 3/3] samples: rust: platform: Add property child and reference args examples
  2025-06-25 15:09         ` Danilo Krummrich
@ 2025-06-25 15:12           ` Rob Herring
  0 siblings, 0 replies; 14+ messages in thread
From: Rob Herring @ 2025-06-25 15:12 UTC (permalink / raw)
  To: Danilo Krummrich
  Cc: Remo Senekowitsch, Saravana Kannan, Greg Kroah-Hartman,
	Rafael J. Wysocki, Miguel Ojeda, Alex Gaynor, Boqun Feng,
	Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg,
	Alice Ryhl, Trevor Gross, Mark Brown, Dirk Behme, devicetree,
	linux-kernel, rust-for-linux

On Wed, Jun 25, 2025 at 10:09 AM Danilo Krummrich <dakr@kernel.org> wrote:
>
> On 6/25/25 4:39 PM, Rob Herring wrote:
> > On Sat, Jun 21, 2025 at 12:37:27AM +0200, Danilo Krummrich wrote:
> >> On Tue, Jun 17, 2025 at 08:01:08AM -0500, Rob Herring wrote:
> >>> On Mon, Jun 16, 2025 at 10:45 AM Remo Senekowitsch <remo@buenzli.dev> wrote:
> >>>>
> >>>> Add some example usage of the device property methods for reading
> >>>> DT/ACPI/swnode child nodes and reference args.
> >>>>
> >>>> Signed-off-by: Remo Senekowitsch <remo@buenzli.dev>
> >>>> ---
> >>>>   drivers/of/unittest-data/tests-platform.dtsi |  7 +++++++
> >>>>   samples/rust/rust_driver_platform.rs         | 13 ++++++++++++-
> >>>>   2 files changed, 19 insertions(+), 1 deletion(-)
> >>>>
> >>>> diff --git a/drivers/of/unittest-data/tests-platform.dtsi b/drivers/of/unittest-data/tests-platform.dtsi
> >>>> index 50a51f38afb6..509eb614ab2b 100644
> >>>> --- a/drivers/of/unittest-data/tests-platform.dtsi
> >>>> +++ b/drivers/of/unittest-data/tests-platform.dtsi
> >>>> @@ -40,6 +40,13 @@ test-device@2 {
> >>>>
> >>>>                                  test,u32-prop = <0xdeadbeef>;
> >>>>                                  test,i16-array = /bits/ 16 <1 2 (-3) (-4)>;
> >>>> +
> >>>> +                               ref_child_0: child@0 {
> >>>
> >>> child-0 or you need to add 'reg' property if you keep the unit-address.
> >>
> >> Adding child nodes here creates the following dt-test failues.
> >>
> >>      [    1.031239] ### dt-test ### FAIL of_unittest_platform_populate():1862 Could not create device for node 'child'
> >>      [    1.031647] ### dt-test ### FAIL of_unittest_platform_populate():1862 Could not create device for node 'child'
> >>
> >> @Rob: What do you suggest?
> >
> > This should fix it:
> >
> > index eeb370e0f507..e3503ec20f6c 100644
> > --- a/drivers/of/unittest.c
> > +++ b/drivers/of/unittest.c
> > @@ -1856,6 +1856,8 @@ static void __init of_unittest_platform_populate(void)
> >          of_platform_populate(np, match, NULL, &test_bus->dev);
> >          for_each_child_of_node(np, child) {
> >                  for_each_child_of_node(child, grandchild) {
> > +                       if (!of_property_present(grandchild, "compatible"))
> > +                               continue;
> >                          pdev = of_find_device_by_node(grandchild);
> >                          unittest(pdev,
> >                                   "Could not create device for node '%pOFn'\n",
> >
>
> Do you want this to be a separate patch? Otherwise, I'd fine just adding it to
> this one.

Adding it here is fine.

Rob

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v1 0/3] Add Rust bindings for device property child nodes and reference args
  2025-06-16 15:45 [PATCH v1 0/3] Add Rust bindings for device property child nodes and reference args Remo Senekowitsch
                   ` (2 preceding siblings ...)
  2025-06-16 15:45 ` [PATCH v1 3/3] samples: rust: platform: Add property child and reference args examples Remo Senekowitsch
@ 2025-06-25 16:08 ` Danilo Krummrich
  3 siblings, 0 replies; 14+ messages in thread
From: Danilo Krummrich @ 2025-06-25 16:08 UTC (permalink / raw)
  To: Remo Senekowitsch
  Cc: Rob Herring, Saravana Kannan, Greg Kroah-Hartman,
	Rafael J. Wysocki, Miguel Ojeda, Alex Gaynor, Boqun Feng,
	Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg,
	Alice Ryhl, Trevor Gross, Mark Brown, Dirk Behme, devicetree,
	linux-kernel, rust-for-linux

On Mon, Jun 16, 2025 at 05:45:08PM +0200, Remo Senekowitsch wrote:
> This patch series was split-off from an earlier one. [1]
> 
> [1] https://lore.kernel.org/lkml/20250611102908.212514-1-remo@buenzli.dev/

Applied to driver-core-testing, thanks!

> Remo Senekowitsch (3):
>   rust: device: Add child accessor and iterator
>   rust: device: Add property_get_reference_args

    [ Move up NArgs; refer to FwNodeReferenceArgs in NArgs doc-comment.
      - Danilo ]

>   samples: rust: platform: Add property child and reference args
>     examples

    [ Convert 'child@{0,1}' to 'child-{0,1}'; skip child nodes without
      'compatible' property in of_unittest_platform_populate() as proposed
      by Rob Herring. - Danilo]

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2025-06-25 16:08 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-16 15:45 [PATCH v1 0/3] Add Rust bindings for device property child nodes and reference args Remo Senekowitsch
2025-06-16 15:45 ` [PATCH v1 1/3] rust: device: Add child accessor and iterator Remo Senekowitsch
2025-06-16 15:45 ` [PATCH v1 2/3] rust: device: Add property_get_reference_args Remo Senekowitsch
2025-06-16 15:45 ` [PATCH v1 3/3] samples: rust: platform: Add property child and reference args examples Remo Senekowitsch
2025-06-17 13:01   ` Rob Herring
2025-06-17 13:11     ` Danilo Krummrich
2025-06-18 11:37       ` Remo Senekowitsch
2025-06-18 13:31         ` Rob Herring
2025-06-18 14:16           ` Danilo Krummrich
2025-06-20 22:37     ` Danilo Krummrich
2025-06-25 14:39       ` Rob Herring
2025-06-25 15:09         ` Danilo Krummrich
2025-06-25 15:12           ` Rob Herring
2025-06-25 16:08 ` [PATCH v1 0/3] Add Rust bindings for device property child nodes and reference args Danilo Krummrich

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).