From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-wr1-f49.google.com (mail-wr1-f49.google.com [209.85.221.49]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1685A2C326F for ; Fri, 3 Jul 2026 03:01:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.49 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783047706; cv=none; b=PoCp/tQo3e460QRDzdwbPfRYHSTlbda9btufmQToaTvl8N1+qTEhmVsH6FMA8+xUx5MYumoYTSQE6VD7hu327PoSBE4C6Lv8ghR2i1cTH+aVw9uMP2wPskH//7ubwiYAGcGIL426Xlf3aA0vdkt0ZNbeZh6UXqihhoyZjmGQmJE= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783047706; c=relaxed/simple; bh=EqgrFDHbbJ2MtQkYe+i0eTel4RgJhDt/VrzWaWdchLA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=iT1rO4ZqCYDU8HCiCckv1r1XFaHL1nK+c/uGSI5ZyT2Lw3AHvfgoOTH3h1zdyyAchjzLVhOPVUEzRVYWWjnshmYlHyM7xpUCvKg46P7NEFWnRRAtC9lDftf9iZqVO7GhY2qbVCa2rxBpWQRd1uvaFZIAfctV3W7GhBbwvCNSGIo= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=fireburn.co.uk; spf=none smtp.mailfrom=fireburn.co.uk; dkim=pass (2048-bit key) header.d=fireburn-co-uk.20251104.gappssmtp.com header.i=@fireburn-co-uk.20251104.gappssmtp.com header.b=Uy0dOLGM; arc=none smtp.client-ip=209.85.221.49 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=fireburn.co.uk Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=fireburn.co.uk Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=fireburn-co-uk.20251104.gappssmtp.com header.i=@fireburn-co-uk.20251104.gappssmtp.com header.b="Uy0dOLGM" Received: by mail-wr1-f49.google.com with SMTP id ffacd0b85a97d-4629051c946so46706f8f.1 for ; Thu, 02 Jul 2026 20:01:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fireburn-co-uk.20251104.gappssmtp.com; s=20251104; t=1783047701; x=1783652501; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=CX+j4GjseoiCPFw3EfmCmbTSaMoPGlBM4ySiKg5qPW4=; b=Uy0dOLGMk67IWXO+PXBAM6TKeBD33+Xivi3EINx0drgPq27dByPMLmqdUpvHhM6nyc ZTQkCLWttmbMriOSsVxVnGMvlxplsPCJSF3gwA2Skgk06wEJX8u7ujl62ku89Uyldy/l vgAvlp1gKkisYagfEPectVwBn1IOTUCaczXw9dAkPYeXWS8EGkkqwI+wcvZTKSk6E4yQ Au8Yr4vNeHRpB4QVXnmmCIWpSy0br0TwleP5Bd3M83B0XEZSb+9HdUOeZMlxdLpQ/Z4f zTlh6kVw0IPJDzJXJgmaUvqrWInafcvU2EfI/Dypt4Etph5A2NLec5+qZNnT1pwzhqJ8 PJKA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783047701; x=1783652501; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=CX+j4GjseoiCPFw3EfmCmbTSaMoPGlBM4ySiKg5qPW4=; b=j3uzRVxF6LU9L2sr9gGcVnO891z3j7JpXPToYWQKLJT/NYK/tLetBnp3JVpZJgIpBK yMKxFMMCX+iMn20Y0vC7YgvMTHXTzjeP1WPEZYX8ylh6XBUdGRRTcVy3PJbHAYF+L5VY RpeBhRUmOqS1upJT+dCaulCV2gjZrFcpaYkJ+i+XC3Ol/X11cHFiXws/klRP2ZTN0x1U RMJE9GrNm7LJgl6gMLTsyO1ixBwnWvFXdjBsi7HnN9eeISU8cBAPtiHDEt5zJyAxjy/Z w8jlrt/5xwW9omaebASQZnatqC352fdYByFsq1rKxKM7+JVZ9kVTjxtTSDy6jvHvKvRG gIXg== X-Gm-Message-State: AOJu0YwwZES+5Ww01aNvhtqToBgaVTolV92cNl+bkFzYUfHmYkHZhoEh 4DSas+btx4kflxlzlZGMovuo13OK8GD+OUisBLJqBpOIrdfx2SZvR9HXb+kh0+CMPY4I+dH80HK sNC4IC3M5 X-Gm-Gg: AfdE7clOy77Kh/ziV6q/EvxdiZXi5xZyuL4OQd+9y7qncVPL6zGenC4r8Nd4AZU4A24 hiwgWSAjKeq5LS1GVKec8JMksd1TZ/xzYQPO9D/33pY/N0ocVgkunYzQzU4d8Xey7lPRGR1D98d Wf4AuRJswSjljASR9XAHJVoPfAQ50pLMhpPsNls1FfnJDmes5yRq6EuN78jxRdlnfUR3dE2jJIG aGu8lI9kv7uik8rswIa6k0t3KjFE1A8Z6CfUOZPcqwKWodbFzlhRfrZvJ2mG6vt7pIwuqI7Tmfl J4hc11ZCsYCJUjBX27c4hhUNQJjS9kQBTqppB9ZBeWknzatDUPmXp7QWQMV5Q3UseL1hNjnAVAn 7FMSug5kN+CKOSWPtOSIx2XgSbf1vzvdy/K4/YQUBwGwhvAyZzEeXXGFBIkFOuk75v8ybDxkkFc 7+ABHOQyvxd4ZmdPPIsE923J9rjw/eQlbAHKBmXigbo45G9i0QRDdMeFYG X-Received: by 2002:a05:6000:41d0:b0:470:e26d:88ff with SMTP id ffacd0b85a97d-479343d1d3dmr3253927f8f.4.1783047701016; Thu, 02 Jul 2026 20:01:41 -0700 (PDT) Received: from axion.fireburn.co.uk ([137.220.119.72]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-477db3dbacbsm14466500f8f.4.2026.07.02.20.01.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 02 Jul 2026 20:01:40 -0700 (PDT) From: Mike Lothian To: rust-for-linux@vger.kernel.org Cc: dri-devel@lists.freedesktop.org, David Airlie , Simona Vetter , Danilo Krummrich , Lyude Paul , Miguel Ojeda , Boqun Feng , Gary Guo , =?UTF-8?q?Bj=C3=B6rn=20Roy=20Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross , linux-kernel@vger.kernel.org, Mike Lothian 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 Message-ID: <20260703030123.2814-5-mike@fireburn.co.uk> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260703030123.2814-1-mike@fireburn.co.uk> References: <20260617150232.2210-1-mike@fireburn.co.uk> <20260703030123.2814-1-mike@fireburn.co.uk> Precedence: bulk X-Mailing-List: rust-for-linux@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 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::::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 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::::ALLOC_OPS.dumb_map_offset, show_fdinfo: None, - fbdev_probe: T::Object::ALLOC_OPS.fbdev_probe, + fbdev_probe: T::Object::::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::::has_kms().then(|| { + let mode_config_info = if drm::Device::::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::::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`]: 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`, 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; + /// The driver's [`DriverPlane`](plane::DriverPlane) implementation. - type Plane; + /// + /// TODO: This will be unneeded once we support multiple `DriverPlane` implementations. + type Plane: plane::DriverPlane; + /// The driver's [`DriverCrtc`](crtc::DriverCrtc) implementation. - type Crtc; + /// + /// TODO: This will be unneeded once we support multiple `DriverCrtc` implementations. + type Crtc: crtc::DriverCrtc; + /// The driver's [`DriverEncoder`](encoder::DriverEncoder) implementation. - type Encoder; + /// + /// TODO: This will be unneeded once we support multiple `DriverEncoder` implementations. + type Encoder: encoder::DriverEncoder; /// Return a [`ModeConfigInfo`] structure for this [`device::Device`]. fn mode_config_info(dev: &Device) -> Result @@ -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 Device { @@ -512,6 +521,7 @@ unsafe fn dec_ref(obj: core::ptr::NonNull) { /// /// `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); 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) -> 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 { 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; + 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, args: Self::Args) -> impl PinInit; + fn new(device: &Device, args: Self::Args) -> impl PinInit; /// Retrieve a list of available display modes for this [`Connector`]. fn get_modes<'a>( @@ -700,17 +700,13 @@ pub struct ConnectorState { /// [`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 Sealed for ConnectorState {} -impl AsRawConnectorState for ConnectorState -where - T::Connector: DriverConnector, -{ +impl AsRawConnectorState for ConnectorState { type Connector = Connector; } @@ -724,10 +720,7 @@ unsafe fn as_raw_mut(&mut self) -> &mut bindings::drm_connector_state { } } -impl FromRawConnectorState for ConnectorState -where - T::Connector: DriverConnector, -{ +impl FromRawConnectorState for ConnectorState { 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( } } -impl<'a, T: DriverConnectorState> Deref for ConnectorStateMutator<'a, ConnectorState> -where - T::Connector: DriverConnector, -{ +impl<'a, T: DriverConnectorState> Deref for ConnectorStateMutator<'a, ConnectorState> { 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> -where - T::Connector: DriverConnector, -{ +impl<'a, T: DriverConnectorState> DerefMut for ConnectorStateMutator<'a, ConnectorState> { 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; + 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, args: &Self::Args) -> impl PinInit; + fn new(device: &Device, args: &Self::Args) -> impl PinInit; /// The optional [`drm_crtc_helper_funcs.atomic_check`] hook for this crtc. /// @@ -561,9 +561,10 @@ impl Sealed for CrtcState {} /// [`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 + 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 AsRawCrtcState for CrtcState -where - T::Crtc: DriverCrtc, -{ +impl AsRawCrtcState for CrtcState { type Crtc = Crtc; } -impl FromRawCrtcState for CrtcState -where - T::Crtc: DriverCrtc, -{ +impl FromRawCrtcState for CrtcState { 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> -where - T::Crtc: DriverCrtc, -{ +impl<'a, T: DriverCrtcState> Deref for CrtcStateMutator<'a, CrtcState> { 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> -where - T::Crtc: DriverCrtc, -{ +impl<'a, T: DriverCrtcState> DerefMut for CrtcStateMutator<'a, CrtcState> { 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, args: Self::Args) -> impl PinInit; + fn new(device: &Device, args: Self::Args) -> impl PinInit; } /// 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; + 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, args: Self::Args) -> impl PinInit; + fn new(device: &Device, args: Self::Args) -> impl PinInit; /// The optional [`drm_plane_helper_funcs.atomic_update`] hook for this plane. /// @@ -689,17 +689,13 @@ pub struct PlaneState { /// [`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 Sealed for PlaneState {} -impl AsRawPlaneState for PlaneState -where - T::Plane: DriverPlane, -{ +impl AsRawPlaneState for PlaneState { type Plane = Plane; } @@ -713,10 +709,7 @@ unsafe fn as_raw_mut(&mut self) -> &mut bindings::drm_plane_state { } } -impl FromRawPlaneState for PlaneState -where - T::Plane: DriverPlane, -{ +impl FromRawPlaneState for PlaneState { 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> -where - T::Plane: DriverPlane, -{ +impl<'a, T: DriverPlaneState> Deref for PlaneStateMutator<'a, PlaneState> { 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> -where - T::Plane: DriverPlane, -{ +impl<'a, T: DriverPlaneState> DerefMut for PlaneStateMutator<'a, PlaneState> { 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; /// The generated [`VblankOps`]. const VBLANK_OPS: VblankOps; -- 2.55.0