From 0242623384c767b1156b61b67894b4ecf6682b8b Mon Sep 17 00:00:00 2001 From: Danilo Krummrich Date: Thu, 16 Oct 2025 14:55:28 +0200 Subject: rust: driver: let probe() return impl PinInit The driver model defines the lifetime of the private data stored in (and owned by) a bus device to be valid from when the driver is bound to a device (i.e. from successful probe()) until the driver is unbound from the device. This is already taken care of by the Rust implementation of the driver model. However, we still ask drivers to return a Result>> from probe(). Unlike in C, where we do not have the concept of initializers, but rather deal with uninitialized memory, drivers can just return an impl PinInit instead. This contributes to more clarity to the fact that a driver returns it's device private data in probe() and the Rust driver model owns the data, manages the lifetime and - considering the lifetime - provides (safe) accessors for the driver. Hence, let probe() functions return an impl PinInit instead of Result>>. Reviewed-by: Alice Ryhl Acked-by: Viresh Kumar Reviewed-by: Alexandre Courbot Acked-by: Greg Kroah-Hartman Signed-off-by: Danilo Krummrich --- rust/kernel/platform.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'rust/kernel/platform.rs') diff --git a/rust/kernel/platform.rs b/rust/kernel/platform.rs index 7205fe3416d3..043721fdb6d8 100644 --- a/rust/kernel/platform.rs +++ b/rust/kernel/platform.rs @@ -74,9 +74,9 @@ impl Adapter { let info = ::id_info(pdev.as_ref()); from_result(|| { - let data = T::probe(pdev, info)?; + let data = T::probe(pdev, info); - pdev.as_ref().set_drvdata(data); + pdev.as_ref().set_drvdata(data)?; Ok(0) }) } @@ -166,7 +166,7 @@ macro_rules! module_platform_driver { /// fn probe( /// _pdev: &platform::Device, /// _id_info: Option<&Self::IdInfo>, -/// ) -> Result>> { +/// ) -> impl PinInit { /// Err(ENODEV) /// } /// } @@ -190,8 +190,10 @@ pub trait Driver: Send { /// /// Called when a new platform device is added or discovered. /// Implementers should attempt to initialize the device here. - fn probe(dev: &Device, id_info: Option<&Self::IdInfo>) - -> Result>>; + fn probe( + dev: &Device, + id_info: Option<&Self::IdInfo>, + ) -> impl PinInit; /// Platform driver unbind. /// -- cgit From 6bbaa93912bfdfd5ffdc804275cc6a444c9400af Mon Sep 17 00:00:00 2001 From: Danilo Krummrich Date: Tue, 21 Oct 2025 00:34:23 +0200 Subject: rust: device: narrow the generic of drvdata_obtain() Let T be the actual private driver data type without the surrounding box, as it leaves less room for potential bugs. Reviewed-by: Alice Ryhl Reviewed-by: Greg Kroah-Hartman Signed-off-by: Danilo Krummrich --- rust/kernel/platform.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'rust/kernel/platform.rs') diff --git a/rust/kernel/platform.rs b/rust/kernel/platform.rs index 043721fdb6d8..8f7522c4cf89 100644 --- a/rust/kernel/platform.rs +++ b/rust/kernel/platform.rs @@ -91,7 +91,7 @@ impl Adapter { // SAFETY: `remove_callback` is only ever called after a successful call to // `probe_callback`, hence it's guaranteed that `Device::set_drvdata()` has been called // and stored a `Pin>`. - let data = unsafe { pdev.as_ref().drvdata_obtain::>>() }; + let data = unsafe { pdev.as_ref().drvdata_obtain::() }; T::unbind(pdev, data.as_ref()); } -- cgit From b892ed360de8227d700ef010b08564f87ad3a7ce Mon Sep 17 00:00:00 2001 From: Danilo Krummrich Date: Mon, 3 Nov 2025 21:30:13 +0100 Subject: rust: platform: get rid of redundant Result in IRQ methods Currently request_irq_by_index() returns Result, Error> + 'a> which may carry an error in the Result or the initializer; the same is true for the other IRQ methods. Use pin_init::pin_init_scope() to get rid of this redundancy. Reviewed-by: Alice Ryhl Link: https://patch.msgid.link/20251103203053.2348783-2-dakr@kernel.org Signed-off-by: Danilo Krummrich --- rust/kernel/platform.rs | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) (limited to 'rust/kernel/platform.rs') diff --git a/rust/kernel/platform.rs b/rust/kernel/platform.rs index 8f7522c4cf89..f4b617c570be 100644 --- a/rust/kernel/platform.rs +++ b/rust/kernel/platform.rs @@ -301,15 +301,17 @@ macro_rules! define_irq_accessor_by_index { index: u32, name: &'static CStr, handler: impl PinInit + 'a, - ) -> Result, Error> + 'a> { - let request = self.$request_fn(index)?; - - Ok(irq::$reg_type::::new( - request, - flags, - name, - handler, - )) + ) -> impl PinInit, Error> + 'a { + pin_init::pin_init_scope(move || { + let request = self.$request_fn(index)?; + + Ok(irq::$reg_type::::new( + request, + flags, + name, + handler, + )) + }) } }; } @@ -325,18 +327,20 @@ macro_rules! define_irq_accessor_by_name { pub fn $fn_name<'a, T: irq::$handler_trait + 'static>( &'a self, flags: irq::Flags, - irq_name: &CStr, + irq_name: &'a CStr, name: &'static CStr, handler: impl PinInit + 'a, - ) -> Result, Error> + 'a> { - let request = self.$request_fn(irq_name)?; - - Ok(irq::$reg_type::::new( - request, - flags, - name, - handler, - )) + ) -> impl PinInit, Error> + 'a { + pin_init::pin_init_scope(move || { + let request = self.$request_fn(irq_name)?; + + Ok(irq::$reg_type::::new( + request, + flags, + name, + handler, + )) + }) } }; } -- cgit From e4addc7cc2dfcc19f1c8c8e47f3834b22cb21559 Mon Sep 17 00:00:00 2001 From: Markus Probst Date: Mon, 27 Oct 2025 20:06:03 +0000 Subject: rust: Add trait to convert a device reference to a bus device reference Implement the `AsBusDevice` trait for converting a `Device` reference to a bus device reference for all bus devices. The `AsBusDevice` trait allows abstractions to provide the bus device in class device callbacks. It must not be used by drivers and is intended for bus and class device abstractions only. Signed-off-by: Markus Probst Link: https://patch.msgid.link/20251027200547.1038967-2-markus.probst@posteo.de [ * Remove unused import. * Change visibility of AsBusDevice to public. * Fix build for USB. * Add impl for I2cClient. - Danilo ] Signed-off-by: Danilo Krummrich --- rust/kernel/platform.rs | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'rust/kernel/platform.rs') diff --git a/rust/kernel/platform.rs b/rust/kernel/platform.rs index f4b617c570be..ed889f079cab 100644 --- a/rust/kernel/platform.rs +++ b/rust/kernel/platform.rs @@ -19,6 +19,7 @@ use crate::{ use core::{ marker::PhantomData, + mem::offset_of, ptr::{addr_of_mut, NonNull}, }; @@ -287,6 +288,12 @@ impl Device { } } +// SAFETY: `platform::Device` is a transparent wrapper of `struct platform_device`. +// The offset is guaranteed to point to a valid device field inside `platform::Device`. +unsafe impl device::AsBusDevice for Device { + const OFFSET: usize = offset_of!(bindings::platform_device, dev); +} + macro_rules! define_irq_accessor_by_index { ( $(#[$meta:meta])* $fn_name:ident, -- cgit