[PATCH v4 3/3] rust: Add SoC Driver Sample

Matthew Maurer posted 3 patches 1 month, 1 week ago
[PATCH v4 3/3] rust: Add SoC Driver Sample
Posted by Matthew Maurer 1 month, 1 week ago
Shows registration of a SoC device upon receipt of a probe.

Signed-off-by: Matthew Maurer <mmaurer@google.com>
---
 MAINTAINERS              |  1 +
 samples/rust/Kconfig     | 11 +++++++
 samples/rust/Makefile    |  1 +
 samples/rust/rust_soc.rs | 81 ++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 94 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 4ff01fb0f1bda27002094113c0bf9d074d28fdb6..bb2e710277cc84dd6042d4d46076e665d9f68752 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7705,6 +7705,7 @@ F:	samples/rust/rust_debugfs.rs
 F:	samples/rust/rust_debugfs_scoped.rs
 F:	samples/rust/rust_driver_platform.rs
 F:	samples/rust/rust_driver_faux.rs
+F:	samples/rust/rust_soc.rs
 
 DRIVERS FOR OMAP ADAPTIVE VOLTAGE SCALING (AVS)
 M:	Nishanth Menon <nm@ti.com>
diff --git a/samples/rust/Kconfig b/samples/rust/Kconfig
index 3efa51bfc8efccd91d9ee079ccd078ed1a6e8aa7..c49ab910634596aea4a1a73dac87585e084f420a 100644
--- a/samples/rust/Kconfig
+++ b/samples/rust/Kconfig
@@ -161,6 +161,17 @@ config SAMPLE_RUST_DRIVER_AUXILIARY
 
 	  If unsure, say N.
 
+config SAMPLE_RUST_SOC
+	tristate "SoC Driver"
+	select SOC_BUS
+	help
+	  This option builds the Rust SoC driver sample.
+
+	  To compile this as a module, choose M here:
+	  the module will be called rust_soc.
+
+	  If unsure, say N.
+
 config SAMPLE_RUST_HOSTPROGS
 	bool "Host programs"
 	help
diff --git a/samples/rust/Makefile b/samples/rust/Makefile
index f65885d1d62bf406b0db13121ef3e5b09829cfbc..6c0aaa58ccccfd12ef019f68ca784f6d977bc668 100644
--- a/samples/rust/Makefile
+++ b/samples/rust/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_SAMPLE_RUST_DRIVER_USB)		+= rust_driver_usb.o
 obj-$(CONFIG_SAMPLE_RUST_DRIVER_FAUX)		+= rust_driver_faux.o
 obj-$(CONFIG_SAMPLE_RUST_DRIVER_AUXILIARY)	+= rust_driver_auxiliary.o
 obj-$(CONFIG_SAMPLE_RUST_CONFIGFS)		+= rust_configfs.o
+obj-$(CONFIG_SAMPLE_RUST_SOC)			+= rust_soc.o
 
 rust_print-y := rust_print_main.o rust_print_events.o
 
diff --git a/samples/rust/rust_soc.rs b/samples/rust/rust_soc.rs
new file mode 100644
index 0000000000000000000000000000000000000000..403c1137af779d3c660786959d6f5160f934f4ae
--- /dev/null
+++ b/samples/rust/rust_soc.rs
@@ -0,0 +1,81 @@
+// SPDX-License-Identifier: GPL-2.0
+
+//! Rust SoC Platform driver sample.
+
+use kernel::{
+    acpi,
+    device::Core,
+    of,
+    platform,
+    prelude::*,
+    soc,
+    str::CString,
+    sync::aref::ARef, //
+};
+use pin_init::pin_init_scope;
+
+#[pin_data]
+struct SampleSocDriver {
+    pdev: ARef<platform::Device>,
+    #[pin]
+    _dev_reg: soc::Registration,
+}
+
+kernel::of_device_table!(
+    OF_TABLE,
+    MODULE_OF_TABLE,
+    <SampleSocDriver as platform::Driver>::IdInfo,
+    [(of::DeviceId::new(c"test,rust-device"), ())]
+);
+
+kernel::acpi_device_table!(
+    ACPI_TABLE,
+    MODULE_ACPI_TABLE,
+    <SampleSocDriver as platform::Driver>::IdInfo,
+    [(acpi::DeviceId::new(c"LNUXBEEF"), ())]
+);
+
+impl platform::Driver for SampleSocDriver {
+    type IdInfo = ();
+    const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = Some(&OF_TABLE);
+    const ACPI_ID_TABLE: Option<acpi::IdTable<Self::IdInfo>> = Some(&ACPI_TABLE);
+
+    fn probe(
+        pdev: &platform::Device<Core>,
+        _info: Option<&Self::IdInfo>,
+    ) -> impl PinInit<Self, Error> {
+        let dev = pdev.as_ref();
+
+        dev_dbg!(dev, "Probe Rust SoC driver sample.\n");
+
+        let pdev = pdev.into();
+        pin_init_scope(move || {
+            let machine = CString::try_from(c"My cool ACME15 dev board")?;
+            let family = CString::try_from(c"ACME")?;
+            let revision = CString::try_from(c"1.2")?;
+            let serial_number = CString::try_from(c"12345")?;
+            let soc_id = CString::try_from(c"ACME15")?;
+
+            let attr = soc::Attributes {
+                machine: Some(machine),
+                family: Some(family),
+                revision: Some(revision),
+                serial_number: Some(serial_number),
+                soc_id: Some(soc_id),
+            };
+
+            Ok(try_pin_init!(SampleSocDriver {
+                pdev: pdev,
+                _dev_reg <- soc::Registration::new(attr),
+            }? Error))
+        })
+    }
+}
+
+kernel::module_platform_driver! {
+    type: SampleSocDriver,
+    name: "rust_soc",
+    authors: ["Matthew Maurer"],
+    description: "Rust SoC Driver",
+    license: "GPL",
+}

-- 
2.52.0.351.gbe84eed79e-goog
Re: [PATCH v4 3/3] rust: Add SoC Driver Sample
Posted by Kari Argillander 1 month, 1 week ago
On Fri, 26 Dec 2025 at 22:18, Matthew Maurer <mmaurer@google.com> wrote:

> +    fn probe(
> +        pdev: &platform::Device<Core>,
> +        _info: Option<&Self::IdInfo>,
> +    ) -> impl PinInit<Self, Error> {
> +        let dev = pdev.as_ref();
> +
> +        dev_dbg!(dev, "Probe Rust SoC driver sample.\n");
> +
> +        let pdev = pdev.into();
> +        pin_init_scope(move || {
> +            let machine = CString::try_from(c"My cool ACME15 dev board")?;
> +            let family = CString::try_from(c"ACME")?;
> +            let revision = CString::try_from(c"1.2")?;
> +            let serial_number = CString::try_from(c"12345")?;
> +            let soc_id = CString::try_from(c"ACME15")?;
> +
> +            let attr = soc::Attributes {
> +                machine: Some(machine),
> +                family: Some(family),
> +                revision: Some(revision),
> +                serial_number: Some(serial_number),
> +                soc_id: Some(soc_id),
> +            };

To me it seems little bit awkward that all needs to be CStrings. Maybe something
like this could be used (basically cow)

```rust
pub enum AttrStr {
    Static(&'static CStr),
    Owned(CString),
    None,
}
```

This will also take out Option with same time. Then some nice ergonomic way
to use this. This is suggestion and I have nothing to do with soc layer.

    Argillander
Re: [PATCH v4 3/3] rust: Add SoC Driver Sample
Posted by Matthew Maurer 1 month, 1 week ago
On Sat, Dec 27, 2025 at 7:53 AM Kari Argillander
<kari.argillander@gmail.com> wrote:
>
> On Fri, 26 Dec 2025 at 22:18, Matthew Maurer <mmaurer@google.com> wrote:
>
> > +    fn probe(
> > +        pdev: &platform::Device<Core>,
> > +        _info: Option<&Self::IdInfo>,
> > +    ) -> impl PinInit<Self, Error> {
> > +        let dev = pdev.as_ref();
> > +
> > +        dev_dbg!(dev, "Probe Rust SoC driver sample.\n");
> > +
> > +        let pdev = pdev.into();
> > +        pin_init_scope(move || {
> > +            let machine = CString::try_from(c"My cool ACME15 dev board")?;
> > +            let family = CString::try_from(c"ACME")?;
> > +            let revision = CString::try_from(c"1.2")?;
> > +            let serial_number = CString::try_from(c"12345")?;
> > +            let soc_id = CString::try_from(c"ACME15")?;
> > +
> > +            let attr = soc::Attributes {
> > +                machine: Some(machine),
> > +                family: Some(family),
> > +                revision: Some(revision),
> > +                serial_number: Some(serial_number),
> > +                soc_id: Some(soc_id),
> > +            };
>
> To me it seems little bit awkward that all needs to be CStrings. Maybe something
> like this could be used (basically cow)
>
> ```rust
> pub enum AttrStr {
>     Static(&'static CStr),
>     Owned(CString),
>     None,
> }
> ```
>
> This will also take out Option with same time. Then some nice ergonomic way
> to use this. This is suggestion and I have nothing to do with soc layer.

IMO something like this should not be a SoC-specific special type.
Feel free to propose a `CowCStr` in `kernel::str`, or adding the more
general `Cow` and appropriate trait definitions to `kernel::alloc`,
and we could modify the API in the future. Basically, this seems like
a suggestion for a new vocabulary type rather than something for SoC.

We could technically also do a many-parameter'd struct and put `:
Deref<Target=CStr>` bounds on everything, but putting 6 type
parameters on something, which would then need explicit resolution
when `None` was used, seems potentially worse ergonomically.

>
>     Argillander