On Mon, Jun 9, 2025 at 12:47 PM Danilo Krummrich <dakr@xxxxxxxxxx> wrote: > > On Sun, Jun 08, 2025 at 07:51:08PM -0300, Daniel Almeida wrote: > > + dev: &'a Device<Bound>, > > + irq: u32, > > + flags: Flags, > > + name: &'static CStr, > > + handler: T, > > + ) -> impl PinInit<Self, Error> + 'a { > > + let closure = move |slot: *mut Self| { > > + // SAFETY: The slot passed to pin initializer is valid for writing. > > + unsafe { > > + slot.write(Self { > > + inner: Devres::new( > > + dev, > > + RegistrationInner { > > + irq, > > + cookie: slot.cast(), > > + }, > > + GFP_KERNEL, > > + )?, > > + handler, > > + _pin: PhantomPinned, > > + }) > > + }; > > + > > + // SAFETY: > > + // - The callbacks are valid for use with request_irq. > > + // - If this succeeds, the slot is guaranteed to be valid until the > > + // destructor of Self runs, which will deregister the callbacks > > + // before the memory location becomes invalid. > > + let res = to_result(unsafe { > > + bindings::request_irq( > > + irq, > > + Some(handle_irq_callback::<T>), > > + flags.into_inner() as usize, > > + name.as_char_ptr(), > > + slot.cast(), > > + ) > > + }); > > + > > + if res.is_err() { > > + // SAFETY: We are returning an error, so we can destroy the slot. > > + unsafe { core::ptr::drop_in_place(&raw mut (*slot).handler) }; > > + } > > + > > + res > > + }; > > + > > + // SAFETY: > > + // - if this returns Ok, then every field of `slot` is fully > > + // initialized. > > + // - if this returns an error, then the slot does not need to remain > > + // valid. > > + unsafe { pin_init_from_closure(closure) } > > Can't we use try_pin_init!() instead, move request_irq() into the initializer of > RegistrationInner and initialize inner last? We need a pointer to the entire struct when calling bindings::request_irq. I'm not sure this allows you to easily get one? I don't think using container_of! here is worth it. Alice