summaryrefslogtreecommitdiff
path: root/rust/kernel/device.rs
diff options
context:
space:
mode:
authorMarkus Probst <markus.probst@posteo.de>2025-10-27 20:06:03 +0000
committerDanilo Krummrich <dakr@kernel.org>2025-11-18 11:00:51 +1300
commite4addc7cc2dfcc19f1c8c8e47f3834b22cb21559 (patch)
tree3b64a849d11179a07ddce4592af810735b250041 /rust/kernel/device.rs
parent13ae55e24a854efd33eb84bbd19a74b933228ccd (diff)
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 <markus.probst@posteo.de> 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 <dakr@kernel.org>
Diffstat (limited to 'rust/kernel/device.rs')
-rw-r--r--rust/kernel/device.rs33
1 files changed, 33 insertions, 0 deletions
diff --git a/rust/kernel/device.rs b/rust/kernel/device.rs
index 1a307be953c2..660cb2b48c07 100644
--- a/rust/kernel/device.rs
+++ b/rust/kernel/device.rs
@@ -594,6 +594,39 @@ impl DeviceContext for Core {}
impl DeviceContext for CoreInternal {}
impl DeviceContext for Normal {}
+/// Convert device references to bus device references.
+///
+/// Bus devices can implement this trait to allow abstractions to provide the bus device in
+/// class device callbacks.
+///
+/// This must not be used by drivers and is intended for bus and class device abstractions only.
+///
+/// # Safety
+///
+/// `AsBusDevice::OFFSET` must be the offset of the embedded base `struct device` field within a
+/// bus device structure.
+pub unsafe trait AsBusDevice<Ctx: DeviceContext>: AsRef<Device<Ctx>> {
+ /// The relative offset to the device field.
+ ///
+ /// Use `offset_of!(bindings, field)` macro to avoid breakage.
+ const OFFSET: usize;
+
+ /// Convert a reference to [`Device`] into `Self`.
+ ///
+ /// # Safety
+ ///
+ /// `dev` must be contained in `Self`.
+ unsafe fn from_device(dev: &Device<Ctx>) -> &Self
+ where
+ Self: Sized,
+ {
+ let raw = dev.as_raw();
+ // SAFETY: `raw - Self::OFFSET` is guaranteed by the safety requirements
+ // to be a valid pointer to `Self`.
+ unsafe { &*raw.byte_sub(Self::OFFSET).cast::<Self>() }
+ }
+}
+
/// # Safety
///
/// The type given as `$device` must be a transparent wrapper of a type that doesn't depend on the