Skip to contentSkip to conversation

rust: devres: provide an accessor for the device

PATCH In review Danilo Krummrich 3 participants 12 messages Jul 13, 2025 – Jul 15, 2025

Subsystems (2)
lore
Share & tools
lore

Danilo Krummrich

author maintainer
#0 lore raw

PATCH 1/2 rust: devres: provide an accessor for the device

Provide an accessor for the Device a Devres instance has been created with.

For instance, this is useful when registrations want to provide a &Device<Bound> for a scope that is protected by Devres.

---
 rust/kernel/devres.rs | 5 +++++
 1 file changed, 5 insertions(+)
rust/kernel/devres.rs +5 -0
index f43de3d77d61..a8a2d24cac24 100644
@@ -204,6 +204,11 @@ fn remove_action(&self) -> bool {
         } == 0)
     }
 
+    /// Return a reference of the [`Device`] this [`Devres`] instance has been created with.
+    pub fn device(&self) -> &Device {
+        &self.dev
+    }
+
     /// Obtain `&'a T`, bypassing the [`Revocable`].
     ///
     /// This method allows to directly obtain a `&'a T`, bypassing the [`Revocable`], by presenting

base-commit: 3964d07dd821efe9680e90c51c86661a98e60a0f

Signature · 1 line
2.50.0
author maintainer
#1 lore raw

PATCH 2/2 rust: device: implement Device::as_bound()

Provide an unsafe functions for abstractions to convert a regular &Device to a &Device<Bound>.

This is useful for registrations that provide certain guarantees for the scope of their callbacks, such as IRQs or certain class device registrations (e.g. PWM, miscdevice).

---
 rust/kernel/device.rs | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)
rust/kernel/device.rs +19 -0
index d527ceef829e..4d9b052afe92 100644
@@ -60,6 +60,25 @@ pub unsafe fn get_device(ptr: *mut bindings::device) -> ARef<Self> {
         // SAFETY: By the safety requirements ptr is valid
         unsafe { Self::as_ref(ptr) }.into()
     }
+
+    /// Convert a [`&Device`](Device) into a [`&Device<Bound>`](Device<Bound>).
+    ///
+    /// # Safety
+    ///
+    /// The caller is responsible to ensure that the returned [`&Device<Bound>`](Device<Bound>)
+    /// only lives as long as it can be guaranteed that the [`Device`] is actually bound.
+    pub unsafe fn as_bound(&self) -> &Device<Bound> {
+        let ptr = core::ptr::from_ref(self);
+
+        // CAST: By the safety requirements the caller is responsible to guarantee that the
+        // returned reference only lives as long as the device is actually bound.
+        let ptr = ptr.cast::<Device<Bound>>();
+
+        // SAFETY:
+        // - `ptr` comes from `from_ref(self)` above, hence it's guaranteed to be valid.
+        // - Any valid `Device` pointer is also a valid pointer for `Device<Bound>`.
+        unsafe { &*ptr.cast() }
+    }
 }
 
 impl Device<CoreInternal> {
Signature · 1 line
2.50.0
author maintainer
#2 lore raw

Re: [PATCH 2/2] rust: device: implement Device::as_bound()

Quoted 30 lines · Danilo Krummrich

Provide an unsafe functions for abstractions to convert a regular &Device to a &Device<Bound>.

This is useful for registrations that provide certain guarantees for the scope of their callbacks, such as IRQs or certain class device registrations (e.g. PWM, miscdevice).

---
 rust/kernel/device.rs | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)
rust/kernel/device.rs +10 -0
index d527ceef829e..4d9b052afe92 100644
@@ -60,6 +60,25 @@ pub unsafe fn get_device(ptr: *mut bindings::device) -> ARef<Self> {
         // SAFETY: By the safety requirements ptr is valid
         unsafe { Self::as_ref(ptr) }.into()
     }
+
+    /// Convert a [`&Device`](Device) into a [`&Device<Bound>`](Device<Bound>).
+    ///
+    /// # Safety
+    ///
+    /// The caller is responsible to ensure that the returned [`&Device<Bound>`](Device<Bound>)
+    /// only lives as long as it can be guaranteed that the [`Device`] is actually bound.
+    pub unsafe fn as_bound(&self) -> &Device<Bound> {
+        let ptr = core::ptr::from_ref(self);
+

rust/kernel/device.rs pub unsafe fn get_device(ptr: *mut bindings::device) -> ARef<Self> { · line 82

Quoted 10 lines
rust/kernel/device.rs +9 -0
+        // CAST: By the safety requirements the caller is responsible to guarantee that the
+        // returned reference only lives as long as the device is actually bound.
+        let ptr = ptr.cast::<Device<Bound>>();
+
+        // SAFETY:
+        // - `ptr` comes from `from_ref(self)` above, hence it's guaranteed to be valid.
+        // - Any valid `Device` pointer is also a valid pointer for `Device<Bound>`.
+        unsafe { &*ptr.cast() }
+    }
 }
rust/kernel/device.rs +2 -2
index 4d9b052afe92..b6b81546a0da 100644
@@ -72,12 +72,12 @@ pub unsafe fn as_bound(&self) -> &Device<Bound> {
 
         // CAST: By the safety requirements the caller is responsible to guarantee that the
         // returned reference only lives as long as the device is actually bound.
-        let ptr = ptr.cast::<Device<Bound>>();
+        let ptr = ptr.cast();
 
         // SAFETY:
         // - `ptr` comes from `from_ref(self)` above, hence it's guaranteed to be valid.
         // - Any valid `Device` pointer is also a valid pointer for `Device<Bound>`.
-        unsafe { &*ptr.cast() }
+        unsafe { &*ptr }
     }
 }
reviewer Reviewed-by on v1 2/2
#3 lore raw

Re: [PATCH 2/2] rust: device: implement Device::as_bound()

In reply to Danilo Krummrich
Quoted 8 lines · Danilo Krummrich

Provide an unsafe functions for abstractions to convert a regular &Device to a &Device<Bound>.

This is useful for registrations that provide certain guarantees for the scope of their callbacks, such as IRQs or certain class device registrations (e.g. PWM, miscdevice).

---
Cheers,
Benno

Quoted 3 lines
---
 rust/kernel/device.rs | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)
maintainer
#4 lore raw

Re: [PATCH 2/2] rust: device: implement Device::as_bound()

In reply to Danilo Krummrich
Quoted 6 lines · Danilo Krummrich

Provide an unsafe functions for abstractions to convert a regular &Device to a &Device<Bound>.

This is useful for registrations that provide certain guarantees for the scope of their callbacks, such as IRQs or certain class device registrations (e.g. PWM, miscdevice).

Do we have an example where this can be used today in the tree, or is this only for new stuff going forward that would use it?

thanks,

greg k-h

author maintainer
#5 lore raw

Re: [PATCH 2/2] rust: device: implement Device::as_bound()

Quoted 10 lines · Greg KH
Quoted 6 lines · Danilo Krummrich

Provide an unsafe functions for abstractions to convert a regular &Device to a &Device<Bound>.

This is useful for registrations that provide certain guarantees for the scope of their callbacks, such as IRQs or certain class device registrations (e.g. PWM, miscdevice).

Do we have an example where this can be used today in the tree, or is this only for new stuff going forward that would use it?

There's miscdevice in tree, but to be fair, miscdevice doesn't need it without my patch series [1] adding driver support for the existing miscdevice abstractions; the patch in [2] out of this series would use it within args_from_registration().

The PWM abstractions [3] need it in bound_parent_device(). The use-case is the same as everywhere else, PWM chips never out-live driver unbind, hence they can provide the corresponding bus device as &Device<Bound>.

The same is true for IRQ registrations [4]. free_irq() is guaranteed to be called before driver unbind, hence we can provide a &Device<Bound> in the IRQ callbacks.

Ultimately, we want to provide this "cookie" in any driver scope that can be proven to be lifetime wise limited to device / driver unbind, so there'll be much more users.

[1] https://lore.kernel.org/lkml/[email protected]/
[2] https://lore.kernel.org/lkml/[email protected]/
[3] https://lore.kernel.org/lkml/20250710-rust-next-pwm-working-fan-for-sending-v11-3-93824a16f9ec@samsung.com/
[4] https://lore.kernel.org/lkml/[email protected]/

maintainer
#6 lore raw

Re: [PATCH 2/2] rust: device: implement Device::as_bound()

Quoted 21 lines · Danilo Krummrich
Quoted 10 lines · Greg KH
Quoted 6 lines · Danilo Krummrich

Provide an unsafe functions for abstractions to convert a regular &Device to a &Device<Bound>.

This is useful for registrations that provide certain guarantees for the scope of their callbacks, such as IRQs or certain class device registrations (e.g. PWM, miscdevice).

Do we have an example where this can be used today in the tree, or is this only for new stuff going forward that would use it?

There's miscdevice in tree, but to be fair, miscdevice doesn't need it without my patch series [1] adding driver support for the existing miscdevice abstractions; the patch in [2] out of this series would use it within args_from_registration().

The PWM abstractions [3] need it in bound_parent_device(). The use-case is the same as everywhere else, PWM chips never out-live driver unbind, hence they can provide the corresponding bus device as &Device<Bound>.

Quoted 7 lines

The same is true for IRQ registrations [4]. free_irq() is guaranteed to be called before driver unbind, hence we can provide a &Device<Bound> in the IRQ callbacks.

Ultimately, we want to provide this "cookie" in any driver scope that can be proven to be lifetime wise limited to device / driver unbind, so there'll be much more users.

Ok, so we should probably merge it now for 6.17-rc1, no objection from me!

thanks,

greg k-h

author maintainer
#7 lore raw

Re: [PATCH 2/2] rust: device: implement Device::as_bound()

Quoted 26 lines · Greg KH
Quoted 25 lines · Danilo Krummrich
Quoted 10 lines · Greg KH
Quoted 6 lines · Danilo Krummrich

Provide an unsafe functions for abstractions to convert a regular &Device to a &Device<Bound>.

This is useful for registrations that provide certain guarantees for the scope of their callbacks, such as IRQs or certain class device registrations (e.g. PWM, miscdevice).

Do we have an example where this can be used today in the tree, or is this only for new stuff going forward that would use it?

There's miscdevice in tree, but to be fair, miscdevice doesn't need it without my patch series [1] adding driver support for the existing miscdevice abstractions; the patch in [2] out of this series would use it within args_from_registration().

The PWM abstractions [3] need it in bound_parent_device(). The use-case is the same as everywhere else, PWM chips never out-live driver unbind, hence they can provide the corresponding bus device as &Device<Bound>.

The same is true for IRQ registrations [4]. free_irq() is guaranteed to be called before driver unbind, hence we can provide a &Device<Bound> in the IRQ callbacks.

Quoted 6 lines
Quoted 3 lines

Ultimately, we want to provide this "cookie" in any driver scope that can be proven to be lifetime wise limited to device / driver unbind, so there'll be much more users.

Ok, so we should probably merge it now for 6.17-rc1, no objection from me!

Yup, gonna pick it up soon (with the casts fixed up as noted in a previous reply). :)

author maintainer
#8 lore raw

Re: [PATCH 2/2] rust: device: implement Device::as_bound()

In reply to Danilo Krummrich
Quoted 8 lines · Danilo Krummrich

Provide an unsafe functions for abstractions to convert a regular &Device to a &Device<Bound>.

This is useful for registrations that provide certain guarantees for the scope of their callbacks, such as IRQs or certain class device registrations (e.g. PWM, miscdevice).

Applied to driver-core-testing, thanks!

[ Remove unnecessary cast(). - Danilo ]

reviewer Reviewed-by on v1 1/2
#9 lore raw
In reply to Danilo Krummrich
Quoted 8 lines · Danilo Krummrich

Provide an accessor for the Device a Devres instance has been created with.

For instance, this is useful when registrations want to provide a &Device<Bound> for a scope that is protected by Devres.

---
Cheers,
Benno

Quoted 3 lines
---
 rust/kernel/devres.rs | 5 +++++
 1 file changed, 5 insertions(+)
maintainer Acked-by on v1 1/2
#10 lore raw
In reply to Danilo Krummrich
Quoted 11 lines · Danilo Krummrich

Provide an accessor for the Device a Devres instance has been created with.

For instance, this is useful when registrations want to provide a &Device<Bound> for a scope that is protected by Devres.

---
 rust/kernel/devres.rs | 5 +++++
 1 file changed, 5 insertions(+)