From: Mike Lothian <mike@fireburn.co.uk>
To: rust-for-linux@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org,
"David Airlie" <airlied@gmail.com>,
"Simona Vetter" <simona@ffwll.ch>,
"Danilo Krummrich" <dakr@kernel.org>,
"Lyude Paul" <lyude@redhat.com>,
"Miguel Ojeda" <ojeda@kernel.org>,
"Boqun Feng" <boqun@kernel.org>, "Gary Guo" <gary@garyguo.net>,
"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
"Benno Lossin" <lossin@kernel.org>,
"Andreas Hindborg" <a.hindborg@kernel.org>,
"Alice Ryhl" <aliceryhl@google.com>,
"Trevor Gross" <tmgross@umich.edu>,
linux-kernel@vger.kernel.org,
"Mike Lothian" <mike@fireburn.co.uk>
Subject: [RFC PATCH v2 04/18] rust: drm: kms: build the kernel crate clean under -Znext-solver
Date: Fri, 3 Jul 2026 04:00:51 +0100 [thread overview]
Message-ID: <20260703030123.2814-5-mike@fireburn.co.uk> (raw)
In-Reply-To: <20260703030123.2814-1-mike@fireburn.co.uk>
The coinductive cycle from the previous commit isn't a bug in this
port -- it's inherent to the mutual type Driver / type State / type
Crtc references in the mode-object traits, and the current trait
solver can't evaluate a coinductive obligation without unbounded
memory, regardless of where the bounds are placed. Disabling the
unused from_opaque-on-state impls doesn't help either: their errors
were masking the same explosion one level down.
The next-generation trait solver (-Znext-solver) does handle it. Scope
it to the kernel crate only in rust/Makefile rather than globally, so
core/alloc/etc. stay on the old solver -- core.o ICEs under
-Znext-solver on this toolchain, and there's no reason to pay that
cost crate-wide when only kernel/ needs the new solver's coinductive
support.
rust/kernel.o now builds with 0 errors, safe KMS layer included. Fixes
needed to get there once the solver could actually evaluate the web:
restore the pinned associated-type bounds (no back-edge cuts needed
under the new solver); add Device::event_lock(), ModeConfigGuard::new();
import AlwaysRefCounted/SpinLockIrq; Driver*::new() takes
&Device<.., Uninit> since objects are created during probe; base drift
in drm_crtc_helper_funcs (drop mode_set_base_atomic, add
handle_vblank_timeout); device.rs T::Object::<Uninit>::ALLOC_OPS and a
probe_kms Option rewrite; driver.rs captures preferred_fourcc and uses
the registered device after mem::forget(drm); unused imports dropped;
allow(dead_code) on the not-yet-used ModeObjectVtable.
Signed-off-by: Mike Lothian <mike@fireburn.co.uk>
Assisted-by: Claude:claude-sonnet-5 [Claude-Code]
---
rust/Makefile | 6 ++--
rust/kernel/drm/device.rs | 12 ++++----
rust/kernel/drm/driver.rs | 8 ++---
rust/kernel/drm/kms.rs | 51 +++++++++++++++++++++++---------
rust/kernel/drm/kms/connector.rs | 31 ++++++-------------
rust/kernel/drm/kms/crtc.rs | 35 ++++++++--------------
rust/kernel/drm/kms/encoder.rs | 4 +--
rust/kernel/drm/kms/modes.rs | 5 ++++
rust/kernel/drm/kms/plane.rs | 31 ++++++-------------
rust/kernel/drm/kms/vblank.rs | 7 ++---
10 files changed, 91 insertions(+), 99 deletions(-)
diff --git a/rust/Makefile b/rust/Makefile
index a870d1616c71..9aa985e21905 100644
--- a/rust/Makefile
+++ b/rust/Makefile
@@ -270,7 +270,7 @@ rustdoc-kernel: private is-kernel-object := y
rustdoc-kernel: private rustc_target_flags = --extern ffi --extern pin_init \
--extern build_error --extern macros \
--extern bindings --extern uapi \
- --extern zerocopy --extern zerocopy_derive
+ --extern zerocopy --extern zerocopy_derive -Znext-solver
rustdoc-kernel: $(src)/kernel/lib.rs rustdoc-core rustdoc-ffi rustdoc-macros \
rustdoc-pin_init rustdoc-compiler_builtins $(obj)/$(libmacros_name) \
$(obj)/bindings.o FORCE
@@ -342,7 +342,7 @@ rusttestlib-pin_init: $(src)/pin-init/src/lib.rs rusttestlib-macros \
rusttestlib-kernel: private rustc_target_flags = --extern ffi \
--extern build_error --extern macros --extern pin_init \
--extern bindings --extern uapi \
- --extern zerocopy --extern zerocopy_derive
+ --extern zerocopy --extern zerocopy_derive -Znext-solver
rusttestlib-kernel: $(src)/kernel/lib.rs rusttestlib-bindings rusttestlib-uapi \
rusttestlib-build_error rusttestlib-pin_init $(obj)/$(libmacros_name) \
$(obj)/bindings.o rusttestlib-zerocopy rusttestlib-zerocopy_derive FORCE
@@ -764,7 +764,7 @@ $(obj)/uapi.o: $(src)/uapi/lib.rs \
$(obj)/kernel.o: private rustc_target_flags = --extern ffi --extern pin_init \
--extern build_error --extern macros --extern bindings --extern uapi \
- --extern zerocopy --extern zerocopy_derive
+ --extern zerocopy --extern zerocopy_derive -Znext-solver
$(obj)/kernel.o: $(src)/kernel/lib.rs $(obj)/build_error.o $(obj)/pin_init.o \
$(obj)/$(libmacros_name) $(obj)/bindings.o $(obj)/uapi.o \
$(obj)/zerocopy.o $(obj)/$(libzerocopy_derive_name) FORCE
diff --git a/rust/kernel/drm/device.rs b/rust/kernel/drm/device.rs
index 9641102bd87f..5b84ce18fb29 100644
--- a/rust/kernel/drm/device.rs
+++ b/rust/kernel/drm/device.rs
@@ -229,7 +229,7 @@ const fn compute_features() -> u32 {
dumb_map_offset: T::Object::<Uninit>::ALLOC_OPS.dumb_map_offset,
show_fdinfo: None,
- fbdev_probe: T::Object::ALLOC_OPS.fbdev_probe,
+ fbdev_probe: T::Object::<Uninit>::ALLOC_OPS.fbdev_probe,
major: T::INFO.major,
minor: T::INFO.minor,
@@ -306,15 +306,17 @@ pub fn new(
// won't be called during its lifetime and that the device is unregistered.
let drm_dev = unsafe { ARef::from_raw(raw_drm) };
- let mode_config_info = drm::Device::<T>::has_kms().then(|| {
+ let mode_config_info = if drm::Device::<T>::has_kms() {
// SAFETY: This is the only place that we call probe_kms
- unsafe { T::Kms::probe_kms(&drm_dev)? }
- });
+ Some(unsafe { T::Kms::probe_kms(&drm_dev)? })
+ } else {
+ None
+ };
Ok(Self {
// SAFETY: We just completed all of the initialization steps for this device.
dev: unsafe { mem::transmute(drm_dev) },
- preferred_fourcc: mode_config_info.preferred_fourcc,
+ preferred_fourcc: mode_config_info.and_then(|i| i.preferred_fourcc),
_p: NotThreadSafe,
})
}
diff --git a/rust/kernel/drm/driver.rs b/rust/kernel/drm/driver.rs
index c7716afabcb0..b7e80df6289e 100644
--- a/rust/kernel/drm/driver.rs
+++ b/rust/kernel/drm/driver.rs
@@ -10,7 +10,6 @@
devres,
drm::{
self,
- kms::private::KmsImpl as KmsImplPrivate,
},
error::to_result,
prelude::*,
@@ -214,6 +213,7 @@ fn new<'bound, E>(
return Err(e);
}
+ let preferred_fourcc = drm.preferred_fourcc;
// SAFETY: We just called `drm_dev_register` above
let new = NonNull::from(unsafe { drm.assume_ctx() });
@@ -226,12 +226,12 @@ fn new<'bound, E>(
#[cfg(CONFIG_DRM_CLIENT = "y")]
if drm::Device::<T>::has_kms() {
- if let Some(fourcc) = drm.preferred_fourcc {
+ if let Some(fourcc) = preferred_fourcc {
// SAFETY: We just registered `drm` above, fulfilling the C API requirements
- unsafe { bindings::drm_client_setup_with_fourcc(drm.as_raw(), fourcc) }
+ unsafe { bindings::drm_client_setup_with_fourcc(new.as_raw(), fourcc) }
} else {
// SAFETY: We just registered `drm` above, fulfilling the C API requirements
- unsafe { bindings::drm_client_setup(drm.as_raw(), ptr::null()) }
+ unsafe { bindings::drm_client_setup(new.as_raw(), ptr::null()) }
}
}
diff --git a/rust/kernel/drm/kms.rs b/rust/kernel/drm/kms.rs
index d07389fd510c..7c7e1d59c892 100644
--- a/rust/kernel/drm/kms.rs
+++ b/rust/kernel/drm/kms.rs
@@ -12,7 +12,7 @@
},
error::to_result,
prelude::*,
- sync::{aref::ARef, Mutex, MutexGuard},
+ sync::{aref::{ARef, AlwaysRefCounted}, Mutex, MutexGuard, SpinLockIrq},
};
use bindings;
use core::{
@@ -122,23 +122,25 @@ fn deref(&self) -> &Self::Target {
/// [`PhantomData<Self>`]: PhantomData
#[vtable]
pub trait KmsDriver: Driver {
- // The driver's mode-object implementations. Left *unbounded* to break a trait
- // well-formedness cycle: the natural bound (`type Crtc: DriverCrtc<Driver = Self>`, etc.)
- // makes every `T: KmsDriver` obligation pull in the mutually-recursive Driver* web, which
- // the compiler cannot evaluate (it loops in obligation processing and exhausts memory). The
- // `DriverConnector`/`DriverCrtc`/... bounds are required at the use sites as `where`-clauses
- // instead (an assumption, not an eagerly WF-checked trait-definition obligation).
- //
- // TODO: unneeded once we support multiple `Driver*` implementations per driver.
-
/// The driver's [`DriverConnector`](connector::DriverConnector) implementation.
- type Connector;
+ ///
+ /// TODO: This will be unneeded once we support multiple `DriverConnector` implementations.
+ type Connector: connector::DriverConnector<Driver = Self>;
+
/// The driver's [`DriverPlane`](plane::DriverPlane) implementation.
- type Plane;
+ ///
+ /// TODO: This will be unneeded once we support multiple `DriverPlane` implementations.
+ type Plane: plane::DriverPlane<Driver = Self>;
+
/// The driver's [`DriverCrtc`](crtc::DriverCrtc) implementation.
- type Crtc;
+ ///
+ /// TODO: This will be unneeded once we support multiple `DriverCrtc` implementations.
+ type Crtc: crtc::DriverCrtc<Driver = Self>;
+
/// The driver's [`DriverEncoder`](encoder::DriverEncoder) implementation.
- type Encoder;
+ ///
+ /// TODO: This will be unneeded once we support multiple `DriverEncoder` implementations.
+ type Encoder: encoder::DriverEncoder<Driver = Self>;
/// Return a [`ModeConfigInfo`] structure for this [`device::Device`].
fn mode_config_info(dev: &Device<Self, Uninit>) -> Result<ModeConfigInfo>
@@ -372,6 +374,13 @@ pub fn num_crtcs(&self) -> u32 {
// * num_crtc is always >= 0, so casting to u32 is fine
unsafe { (*self.as_raw()).mode_config.num_crtc as u32 }
}
+
+ /// Returns a reference to the `event` spinlock for this [`Device`].
+ #[inline]
+ pub(crate) fn event_lock(&self) -> &SpinLockIrq<()> {
+ // SAFETY: `event_lock` is initialized for as long as `self` is exposed to users.
+ unsafe { SpinLockIrq::from_raw(addr_of_mut!((*self.as_raw()).event_lock)) }
+ }
}
impl<T: KmsDriver> Device<T> {
@@ -512,6 +521,7 @@ unsafe fn dec_ref(obj: core::ptr::NonNull<Self>) {
///
/// `ModeObjectVtable::vtable()` must always return a valid pointer to the relevant mode object's
/// vtable.
+#[allow(dead_code)] // Scaffolding for future vtable-pointer comparison; see doc above.
pub(crate) unsafe trait ModeObjectVtable {
/// The type for the auto-generated vtable.
type Vtable;
@@ -539,6 +549,19 @@ pub(crate) unsafe trait ModeObjectVtable {
pub struct ModeConfigGuard<'a, T: KmsDriver>(MutexGuard<'a, ()>, PhantomData<T>);
impl<'a, T: KmsDriver> ModeConfigGuard<'a, T> {
+ /// Construct a new [`ModeConfigGuard`].
+ ///
+ /// # Safety
+ ///
+ /// The caller must ensure that `drm_device.mode_config.mutex` is acquired.
+ pub(crate) unsafe fn new(drm: &'a Device<T>) -> Self {
+ // SAFETY: Our safety contract fulfills the requirements of `MutexGuard::new()`.
+ Self(
+ unsafe { MutexGuard::new(drm.mode_config_mutex(), ()) },
+ PhantomData,
+ )
+ }
+
/// Return the [`Device`] that this [`ModeConfigGuard`] belongs to.
pub fn drm_dev(&self) -> &'a Device<T> {
let lock: *mut bindings::mutex = ptr::from_ref(self.0.lock_ref()).cast_mut().cast();
diff --git a/rust/kernel/drm/kms/connector.rs b/rust/kernel/drm/kms/connector.rs
index aca7be50e583..1c7c7b586340 100644
--- a/rust/kernel/drm/kms/connector.rs
+++ b/rust/kernel/drm/kms/connector.rs
@@ -10,7 +10,7 @@
use crate::{
alloc::KBox,
bindings,
- drm::{device::Device, kms::{NewKmsDevice, Probing}},
+ drm::{device::{Device, Uninit}, kms::{NewKmsDevice, Probing}},
error::to_result,
prelude::*,
types::{NotThreadSafe, Opaque},
@@ -139,12 +139,12 @@ pub trait DriverConnector: Send + Sync + Sized {
/// The [`DriverConnectorState`] implementation for this [`DriverConnector`].
///
/// See [`DriverConnectorState`] for more info.
- type State: DriverConnectorState<Connector = Self>;
+ type State: DriverConnectorState;
/// The constructor for creating a [`Connector`] using this [`DriverConnector`] implementation.
///
/// Drivers may use this to instantiate their [`DriverConnector`] object.
- fn new(device: &Device<Self::Driver>, args: Self::Args) -> impl PinInit<Self, Error>;
+ fn new(device: &Device<Self::Driver, Uninit>, args: Self::Args) -> impl PinInit<Self, Error>;
/// Retrieve a list of available display modes for this [`Connector`].
fn get_modes<'a>(
@@ -700,17 +700,13 @@ pub struct ConnectorState<T: DriverConnectorState> {
/// [`struct drm_connector`]: srctree/include/drm_connector.h
/// [`struct drm_connector_state`]: srctree/include/drm_connector.h
pub trait DriverConnectorState: Clone + Default + Sized {
- /// The parent [`DriverConnector`]. Unbounded to break the trait WF cycle; the
- /// `DriverConnector` bound is required at use sites instead.
- type Connector;
+ /// The parent [`DriverConnector`].
+ type Connector: DriverConnector;
}
impl<T: DriverConnectorState> Sealed for ConnectorState<T> {}
-impl<T: DriverConnectorState> AsRawConnectorState for ConnectorState<T>
-where
- T::Connector: DriverConnector,
-{
+impl<T: DriverConnectorState> AsRawConnectorState for ConnectorState<T> {
type Connector = Connector<T::Connector>;
}
@@ -724,10 +720,7 @@ unsafe fn as_raw_mut(&mut self) -> &mut bindings::drm_connector_state {
}
}
-impl<T: DriverConnectorState> FromRawConnectorState for ConnectorState<T>
-where
- T::Connector: DriverConnector,
-{
+impl<T: DriverConnectorState> FromRawConnectorState for ConnectorState<T> {
unsafe fn from_raw<'a>(ptr: *const bindings::drm_connector_state) -> &'a Self {
// Our data layout starts with `bindings::drm_connector_state`.
let ptr: *const Self = ptr.cast();
@@ -866,10 +859,7 @@ pub(super) fn new<D: KmsDriver>(
}
}
-impl<'a, T: DriverConnectorState> Deref for ConnectorStateMutator<'a, ConnectorState<T>>
-where
- T::Connector: DriverConnector,
-{
+impl<'a, T: DriverConnectorState> Deref for ConnectorStateMutator<'a, ConnectorState<T>> {
type Target = T;
fn deref(&self) -> &Self::Target {
@@ -877,10 +867,7 @@ fn deref(&self) -> &Self::Target {
}
}
-impl<'a, T: DriverConnectorState> DerefMut for ConnectorStateMutator<'a, ConnectorState<T>>
-where
- T::Connector: DriverConnector,
-{
+impl<'a, T: DriverConnectorState> DerefMut for ConnectorStateMutator<'a, ConnectorState<T>> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.state.inner
}
diff --git a/rust/kernel/drm/kms/crtc.rs b/rust/kernel/drm/kms/crtc.rs
index 4c6cb6bbdcb8..9b43501bfb58 100644
--- a/rust/kernel/drm/kms/crtc.rs
+++ b/rust/kernel/drm/kms/crtc.rs
@@ -11,7 +11,7 @@
use crate::{
alloc::KBox,
bindings,
- drm::device::Device,
+ drm::device::{Device, Uninit},
error::{from_result, to_result},
prelude::*,
types::{NotThreadSafe, Opaque},
@@ -107,8 +107,8 @@ pub trait DriverCrtc: Send + Sync + Sized {
},
mode_set_nofb: None,
mode_set_base: None,
- mode_set_base_atomic: None,
get_scanout_position: None,
+ handle_vblank_timeout: None,
},
};
@@ -124,7 +124,7 @@ pub trait DriverCrtc: Send + Sync + Sized {
/// The [`DriverCrtcState`] implementation for this [`DriverCrtc`].
///
/// See [`DriverCrtcState`] for more info.
- type State: DriverCrtcState<Crtc = Self>;
+ type State: DriverCrtcState;
/// The driver's optional hardware vblank implementation
///
@@ -135,7 +135,7 @@ pub trait DriverCrtc: Send + Sync + Sized {
/// The constructor for creating a [`Crtc`] using this [`DriverCrtc`] implementation.
///
/// Drivers may use this to instantiate their [`DriverCrtc`] object.
- fn new(device: &Device<Self::Driver>, args: &Self::Args) -> impl PinInit<Self, Error>;
+ fn new(device: &Device<Self::Driver, Uninit>, args: &Self::Args) -> impl PinInit<Self, Error>;
/// The optional [`drm_crtc_helper_funcs.atomic_check`] hook for this crtc.
///
@@ -561,9 +561,10 @@ impl<T: DriverCrtcState> Sealed for CrtcState<T> {}
/// [`struct drm_crtc`]: srctree/include/drm_crtc.h
/// [`struct drm_crtc_state`]: srctree/include/drm_crtc.h
pub trait DriverCrtcState: Clone + Default + Unpin {
- /// The parent CRTC driver for this CRTC state. Unbounded to break the trait WF cycle;
- /// the `DriverCrtc` bound is required at use sites instead.
- type Crtc;
+ /// The parent CRTC driver for this CRTC state
+ type Crtc: DriverCrtc<State = Self>
+ where
+ Self: Sized;
}
/// The main interface for a [`struct drm_crtc_state`].
@@ -701,17 +702,11 @@ fn as_raw(&self) -> *mut bindings::drm_crtc_state {
}
}
-impl<T: DriverCrtcState> AsRawCrtcState for CrtcState<T>
-where
- T::Crtc: DriverCrtc,
-{
+impl<T: DriverCrtcState> AsRawCrtcState for CrtcState<T> {
type Crtc = Crtc<T::Crtc>;
}
-impl<T: DriverCrtcState> FromRawCrtcState for CrtcState<T>
-where
- T::Crtc: DriverCrtc,
-{
+impl<T: DriverCrtcState> FromRawCrtcState for CrtcState<T> {
unsafe fn from_raw<'a>(ptr: *const bindings::drm_crtc_state) -> &'a Self {
// SAFETY: Our data layout starts with `bindings::drm_crtc_state`
unsafe { &*(ptr.cast()) }
@@ -818,10 +813,7 @@ fn drop(&mut self) {
}
}
-impl<'a, T: DriverCrtcState> Deref for CrtcStateMutator<'a, CrtcState<T>>
-where
- T::Crtc: DriverCrtc,
-{
+impl<'a, T: DriverCrtcState> Deref for CrtcStateMutator<'a, CrtcState<T>> {
type Target = T;
fn deref(&self) -> &Self::Target {
@@ -831,10 +823,7 @@ fn deref(&self) -> &Self::Target {
}
}
-impl<'a, T: DriverCrtcState> DerefMut for CrtcStateMutator<'a, CrtcState<T>>
-where
- T::Crtc: DriverCrtc,
-{
+impl<'a, T: DriverCrtcState> DerefMut for CrtcStateMutator<'a, CrtcState<T>> {
fn deref_mut(&mut self) -> &mut Self::Target {
// SAFETY: Our interface ensures that `self.state.inner` follows rust's data-aliasing rules,
// so this is safe
diff --git a/rust/kernel/drm/kms/encoder.rs b/rust/kernel/drm/kms/encoder.rs
index 5f860faf8b61..47fd223a4d3a 100644
--- a/rust/kernel/drm/kms/encoder.rs
+++ b/rust/kernel/drm/kms/encoder.rs
@@ -9,7 +9,7 @@
};
use crate::{
alloc::KBox,
- drm::device::Device,
+ drm::device::{Device, Uninit},
error::to_result,
prelude::*,
types::{NotThreadSafe, Opaque},
@@ -105,7 +105,7 @@ pub trait DriverEncoder: Send + Sync + Sized {
/// The constructor for creating a [`Encoder`] using this [`DriverEncoder`] implementation.
///
/// Drivers may use this to instantiate their [`DriverEncoder`] object.
- fn new(device: &Device<Self::Driver>, args: Self::Args) -> impl PinInit<Self, Error>;
+ fn new(device: &Device<Self::Driver, Uninit>, args: Self::Args) -> impl PinInit<Self, Error>;
}
/// The generated C vtable for a [`DriverEncoder`].
diff --git a/rust/kernel/drm/kms/modes.rs b/rust/kernel/drm/kms/modes.rs
index 0e8dc434487d..88ea27729212 100644
--- a/rust/kernel/drm/kms/modes.rs
+++ b/rust/kernel/drm/kms/modes.rs
@@ -1,4 +1,9 @@
// SPDX-License-Identifier: GPL-2.0
+
+//! DRM display mode definitions ([`struct drm_display_mode`]).
+//!
+//! [`struct drm_display_mode`]: srctree/include/drm/drm_modes.h
+
use bindings;
use crate::types::Opaque;
diff --git a/rust/kernel/drm/kms/plane.rs b/rust/kernel/drm/kms/plane.rs
index 47e05fe6bee1..375f79bd3ceb 100644
--- a/rust/kernel/drm/kms/plane.rs
+++ b/rust/kernel/drm/kms/plane.rs
@@ -11,7 +11,7 @@
use crate::{
alloc::KBox,
bindings,
- drm::{device::Device, fourcc::*},
+ drm::{device::{Device, Uninit}, fourcc::*},
error::{from_result, to_result, Error},
prelude::*,
types::{NotThreadSafe, Opaque},
@@ -98,12 +98,12 @@ pub trait DriverPlane: Send + Sync + Sized {
/// The [`DriverPlaneState`] implementation for this [`DriverPlane`].
///
/// See [`DriverPlaneState`] for more info.
- type State: DriverPlaneState<Plane = Self>;
+ type State: DriverPlaneState;
/// The constructor for creating a [`Plane`] using this [`DriverPlane`] implementation.
///
/// Drivers may use this to instantiate their [`DriverPlane`] object.
- fn new(device: &Device<Self::Driver>, args: Self::Args) -> impl PinInit<Self, Error>;
+ fn new(device: &Device<Self::Driver, Uninit>, args: Self::Args) -> impl PinInit<Self, Error>;
/// The optional [`drm_plane_helper_funcs.atomic_update`] hook for this plane.
///
@@ -689,17 +689,13 @@ pub struct PlaneState<T: DriverPlaneState> {
/// [`struct drm_plane`]: srctree/include/drm_plane.h
/// [`struct drm_plane_state`]: srctree/include/drm_plane.h
pub trait DriverPlaneState: Clone + Default + Sized {
- /// The type for this driver's drm_plane implementation. Unbounded to break the trait WF
- /// cycle; the `DriverPlane` bound is required at use sites instead.
- type Plane;
+ /// The type for this driver's drm_plane implementation
+ type Plane: DriverPlane;
}
impl<T: DriverPlaneState> Sealed for PlaneState<T> {}
-impl<T: DriverPlaneState> AsRawPlaneState for PlaneState<T>
-where
- T::Plane: DriverPlane,
-{
+impl<T: DriverPlaneState> AsRawPlaneState for PlaneState<T> {
type Plane = Plane<T::Plane>;
}
@@ -713,10 +709,7 @@ unsafe fn as_raw_mut(&mut self) -> &mut bindings::drm_plane_state {
}
}
-impl<T: DriverPlaneState> FromRawPlaneState for PlaneState<T>
-where
- T::Plane: DriverPlane,
-{
+impl<T: DriverPlaneState> FromRawPlaneState for PlaneState<T> {
unsafe fn from_raw<'a>(ptr: *const bindings::drm_plane_state) -> &'a Self {
// Our data layout starts with `bindings::drm_plane_state`.
let ptr: *const Self = ptr.cast();
@@ -892,10 +885,7 @@ unsafe fn as_raw_mut(&mut self) -> &mut bindings::drm_plane_state {
impl<'a, T: FromRawPlaneState> Sealed for PlaneStateMutator<'a, T> {}
-impl<'a, T: DriverPlaneState> Deref for PlaneStateMutator<'a, PlaneState<T>>
-where
- T::Plane: DriverPlane,
-{
+impl<'a, T: DriverPlaneState> Deref for PlaneStateMutator<'a, PlaneState<T>> {
type Target = T;
fn deref(&self) -> &Self::Target {
@@ -903,10 +893,7 @@ fn deref(&self) -> &Self::Target {
}
}
-impl<'a, T: DriverPlaneState> DerefMut for PlaneStateMutator<'a, PlaneState<T>>
-where
- T::Plane: DriverPlane,
-{
+impl<'a, T: DriverPlaneState> DerefMut for PlaneStateMutator<'a, PlaneState<T>> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.state.inner
}
diff --git a/rust/kernel/drm/kms/vblank.rs b/rust/kernel/drm/kms/vblank.rs
index 534fd18f63b4..84e5cbbe923d 100644
--- a/rust/kernel/drm/kms/vblank.rs
+++ b/rust/kernel/drm/kms/vblank.rs
@@ -4,7 +4,7 @@
//!
//! C header: [`include/drm/drm_vblank.h`](srcfree/include/drm/drm_vblank.h)
-use super::{crtc::*, ModeObject, modes::*, Sealed};
+use super::{crtc::*, ModeObject, modes::*};
use bindings;
use core::{
marker::*,
@@ -62,9 +62,8 @@ fn get_vblank_timestamp(
/// Drivers interested in implementing vblank support should refer to [`VblankSupport`], drivers
/// that don't have vblank support can use [`PhantomData`].
pub trait VblankImpl {
- /// The parent [`DriverCrtc`]. Unbounded to break the trait WF cycle; the `DriverCrtc`
- /// bound is required at use sites instead.
- type Crtc;
+ /// The parent [`DriverCrtc`].
+ type Crtc: DriverCrtc<VblankImpl = Self>;
/// The generated [`VblankOps`].
const VBLANK_OPS: VblankOps;
--
2.55.0
next prev parent reply other threads:[~2026-07-03 3:01 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-17 15:02 [RFC PATCH 0/5] rust: drm: minimal KMS bindings, EDID read, rotation, HDCP defs Mike Lothian
2026-06-17 15:02 ` [RFC PATCH 1/4] rust: drm: add minimal KMS bindings for simple-display-pipe drivers Mike Lothian
2026-06-17 15:02 ` [RFC PATCH 2/4] rust: drm: expose drm_edid.h for reading connector EDID Mike Lothian
2026-06-17 15:02 ` [RFC PATCH 3/4] rust: drm: expose drm::Device::as_raw() Mike Lothian
2026-06-17 15:02 ` [RFC PATCH 4/4] rust: drm: expose drm_blend.h and the atomic new-CRTC-state accessor Mike Lothian
2026-06-17 15:11 ` [RFC PATCH 0/5] rust: drm: minimal KMS bindings, EDID read, rotation, HDCP defs Miguel Ojeda
2026-06-17 15:29 ` Mike Lothian
2026-07-03 3:00 ` [RFC PATCH v2 00/18] rust: drm: safe KMS mode-object layer + evdi bindings Mike Lothian
2026-07-03 3:00 ` [RFC PATCH v2 01/18] rust: drm: kms: forward-port the safe mode-object layer onto the typestate device Mike Lothian
2026-07-07 21:46 ` lyude
2026-07-07 22:21 ` lyude
2026-07-03 3:00 ` [RFC PATCH v2 02/18] rust: drm: kms: adapt the port to current drm-next Mike Lothian
2026-07-03 3:00 ` [RFC PATCH v2 03/18] rust: drm: kms: break the Driver* trait well-formedness cycle Mike Lothian
2026-07-03 3:00 ` Mike Lothian [this message]
2026-07-03 3:00 ` [RFC PATCH v2 05/18] rust: drm: expose <drm/display/drm_hdcp.h> HDCP 2.2 message definitions Mike Lothian
2026-07-03 3:00 ` [RFC PATCH v2 06/18] rust: drm: kms: add a Framebuffer::vmap() guard Mike Lothian
2026-07-07 21:51 ` lyude
2026-07-03 3:00 ` [RFC PATCH v2 07/18] rust: drm: kms: add safe accessors for common state and connector modes Mike Lothian
2026-07-03 3:00 ` [RFC PATCH v2 08/18] rust: drm: tyr: add the Kms associated type Mike Lothian
2026-07-03 3:00 ` [RFC PATCH v2 09/18] rust: drm: add drm_event delivery Mike Lothian
2026-07-03 3:00 ` [RFC PATCH v2 10/18] rust: drm: allow drivers to declare ioctls from their own uAPI module Mike Lothian
2026-07-03 3:00 ` [RFC PATCH v2 11/18] rust: platform: add runtime platform device creation Mike Lothian
2026-07-03 3:00 ` [RFC PATCH v2 12/18] rust: drm: framebuffer: add geometry accessors, refcounting and a byte-slice vmap Mike Lothian
2026-07-03 3:01 ` [RFC PATCH v2 13/18] rust: i2c: add adapter-provider (bus controller) registration Mike Lothian
2026-07-03 3:01 ` [RFC PATCH v2 14/18] rust: add sysfs device attribute groups Mike Lothian
2026-07-03 3:01 ` [RFC PATCH v2 15/18] rust: drm: support hardware cursor planes with sleepable event delivery Mike Lothian
2026-07-03 3:01 ` [RFC PATCH v2 16/18] rust: drm: add CRTC gamma LUT and plane rotation property bindings Mike Lothian
2026-07-03 3:01 ` [RFC PATCH v2 17/18] rust: drm: kms: add connector detect() and mode_valid() hooks Mike Lothian
2026-07-03 3:01 ` [RFC PATCH v2 18/18] rust: drm: kms: add plane damage-clip accessors Mike Lothian
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260703030123.2814-5-mike@fireburn.co.uk \
--to=mike@fireburn.co.uk \
--cc=a.hindborg@kernel.org \
--cc=airlied@gmail.com \
--cc=aliceryhl@google.com \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun@kernel.org \
--cc=dakr@kernel.org \
--cc=dri-devel@lists.freedesktop.org \
--cc=gary@garyguo.net \
--cc=linux-kernel@vger.kernel.org \
--cc=lossin@kernel.org \
--cc=lyude@redhat.com \
--cc=ojeda@kernel.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=simona@ffwll.ch \
--cc=tmgross@umich.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox