From nobody Mon Oct 6 10:13:18 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5CA4D2EBDE0; Tue, 22 Jul 2025 15:01:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753196484; cv=none; b=hV881vHPDqb/avgKcUCMzyKRaA9ngxtG6iwJIGxxpAk7AEQAfc48Bs/QDmy4Ftm7EsyLDqfwPWPUXL/FDna/z6vpfTHTyto+MdBLnOxwmNfsFsJnMj9yGNRx1Xp7WUQxnntTQxbCAmt0lUrAzuNtOEyI6vYv2HMw9DdlY851t10= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753196484; c=relaxed/simple; bh=kbZWRBa133EyVivWNfo1Ul3K7i+pBTVUEjE7NjH9MBc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=I+uI6ibcxH8OL5YAzKRYEKfWx2dsr+JirGXoqqomsCJvRlffrGCLaxYLfirD7TG3GVBWF9zKkralgJkLwh0VcoRxF8mmNpCI93uGnng/PsW1VNXhy33M2u+3D1BhpEgNTwsCZF3u65o7lgqSyLbXA6oIzorgZDx5lj9z2UvBYTs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=i8Z4wTCf; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="i8Z4wTCf" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0A4B1C4CEF6; Tue, 22 Jul 2025 15:01:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1753196483; bh=kbZWRBa133EyVivWNfo1Ul3K7i+pBTVUEjE7NjH9MBc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=i8Z4wTCf0+vYr2bTPcGLUdO4gDQBfhPmmiAfSstCLmqcGos4IavqLT3+le8QZ7wKJ cbSnyAWGasW5aem4f/Cv9CWfB3AnQVwepNevQf3zrNTIoRis+hYDXx2qbrDL35f/fK dEDnQSl1LsBnLbQgBEOZMKJvOsLpZv4x7XiKO2S55DrSxUfMzflwpNiC1vW8e4ttdL spmFP8Lns9tpszA7e4AS1xfQDdUNfFLR1Atq2fOItNJ9zsn1QO0/5eFjSysxlCy4Mv 2uYC5Sbfv15kqdcgKSJZyffcFe2PiS2w4MjcfoCsK095PbZ8vPoR7jjRnMR8DiDe4/ +uC+rIl15wpcw== From: Danilo Krummrich To: gregkh@linuxfoundation.org, rafael@kernel.org, ojeda@kernel.org, alex.gaynor@gmail.com, boqun.feng@gmail.com, gary@garyguo.net, bjorn3_gh@protonmail.com, lossin@kernel.org, a.hindborg@kernel.org, aliceryhl@google.com, tmgross@umich.edu Cc: rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, Danilo Krummrich Subject: [PATCH v2 1/3] device: rust: expand documentation for DeviceContext Date: Tue, 22 Jul 2025 16:59:59 +0200 Message-ID: <20250722150110.23565-2-dakr@kernel.org> X-Mailer: git-send-email 2.50.0 In-Reply-To: <20250722150110.23565-1-dakr@kernel.org> References: <20250722150110.23565-1-dakr@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Expand the documentation around DeviceContext states and types, in order to provide detailed information about their purpose and relationship with each other. Reviewed-by: Greg Kroah-Hartman Signed-off-by: Danilo Krummrich Reviewed-by: Alexandre Courbot Reviewed-by: Alice Ryhl Reviewed-by: Daniel Almeida --- rust/kernel/device.rs | 69 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 58 insertions(+), 11 deletions(-) diff --git a/rust/kernel/device.rs b/rust/kernel/device.rs index ca82926fd67f..f5d1db568f00 100644 --- a/rust/kernel/device.rs +++ b/rust/kernel/device.rs @@ -311,28 +311,75 @@ unsafe impl Send for Device {} // synchronization in `struct device`. unsafe impl Sync for Device {} =20 -/// Marker trait for the context of a bus specific device. +/// Marker trait for the context or scope of a bus specific device. /// -/// Some functions of a bus specific device should only be called from a c= ertain context, i.e. bus -/// callbacks, such as `probe()`. +/// [`DeviceContext`] is a marker trait for types representing the context= of a bus specific +/// [`Device`]. /// -/// This is the marker trait for structures representing the context of a = bus specific device. +/// The specific device context types are: [`CoreInternal`], [`Core`], [`B= ound`] and [`Normal`]. +/// +/// [`DeviceContext`] types are hierarchical, which means that there is a = strict hierarchy that +/// defines which [`DeviceContext`] type can be derived from another. For = instance, any +/// [`Device`] can dereference to a [`Device`]. +/// +/// The following enunumeration illustrates the dereference hierarchy of [= `DeviceContext`] types. +/// +/// - [`CoreInternal`] =3D> [`Core`] =3D> [`Bound`] =3D> [`Normal`] +/// +/// Bus devices can automatically implement the dereference hierarchy by u= sing +/// [`impl_device_context_deref`]. +/// +/// Note that the guarantee for a [`Device`] reference to have a certain [= `DeviceContext`] comes +/// from the specific scope the [`Device`] reference is valid in. +/// +/// [`impl_device_context_deref`]: kernel::impl_device_context_deref pub trait DeviceContext: private::Sealed {} =20 -/// The [`Normal`] context is the context of a bus specific device when it= is not an argument of -/// any bus callback. +/// The [`Normal`] context is the default [`DeviceContext`] of any [`Devic= e`]. +/// +/// The normal context does not indicate any specific context. Any `Device= ` is also a valid +/// [`Device`]. It is the only [`DeviceContext`] for which it is v= alid to implement +/// [`AlwaysRefCounted`] for. +/// +/// [`AlwaysRefCounted`]: kernel::types::AlwaysRefCounted pub struct Normal; =20 -/// The [`Core`] context is the context of a bus specific device when it i= s supplied as argument of -/// any of the bus callbacks, such as `probe()`. +/// The [`Core`] context is the context of a bus specific device when it a= ppears as argument of +/// any bus specific callback, such as `probe()`. +/// +/// The core context indicates that the [`Device`] reference's scope= is limited to the bus +/// callback it appears in. It is intended to be used for synchronization = purposes. Bus device +/// implementations can implement methods for [`Device`], such that = they can only be called +/// from bus callbacks. pub struct Core; =20 -/// Semantically the same as [`Core`] but reserved for internal usage of t= he corresponding bus +/// Semantically the same as [`Core`], but reserved for internal usage of = the corresponding bus +/// abstraction. +/// +/// The internal core context is intended to be used in exactly the same w= ay as the [Core] context, +/// with the difference that this [`DeviceContext`] is internal to the cor= responding bus /// abstraction. +/// +/// This context mainly exists to share generic [`Device`] infrastructure = that should only be called +/// from bus callbacks with bus abstractions, but without making them acce= ssible for drivers. pub struct CoreInternal; =20 -/// The [`Bound`] context is the context of a bus specific device referenc= e when it is guaranteed to -/// be bound for the duration of its lifetime. +/// The [`Bound`] context is the [`DeviceContext`] of a bus specific devic= e when it is guaranteed to +/// be bound to a driver. +/// +/// The bound context indicates that for the entire duration of the lifeti= me of a [`Device`] +/// reference, the [`Device`] is guaranteed to be bound to a driver. +/// +/// Some APIs, such as [`dma::CoherentAllocation`] or [`Devres`] rely on t= he [`Device`] to be bound, +/// which can be proven with the [`Bound`] device context. +/// +/// Any abstraction that can guarantee a scope where the corresponding bus= device is bound, should +/// provide a [`Device`] reference to its users for this scope. Thi= s allows users to benefit +/// from optimizations for accessing device resources, see also [`Devres::= access`]. +/// +/// [`Devres`]: kernel::devres::Devres +/// [`Devres::access`]: kernel::devres::Devres::access +/// [`dma::CoherentAllocation`]: kernel::dma::CoherentAllocation pub struct Bound; =20 mod private { --=20 2.50.0 From nobody Mon Oct 6 10:13:18 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C51942ECE89; Tue, 22 Jul 2025 15:01:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753196487; cv=none; b=XSOJN52YsWtx6JpYSjdvc6rITWSYOihFrGq4OInMim+LmL8pH6+xrI55KFQ6o5FVnLI23UGIx7jp9+k5wNRCIWikXxf5ihJITjFuDhBOpHuy3vNn4Iw1g3b4fZG5zb6D00ChBdEBEpwS0AITCJAEzqBfSPQhtQhPRVLpI/Utdhk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753196487; c=relaxed/simple; bh=y/u2dKefOvvJa3r/lkuSNuJJvDKeMjJ5Xk8vtaghlOw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=WcXLuTW1/2tpUlOakND+EHm3vkPSupbEQl9j7WSJRST//hgVfwCMMzNwetxW7blv0KZO6N9Bpf8Zn+tS6SdAjFXwy44WziiN4fsLwb0orX+15+0uaZ/PgJyOoD/tnrQgT3G8HkQ2Zugm6r1Vyv65Ah7k/xXFVJHgcJ14iv+auMs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=UTlZEkBr; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="UTlZEkBr" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 59300C4CEEB; Tue, 22 Jul 2025 15:01:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1753196487; bh=y/u2dKefOvvJa3r/lkuSNuJJvDKeMjJ5Xk8vtaghlOw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=UTlZEkBr0B5DmXKpWTIa1jL2lvpO5odXosuLAB12tXZbDPJN6t9d70yZbYQO3MO/q EDGWFy33TYI4JTg5H+35dDsoV91zHo5CNs15hTWMUgleTphmbgCkAKcoN3o5GLDBYf fg1pcdZnFn0exu7fE31C4HNO2DqALAJ2WEtdrEtZIvoXvqiBMcndfUga1VxKp88Tr5 e5yvi3DuroC9e/9gNftErQEOSpTrC73rzkyt8e41gXewt1DICOx3YI2xuv8s8ps65B 8LiZD7GNE7VIqd1ZnG5juZL3ZwN7Naoebu2rQ4TVllmg4i57PlTpkN67njBEy1Vzc3 N1S+znwoptyeg== From: Danilo Krummrich To: gregkh@linuxfoundation.org, rafael@kernel.org, ojeda@kernel.org, alex.gaynor@gmail.com, boqun.feng@gmail.com, gary@garyguo.net, bjorn3_gh@protonmail.com, lossin@kernel.org, a.hindborg@kernel.org, aliceryhl@google.com, tmgross@umich.edu Cc: rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, Danilo Krummrich , Daniel Almeida Subject: [PATCH v2 2/3] device: rust: expand documentation for Device Date: Tue, 22 Jul 2025 17:00:00 +0200 Message-ID: <20250722150110.23565-3-dakr@kernel.org> X-Mailer: git-send-email 2.50.0 In-Reply-To: <20250722150110.23565-1-dakr@kernel.org> References: <20250722150110.23565-1-dakr@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The documentation for the generic Device type is outdated and deserves much more detail. Hence, expand the documentation and cover topics such as device types, device contexts, as well as information on how to use the generic device infrastructure to implement bus and class specific device types. Reviewed-by: Daniel Almeida Reviewed-by: Greg Kroah-Hartman Signed-off-by: Danilo Krummrich Reviewed-by: Alexandre Courbot Reviewed-by: Alice Ryhl --- rust/kernel/device.rs | 139 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 126 insertions(+), 13 deletions(-) diff --git a/rust/kernel/device.rs b/rust/kernel/device.rs index f5d1db568f00..9cc35ea6db98 100644 --- a/rust/kernel/device.rs +++ b/rust/kernel/device.rs @@ -15,23 +15,130 @@ =20 pub mod property; =20 -/// A reference-counted device. +/// The core representation of a device in the kernel's driver model. /// -/// This structure represents the Rust abstraction for a C `struct device`= . This implementation -/// abstracts the usage of an already existing C `struct device` within Ru= st code that we get -/// passed from the C side. +/// This structure represents the Rust abstraction for a C `struct device`= . A [`Device`] can either +/// exist as temporary reference (see also [`Device::from_raw`]), which is= only valid within a +/// certain scope or as [`ARef`], owning a dedicated reference cou= nt. /// -/// An instance of this abstraction can be obtained temporarily or permane= nt. +/// # Device Types /// -/// A temporary one is bound to the lifetime of the C `struct device` poin= ter used for creation. -/// A permanent instance is always reference-counted and hence not restric= ted by any lifetime -/// boundaries. +/// A [`Device`] can represent either a bus device or a class device. /// -/// For subsystems it is recommended to create a permanent instance to wra= p into a subsystem -/// specific device structure (e.g. `pci::Device`). This is useful for pas= sing it to drivers in -/// `T::probe()`, such that a driver can store the `ARef` (equival= ent to storing a -/// `struct device` pointer in a C driver) for arbitrary purposes, e.g. al= locating DMA coherent -/// memory. +/// ## Bus Devices +/// +/// A bus device is a [`Device`] that is associated with a physical or vir= tual bus. Examples of +/// buses include PCI, USB, I2C, and SPI. Devices attached to a bus are re= gistered with a specific +/// bus type, which facilitates matching devices with appropriate drivers = based on IDs or other +/// identifying information. Bus devices are visible in sysfs under `/sys/= bus//devices/`. +/// +/// ## Class Devices +/// +/// A class device is a [`Device`] that is associated with a logical categ= ory of functionality +/// rather than a physical bus. Examples of classes include block devices,= network interfaces, sound +/// cards, and input devices. Class devices are grouped under a common cla= ss and exposed to +/// userspace via entries in `/sys/class//`. +/// +/// # Device Context +/// +/// [`Device`] references are generic over a [`DeviceContext`], which repr= esents the type state of +/// a [`Device`]. +/// +/// As the name indicates, this type state represents the context of the s= cope the [`Device`] +/// reference is valid in. For instance, the [`Bound`] context guarantees = that the [`Device`] is +/// bound to a driver for the entire duration of the existence of a [`Devi= ce`] reference. +/// +/// Other [`DeviceContext`] types besides [`Bound`] are [`Normal`], [`Core= `] and [`CoreInternal`]. +/// +/// Unless selected otherwise [`Device`] defaults to the [`Normal`] [`Devi= ceContext`], which by +/// itself has no additional requirements. +/// +/// It is always up to the caller of [`Device::from_raw`] to select the co= rrect [`DeviceContext`] +/// type for the corresponding scope the [`Device`] reference is created i= n. +/// +/// All [`DeviceContext`] types other than [`Normal`] are intended to be u= sed with +/// [bus devices](#bus-devices) only. +/// +/// # Implementing Bus Devices +/// +/// This section provides a guideline to implement bus specific devices, s= uch as [`pci::Device`] or +/// [`platform::Device`]. +/// +/// A bus specific device should be defined as follows. +/// +/// ```ignore +/// #[repr(transparent)] +/// pub struct Device( +/// Opaque, +/// PhantomData, +/// ); +/// ``` +/// +/// Since devices are reference counted, [`AlwaysRefCounted`] should be im= plemented for `Device` +/// (i.e. `Device`). Note that [`AlwaysRefCounted`] must not be im= plemented for any other +/// [`DeviceContext`], since all other device context types are only valid= in a certain scope. +/// +/// In order to be able to implement the [`DeviceContext`] dereference hie= rarchy, bus device +/// implementations should call the [`impl_device_context_deref`] macro as= shown below. +/// +/// ```ignore +/// // SAFETY: `Device` is a transparent wrapper of a type that doesn't de= pend on `Device`'s +/// // generic argument. +/// kernel::impl_device_context_deref!(unsafe { Device }); +/// ``` +/// In order to convert from a any [`Device`] to [`ARef`], bu= s devices can implement +/// the following macro call. +/// +/// ```ignore +/// kernel::impl_device_context_into_aref!(Device); +/// ``` +/// Bus devices should also implement the following [`AsRef`] implementati= on, such that users can +/// easily derive a generic [`Device`] reference. +/// +/// ```ignore +/// impl AsRef> for Device= { +/// fn as_ref(&self) -> &device::Device { +/// ... +/// } +/// } +/// ``` +/// +/// # Implementing Class Devices +/// +/// Class device implementations require less infrastructure and depend sl= ightly more on the +/// specific subsystem. +/// +/// An example implementation for a class device could look like this. +/// +/// ```ignore +/// #[repr(C)] +/// #[pin_data] +/// pub struct Device { +/// dev: Opaque, +/// #[pin] +/// data: T::Data, +/// } +/// ``` +/// +/// This class device uses the sub-classing pattern to embed the driver's = private data within the +/// allocation of the class device. For this to be possible the class devi= ce is generic over the +/// class specific `Driver` trait implementation. +/// +/// Just like any device, class devices are reference counted and should h= ence implement +/// [`AlwaysRefCounted`] for `Device`. +/// +/// Class devices should also implement the following [`AsRef`] implementa= tion, such that users can +/// easily derive a generic [`Device`] reference. +/// +/// ```ignore +/// impl AsRef for Device { +/// fn as_ref(&self) -> &device::Device { +/// ... +/// } +/// } +/// ``` +/// +/// An example for a class device implementation is [`drm::Device`]. /// /// # Invariants /// @@ -42,6 +149,12 @@ /// /// `bindings::device::release` is valid to be called from any thread, hen= ce `ARef` can be /// dropped from any thread. +/// +/// [`AlwaysRefCounted`]: kernel::types::AlwaysRefCounted +/// [`drm::Device`]: kernel::drm::Device +/// [`impl_device_context_deref`]: kernel::impl_device_context_deref +/// [`pci::Device`]: kernel::pci::Device +/// [`platform::Device`]: kernel::platform::Device #[repr(transparent)] pub struct Device(Opaque,= PhantomData); =20 --=20 2.50.0 From nobody Mon Oct 6 10:13:18 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 50E402ECEAB; Tue, 22 Jul 2025 15:01:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753196491; cv=none; b=aOqOXiEFyrrtbZqJEPZgvM5iGnhuF5JTsH5hJZA/dFKLIbsLPLtC0V7PGaXQpRu2CTiYMgnqfaWki/dmiKRqfl+e1vQ9/BxlnBEXU74oK4J8AxnMUj5B+ZFBUU21jL/r1b7hJ42xw4MN2uMQvKN+R4n1tELEX2WrPmSs5wn2Z70= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753196491; c=relaxed/simple; bh=cZJQooCjCy4KF7VmqkC4rIymUInoRT314LZ1r8AK4Wg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ffHzuqhKcVLEH7Ftau+HNZI/2A/rWu+5rBWaP6AH73YqdQ6VzO6sL0ZwyUHe28ayWju1CHalGPe9COY0uqlszj8DTt6epFhot50dcKpLbiXPEKqhihXOW8NbCpgTqxbkoZgzkyScMG02XujstAIMLfaMo7/fTQ+2jYoOvjum/wY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=MMb1KFi6; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="MMb1KFi6" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D43BFC4CEF6; Tue, 22 Jul 2025 15:01:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1753196490; bh=cZJQooCjCy4KF7VmqkC4rIymUInoRT314LZ1r8AK4Wg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=MMb1KFi6BiYCo6N3hjauUkvLKcJosMdskKRmTkIuWX+Dbkn0AjwXdXMkSLcx6Wd0+ hKJ01sQATRlzNAmmHRsyc/QIM9oQ2NzsvAxbbAHnQlVugdGVCFHb6xr+Kk/OXUGn70 HeSGCfLiT2f2G/xwdX87FrNnMyZMsWZZKMqS7QzHhLU3hNvN4VVRxDmFMG8VG5QACP FDMnVFYU0NncsgmSJWl0UsI7KhxE+PigBXRh0AwtCFSHd6vSRbp6/qPEnvb0XtATN3 RLndET21iwi5K4KKnRlvQ7yaUfEos4Ex/XfvkLB1p6aVrSQclMXMSpb9/MSmailo9z +iOygu3Gpr7VQ== From: Danilo Krummrich To: gregkh@linuxfoundation.org, rafael@kernel.org, ojeda@kernel.org, alex.gaynor@gmail.com, boqun.feng@gmail.com, gary@garyguo.net, bjorn3_gh@protonmail.com, lossin@kernel.org, a.hindborg@kernel.org, aliceryhl@google.com, tmgross@umich.edu Cc: rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, Danilo Krummrich , Daniel Almeida Subject: [PATCH v2 3/3] driver: rust: expand documentation for driver infrastructure Date: Tue, 22 Jul 2025 17:00:01 +0200 Message-ID: <20250722150110.23565-4-dakr@kernel.org> X-Mailer: git-send-email 2.50.0 In-Reply-To: <20250722150110.23565-1-dakr@kernel.org> References: <20250722150110.23565-1-dakr@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add documentation about generic driver infrastructure, representing a guideline on how the generic driver infrastructure is intended to be used to implement bus specific driver APIs. This covers aspects such as the bus specific driver trait, adapter implementation, driver registration and custom device ID types. Reviewed-by: Daniel Almeida Reviewed-by: Greg Kroah-Hartman Signed-off-by: Danilo Krummrich Reviewed-by: Alexandre Courbot Reviewed-by: Alice Ryhl --- rust/kernel/driver.rs | 89 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 87 insertions(+), 2 deletions(-) diff --git a/rust/kernel/driver.rs b/rust/kernel/driver.rs index a8f2675ba7a7..279e3af20682 100644 --- a/rust/kernel/driver.rs +++ b/rust/kernel/driver.rs @@ -2,8 +2,93 @@ =20 //! Generic support for drivers of different buses (e.g., PCI, Platform, A= mba, etc.). //! -//! Each bus / subsystem is expected to implement [`RegistrationOps`], whi= ch allows drivers to -//! register using the [`Registration`] class. +//! This documentation describes how to implement a bus specific driver AP= I and how to align it with +//! the design of (bus specific) devices. +//! +//! Note: Readers are expected to know the content of the documentation of= [`Device`] and +//! [`DeviceContext`]. +//! +//! # Driver Trait +//! +//! The main driver interface is defined by a bus specific driver trait. F= or instance: +//! +//! ```ignore +//! pub trait Driver: Send { +//! /// The type holding information about each device ID supported by= the driver. +//! type IdInfo: 'static; +//! +//! /// The table of OF device ids supported by the driver. +//! const OF_ID_TABLE: Option> =3D None; +//! +//! /// The table of ACPI device ids supported by the driver. +//! const ACPI_ID_TABLE: Option> =3D None; +//! +//! /// Driver probe. +//! fn probe(dev: &Device, id_info: &Self::IdInfo) -> Re= sult>>; +//! +//! /// Driver unbind (optional). +//! fn unbind(dev: &Device, this: Pin<&Self>) { +//! let _ =3D (dev, this); +//! } +//! } +//! ``` +//! +//! For specific examples see [`auxiliary::Driver`], [`pci::Driver`] and [= `platform::Driver`]. +//! +//! The `probe()` callback should return a `Result>>`, i.e.= the driver's private +//! data. The bus abstraction should store the pointer in the correspondin= g bus device. The generic +//! [`Device`] infrastructure provides common helpers for this purpose on = its +//! [`Device`] implementation. +//! +//! All driver callbacks should provide a reference to the driver's privat= e data. Once the driver +//! is unbound from the device, the bus abstraction should take back the o= wnership of the driver's +//! private data from the corresponding [`Device`] and [`drop`] it. +//! +//! All driver callbacks should provide a [`Device`] reference (see = also [`device::Core`]). +//! +//! # Adapter +//! +//! The adapter implementation of a bus represents the abstraction layer b= etween the C bus +//! callbacks and the Rust bus callbacks. It therefore has to be generic o= ver an implementation of +//! the [driver trait](#driver-trait). +//! +//! ```ignore +//! pub struct Adapter; +//! ``` +//! +//! There's a common [`Adapter`] trait that can be implemented to inherit = common driver +//! infrastructure, such as finding the ID info from an [`of::IdTable`] or= [`acpi::IdTable`]. +//! +//! # Driver Registration +//! +//! In order to register C driver types (such as `struct platform_driver`)= the [adapter](#adapter) +//! should implement the [`RegistrationOps`] trait. +//! +//! This trait implementation can be used to create the actual registratio= n with the common +//! [`Registration`] type. +//! +//! Typically, bus abstractions want to provide a bus specific `module_bus= _driver!` macro, which +//! creates a kernel module with exactly one [`Registration`] for the bus = specific adapter. +//! +//! The generic driver infrastructure provides a helper for this with the = [`module_driver`] macro. +//! +//! # Device IDs +//! +//! Besides the common device ID types, such as [`of::DeviceId`] and [`acp= i::DeviceId`], most buses +//! may need to implement their own device ID types. +//! +//! For this purpose the generic infrastructure in [`device_id`] should be= used. +//! +//! [`auxiliary::Driver`]: kernel::auxiliary::Driver +//! [`Core`]: device::Core +//! [`Device`]: device::Device +//! [`Device`]: device::Device +//! [`Device`]: device::Device +//! [`DeviceContext`]: device::DeviceContext +//! [`device_id`]: kernel::device_id +//! [`module_driver`]: kernel::module_driver +//! [`pci::Driver`]: kernel::pci::Driver +//! [`platform::Driver`]: kernel::platform::Driver =20 use crate::error::{Error, Result}; use crate::{acpi, device, of, str::CStr, try_pin_init, types::Opaque, This= Module}; --=20 2.50.0