Hi Lyude, > On 30 Sep 2024, at 20:10, Lyude Paul <lyude@xxxxxxxxxx> wrote: > > Same thing as OpaquePlane, but for encoders now. > > Signed-off-by: Lyude Paul <lyude@xxxxxxxxxx> > > --- > > TODO: > * Add upcast functions for this > > Signed-off-by: Lyude Paul <lyude@xxxxxxxxxx> > --- > rust/kernel/drm/kms/encoder.rs | 55 ++++++++++++++++++++++++++++++++++ > 1 file changed, 55 insertions(+) > > diff --git a/rust/kernel/drm/kms/encoder.rs b/rust/kernel/drm/kms/encoder.rs > index 3ae597093645e..71fae45d2d651 100644 > --- a/rust/kernel/drm/kms/encoder.rs > +++ b/rust/kernel/drm/kms/encoder.rs > @@ -235,6 +235,61 @@ pub fn new<'a, 'b: 'a>( > } > } > > +/// A [`struct drm_encoder`] without a known [`DriverEncoder`] implementation. > +/// > +/// This is mainly for situations where our bindings can't infer the [`DriverEncoder`] implementation > +/// for a [`struct drm_encoder`] automatically. It is identical to [`Encoder`], except that it does not > +/// provide access to the driver's private data. > +/// > +/// TODO: Add functions for upcasting. > +/// > +/// # Invariants > +/// > +/// Same as [`Encoder`]. > +#[repr(transparent)] > +pub struct OpaqueEncoder<T: KmsDriver> { > + encoder: Opaque<bindings::drm_encoder>, > + _p: PhantomData<T>, > +} > + > +impl<T: KmsDriver> Sealed for OpaqueEncoder<T> {} > + > +// SAFETY: All of our encoder interfaces are thread-safe > +unsafe impl<T: KmsDriver> Send for OpaqueEncoder<T> {} > + > +// SAFETY: All of our encoder interfaces are thread-safe > +unsafe impl<T: KmsDriver> Sync for OpaqueEncoder<T> {} > + > +impl<T: KmsDriver> ModeObject for OpaqueEncoder<T> { > + type Driver = T; > + > + fn drm_dev(&self) -> &Device<Self::Driver> { > + // SAFETY: DRM encoders exist for as long as the device does, so this pointer is always > + // valid > + unsafe { Device::borrow((*self.encoder.get()).dev) } > + } > + > + fn raw_mode_obj(&self) -> *mut bindings::drm_mode_object { > + // SAFETY: We don't expose Encoder<T> to users before it's initialized, so `base` is always > + // initialized > + unsafe { addr_of_mut!((*self.encoder.get()).base) } > + } > +} > + > +// SAFETY: Encoders do not have a refcount > +unsafe impl<T: KmsDriver> StaticModeObject for OpaqueEncoder<T> {} > + > +impl<T: KmsDriver> AsRawEncoder for OpaqueEncoder<T> { > + fn as_raw(&self) -> *mut bindings::drm_encoder { > + self.encoder.get() > + } > + > + unsafe fn from_raw<'a>(ptr: *mut bindings::drm_encoder) -> &'a Self { > + // SAFETY: Our data layout is identical to `bindings::drm_encoder` > + unsafe { &*ptr.cast() } > + } > +} > + > unsafe extern "C" fn encoder_destroy_callback<T: DriverEncoder>( > encoder: *mut bindings::drm_encoder > ) { > -- > 2.46.1 > No `from_opaque` and `try_from_opaque` like the previous patches? — Daniel