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
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 >
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>; > > + }; > > }; > > };
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",
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.
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
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 > >
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 >> >
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
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.
© 2016 - 2025 Red Hat, Inc.