rust: device: implement device context for Device
authorDanilo Krummrich <dakr@kernel.org>
Sun, 13 Apr 2025 17:36:58 +0000 (19:36 +0200)
committerDanilo Krummrich <dakr@kernel.org>
Thu, 17 Apr 2025 13:21:39 +0000 (15:21 +0200)
Analogous to bus specific device, implement the DeviceContext generic
for generic devices.

This is used for APIs that work with generic devices (such as Devres) to
evaluate the device's context.

Reviewed-by: Benno Lossin <benno.lossin@proton.me>
Link: https://lore.kernel.org/r/20250413173758.12068-4-dakr@kernel.org
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
rust/kernel/device.rs

index 7b96c99879a628e7c518005daff58bdb62b51932..53a13dd4d2d4c01d5fc780238b70108ac0a5557e 100644 (file)
@@ -9,7 +9,7 @@ use crate::{
     str::CStr,
     types::{ARef, Opaque},
 };
-use core::{fmt, ptr};
+use core::{fmt, marker::PhantomData, ptr};
 
 #[cfg(CONFIG_PRINTK)]
 use crate::c_str;
@@ -42,7 +42,7 @@ use crate::c_str;
 /// `bindings::device::release` is valid to be called from any thread, hence `ARef<Device>` can be
 /// dropped from any thread.
 #[repr(transparent)]
-pub struct Device(Opaque<bindings::device>);
+pub struct Device<Ctx: DeviceContext = Normal>(Opaque<bindings::device>, PhantomData<Ctx>);
 
 impl Device {
     /// Creates a new reference-counted abstraction instance of an existing `struct device` pointer.
@@ -59,7 +59,9 @@ impl Device {
         // SAFETY: By the safety requirements ptr is valid
         unsafe { Self::as_ref(ptr) }.into()
     }
+}
 
+impl<Ctx: DeviceContext> Device<Ctx> {
     /// Obtain the raw `struct device *`.
     pub(crate) fn as_raw(&self) -> *mut bindings::device {
         self.0.get()
@@ -189,6 +191,11 @@ impl Device {
     }
 }
 
+// SAFETY: `Device` is a transparent wrapper of a type that doesn't depend on `Device`'s generic
+// argument.
+kernel::impl_device_context_deref!(unsafe { Device });
+kernel::impl_device_context_into_aref!(Device);
+
 // SAFETY: Instances of `Device` are always reference-counted.
 unsafe impl crate::types::AlwaysRefCounted for Device {
     fn inc_ref(&self) {