summaryrefslogtreecommitdiff
path: root/rust/kernel/lib.rs
diff options
context:
space:
mode:
authorJonathan Cameron <Jonathan.Cameron@huawei.com>2024-11-09 10:39:52 +0000
committerJonathan Cameron <Jonathan.Cameron@huawei.com>2024-11-09 10:39:52 +0000
commite459ca0aec9a38f71e35c83d3dcb3cadb5033334 (patch)
treed66e23adf3d366d07d1d77f7f3fc3356808fa795 /rust/kernel/lib.rs
parent56686ac80b859c2049cc372f7837470aa71c98cf (diff)
parent9365f0de4303f82ed4c2db1c39d3de824b249d80 (diff)
Merge commit '9365f0de4303f82ed4c2db1c39d3de824b249d80' into HEAD
Merge v6.12-rc6 via char-misc-next to get some fixes needed for next few patches in IIO.
Diffstat (limited to 'rust/kernel/lib.rs')
-rw-r--r--rust/kernel/lib.rs23
1 files changed, 23 insertions, 0 deletions
diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs
index 8a228bcbbe85..638c8db4ce54 100644
--- a/rust/kernel/lib.rs
+++ b/rust/kernel/lib.rs
@@ -82,6 +82,29 @@ pub trait Module: Sized + Sync + Send {
fn init(module: &'static ThisModule) -> error::Result<Self>;
}
+/// A module that is pinned and initialised in-place.
+pub trait InPlaceModule: Sync + Send {
+ /// Creates an initialiser for the module.
+ ///
+ /// It is called when the module is loaded.
+ fn init(module: &'static ThisModule) -> impl init::PinInit<Self, error::Error>;
+}
+
+impl<T: Module> InPlaceModule for T {
+ fn init(module: &'static ThisModule) -> impl init::PinInit<Self, error::Error> {
+ let initer = move |slot: *mut Self| {
+ let m = <Self as Module>::init(module)?;
+
+ // SAFETY: `slot` is valid for write per the contract with `pin_init_from_closure`.
+ unsafe { slot.write(m) };
+ Ok(())
+ };
+
+ // SAFETY: On success, `initer` always fully initialises an instance of `Self`.
+ unsafe { init::pin_init_from_closure(initer) }
+ }
+}
+
/// Equivalent to `THIS_MODULE` in the C API.
///
/// C header: [`include/linux/export.h`](srctree/include/linux/export.h)