diff --git a/drivers/char/hw_random/bcm2835_rng_rust.rs b/drivers/char/hw_random/bcm2835_rng_rust.rs index 5f3ec20b295b8f..973fda2dc538af 100644 --- a/drivers/char/hw_random/bcm2835_rng_rust.rs +++ b/drivers/char/hw_random/bcm2835_rng_rust.rs @@ -67,7 +67,7 @@ impl PlatformDriver for RngDriver { } struct RngModule { - _pdev: Pin>, + _pdev: platdev::Registration, } impl KernelModule for RngModule { @@ -75,7 +75,7 @@ impl KernelModule for RngModule { const OF_MATCH_TBL: ConstOfMatchTable<1> = ConstOfMatchTable::new_const([&c_str!("brcm,bcm2835-rng")]); - let pdev = platdev::Registration::new_pinned::( + let pdev = platdev::Registration::new::( c_str!("bcm2835-rng-rust"), Some(&OF_MATCH_TBL), &THIS_MODULE, diff --git a/rust/kernel/platdev.rs b/rust/kernel/platdev.rs index 5f306b61321e36..e443ddd57bbf52 100644 --- a/rust/kernel/platdev.rs +++ b/rust/kernel/platdev.rs @@ -15,14 +15,12 @@ use crate::{ types::PointerWrapper, }; use alloc::boxed::Box; -use core::{marker::PhantomPinned, pin::Pin}; /// A registration of a platform device. #[derive(Default)] pub struct Registration { - registered: bool, - pdrv: bindings::platform_driver, - _pin: PhantomPinned, + // We never move out of `pdrv`'s `Box`. + pdrv: Box, } // SAFETY: `Registration` does not expose any of its state across threads @@ -79,62 +77,41 @@ extern "C" fn remove_callback( } impl Registration { - fn register( - self: Pin<&mut Self>, + /// Registers a platform device. + /// + /// Returns a representation of the registration. + pub fn new( name: &'static CStr, of_match_table: Option<&'static OfMatchTable>, module: &'static crate::ThisModule, - ) -> Result { - // SAFETY: We must ensure that we never move out of `this`. - let this = unsafe { self.get_unchecked_mut() }; - if this.registered { - // Already registered. - return Err(Error::EINVAL); - } - this.pdrv.driver.name = name.as_char_ptr(); + ) -> Result { + let mut pdrv = Box::try_new(bindings::platform_driver::default())?; + pdrv.driver.name = name.as_char_ptr(); if let Some(tbl) = of_match_table { - this.pdrv.driver.of_match_table = tbl.as_ptr(); + pdrv.driver.of_match_table = tbl.as_ptr(); } - this.pdrv.probe = Some(probe_callback::

); - this.pdrv.remove = Some(remove_callback::

); + pdrv.probe = Some(probe_callback::

); + pdrv.remove = Some(remove_callback::

); // SAFETY: - // - `this.pdrv` lives at least until the call to `platform_driver_unregister()` returns. - // - `name` pointer has static lifetime. + // - `pdrv` will never move out of its `Box`, and lives at least + // until the call to `platform_driver_unregister()` returns. // - `module.0` lives at least as long as the module. // - `probe()` and `remove()` are static functions. // - `of_match_table` is either a raw pointer with static lifetime, // as guaranteed by the [`of::OfMatchTable::as_ptr()`] return type, // or null. - let ret = unsafe { bindings::__platform_driver_register(&mut this.pdrv, module.0) }; + let ret = unsafe { bindings::__platform_driver_register(&mut *pdrv, module.0) }; if ret < 0 { return Err(Error::from_kernel_errno(ret)); } - this.registered = true; - Ok(()) - } - - /// Registers a platform device. - /// - /// Returns a pinned heap-allocated representation of the registration. - pub fn new_pinned( - name: &'static CStr, - of_match_tbl: Option<&'static OfMatchTable>, - module: &'static crate::ThisModule, - ) -> Result>> { - let mut r = Pin::from(Box::try_new(Self::default())?); - r.as_mut().register::

(name, of_match_tbl, module)?; - Ok(r) + Ok(Self { pdrv }) } } impl Drop for Registration { fn drop(&mut self) { - if self.registered { - // SAFETY: if `registered` is true, then `self.pdev` was registered - // previously, which means `platform_driver_unregister` is always - // safe to call. - unsafe { bindings::platform_driver_unregister(&mut self.pdrv) } - } + // SAFETY: `self.pdev` was registered previously. + unsafe { bindings::platform_driver_unregister(&mut *self.pdrv) } } }