# Meeting 2025-08-06 <!-- Leave your topic starting with ### in the relevant sections below --> ## Critical <!-- bugs, soundness issues, urgent patches/reviews etc. --> ## Status Reports <!-- You want to report on something you are working on/request reviews. Or you want to know the status of something someone else is doing --> ## Discussion Questions <!-- Anything that requires lengthy discussion/more general questions also fit here --> ### Wrapping `Regulator<T>` and `Clk<T>` in Devres Our current design for Regulators and Clks use the typestate pattern to model the underlying reference counts and the transition between states. This works, but Danilo pointed out that these types must be wrapped in Devres, as they are device-bound resources that must be revoked once the underlying Device is unbound. I've been working on this for a few days, and it's been hard to implement owing to the fact that the transitions consume `self`. For example, how should this be written now, given the Devres that will wrap `Regulator<T>`? ```rust /// Attempts to convert the regulator to an enabled state. pub fn try_into_enabled(self) -> Result<Regulator<Enabled>, Error<Disabled>> { // We will be transferring the ownership of our `regulator_get()` count to // `Regulator<Enabled>`. let regulator = ManuallyDrop::new(self); regulator .enable_internal() .map(|()| Regulator { inner: regulator.inner, _phantom: PhantomData, }) .map_err(|error| Error { error, regulator: ManuallyDrop::into_inner(regulator), }) } ``` What is the argument? impl `PinInit<T>`? How can we keep consuming self here? What if the type has already been initialized in the slot? Note that Benno said that both Regulator and Clks should probably use `ARef`, but I feel that this should go into a separate patch, if at all. My current idea to get around the problem of consuming self is this: ```rust struct Regulator<T> { inner: Devres<NonNull<bindings::regulator>>, phantom: PhantomData<T>, } ``` This moves the Devres inside the type, such that the signatures for all functions remain the same (i.e.: they still take self), and the `Devres` is simply moved. This means that a single allocation will be required, regardless of how many state transitions take place. On top of that, I was also thinking about adding a new type: ```rust struct RegulatorInner<'a, T> { regulator: Regulator<T>, dev: &'a Device<Bound>, } ``` So users can do this: ```rust let regulator: RegulatorInner<'_, T> = driver_data.regulator.access(&dev); ``` Benno: In general the typestate pattern doesn't work well with types that should be embedded in structs. it plays especially poorly with pinned/reference counted structs. So I'm not sure we should use that pattern with those types. Now for the specific `Clk` and `Regulator` cases, I'm not sure. Some discussions: Option 1 ```rust Box<Devres<ARef<Regulator>>> ``` Option 2 (from Benno), maybe we can do ```rust ARef<Devres<Regualtor>> ``` Andreas: does it make sense to not use `Devres` at all for `Clk` and `Regulator`. Danilo: That's doable but it might be easy to mess up, you will need to store a reference (e.g. `ARef` ) in your driver/device data. However, if `Devres` solution requires more work, we probably could just go without having a `Devres` around. Daniel: The reference is the `Regulator<T>` itself, not `ARef<Regulator>`. ```rust= unsafe impl AlwaysRefCounted for Regulator<Disabled> { // only use `regulator_get` } unsafe impl AlwaysRefCounted for Regulator<Enabled> { // use `regulator_get` & `regulator_enable` } unsafe impl AlwaysRefCounted for Regulator<Dynamic> { // ??? } ``` ```rust= struct RegulatorWithDevice<'a, T> { } impl<T> RegulatorWithDevice<'a, T> { pub fn get_voltage(&self) {} } struct Regulator<T> { inner: Pin<Box<Devres<Inner>>>, phantom: ... } impl<T> Regulator<T> { pub fn get_voltage(&self, dev: &Device<Bound>) {} } impl Deref for Regulator<T> { type Target = Devres<Inner<T>>; fn deref(&self) -> &Devres<Inner<T>> { &self.inner } } struct Inner<T> { inner: NonNull<bindings::regulator>, } ``` ## Miscellaneous <!-- stuff that does not fit into other categories -->