[PATCH v2 15/16] rust: io: register: remove `Register` trait and cleanup macro

Gary Guo <[email protected]> Wed, 05 Aug 2026 17:35:58 +0100
Newsgroups org.kernel.vger.rust-for-linux,dev.linux.lists.driver-core,dev.linux.lists.nova-gpu,org.freedesktop.lists.dri-devel,org.kernel.vger.linux-kernel,org.kernel.vger.linux-pci
Message-ID <[email protected]>
With the removal of relative registers, there are only two type of
registers left, fixed register and register arrays. There is not much
benefit in having a common super trait for them anymore, thus remove it,
and cleanup the macro rules associated with it.

Signed-off-by: Gary Guo <[email protected]>
---
 rust/kernel/io/register.rs | 102 +++++++++++++++++++--------------------------
 1 file changed, 43 insertions(+), 59 deletions(-)

diff --git a/rust/kernel/io/register.rs b/rust/kernel/io/register.rs
index 295b06dd53a7..fe0e6763a600 100644
--- a/rust/kernel/io/register.rs
+++ b/rust/kernel/io/register.rs
@@ -121,8 +121,8 @@
     io::IoLoc, //
 };
 
-/// Trait implemented by all registers.
-pub trait Register: Sized {
+/// Trait implemented by registers with a fixed offset.
+pub trait FixedRegister: Sized {
     /// Base type for this register.
     type Base: ?Sized;
 
@@ -132,9 +132,6 @@ pub trait Register: Sized {
     const OFFSET: usize;
 }
 
-/// Trait implemented by registers with a fixed offset.
-pub trait FixedRegister: Register {}
-
 /// Allows `()` to be used as the `location` parameter of [`Io::write`](super::Io::write) when
 /// passing a [`FixedRegister`] value.
 impl<Base: ?Sized, T> IoLoc<Base, T> for ()
@@ -200,7 +197,14 @@ fn offset(self) -> usize {
 }
 
 /// Trait implemented by arrays of registers.
-pub trait RegisterArray: Register {
+pub trait RegisterArray: Sized {
+    /// Base type for this register.
+    type Base: ?Sized;
+
+    /// Start offset of the register.
+    ///
+    /// The interpretation of this offset depends on the type of the register.
+    const OFFSET: usize;
     /// Number of elements in the registers array.
     const SIZE: usize;
     /// Number of bytes between the start of elements in the registers array.
@@ -266,8 +270,8 @@ fn try_at(idx: usize) -> Option<RegisterArrayLoc<Self>>
 ///
 /// Implementors can be used with [`Io::write_reg`](super::Io::write_reg).
 pub trait LocatedRegister<Base: ?Sized> {
-    /// Register value to write.
-    type Value: Register;
+    /// Value to write.
+    type Value;
     /// Full location information at which to write the value.
     type Location: IoLoc<Base, Self::Value>;
 
@@ -601,11 +605,22 @@ macro_rules! register {
         { $($fields:tt)* }
         $($rest:tt)*
     ) => {
-        $crate::register!(@bitfield $(#[$attr])* $vis struct $name($storage) { $($fields)* });
-        $crate::register!(@io_base $reg_base; $name
-            @ $crate::register!(@offset $(@ $offset)? $(=> $alias $([$alias_idx])?)?)
+        $crate::bitfield!(
+            #[allow(non_camel_case_types)]
+            $(#[$attr])* $vis struct $name($storage) { $($fields)* }
         );
-        $crate::register!(@io_fixed $(#[$attr])* $vis $name);
+
+        impl $crate::io::register::FixedRegister for $name {
+            type Base = $reg_base;
+
+            const OFFSET: usize =
+                $crate::register!(@offset $(@ $offset)? $(=> $alias $([$alias_idx])?)?);
+        }
+
+        $(#[$attr])*
+        $vis const $name: $crate::io::register::FixedRegisterLoc<$name> =
+            $crate::io::register::FixedRegisterLoc::<$name>::new();
+
         $crate::register!(base: $reg_base; $($rest)*);
     };
 
@@ -615,39 +630,36 @@ macro_rules! register {
         $(#[$attr:meta])* $vis:vis $name:ident ($storage:ty)
             [ $size:expr $(, stride = $stride:expr)? ] @ $offset:literal { $($fields:tt)* }
         $($rest:tt)*
-    ) => {
-        $crate::register!(@bitfield $(#[$attr])* $vis struct $name($storage) { $($fields)* });
-        $crate::register!(@io_base $reg_base; $name @ $offset);
-        $crate::register!(@io_array $vis $name
-            [ $size, stride = $crate::register!(@stride $storage $(, $stride)?) ]
-        );
-        $crate::register!(base: $reg_base; $($rest)*);
-    };
-
-    // All the rules below are private helpers.
-
-    // Generates the bitfield for the register.
-    //
-    // `#[allow(non_camel_case_types)]` is added since register names typically use
-    // `SCREAMING_CASE`.
-    (
-        @bitfield $(#[$attr:meta])* $vis:vis struct $name:ident($storage:ty) { $($fields:tt)* }
     ) => {
         $crate::bitfield!(
             #[allow(non_camel_case_types)]
             $(#[$attr])* $vis struct $name($storage) { $($fields)* }
         );
+
+        impl $crate::io::register::Array for $name {}
+
+        impl $crate::io::register::RegisterArray for $name {
+            type Base = $reg_base;
+
+            const OFFSET: usize = $offset;
+            const SIZE: usize = $size;
+            const STRIDE: usize = $crate::register!(@stride $storage $(, $stride)?);
+        }
+
+        $crate::register!(base: $reg_base; $($rest)*);
     };
 
+    // All the rules below are private helpers.
+
     // Offset computation helper rules.
     (@offset @ $offset:expr) => { $offset };
-    (@offset => $alias:path) => { <$alias as $crate::io::register::Register>::OFFSET };
+    (@offset => $alias:path) => { <$alias as $crate::io::register::FixedRegister>::OFFSET };
     (@offset => $alias:path [$idx:expr]) => {{
         $crate::build_assert::static_assert!(
             $idx < <$alias as $crate::io::register::RegisterArray>::SIZE
         );
 
-        <$alias as $crate::io::register::Register>::OFFSET +
+        <$alias as $crate::io::register::RegisterArray>::OFFSET +
             $idx * <$alias as $crate::io::register::RegisterArray>::STRIDE
     }};
 
@@ -657,32 +669,4 @@ macro_rules! register {
         $stride
     }};
     (@stride $ty: ty) => { ::core::mem::size_of::<$ty>() };
-
-    // Implementations shared by all registers types.
-    (@io_base $reg_base:ty; $name:ident @ $offset:expr) => {
-        impl $crate::io::register::Register for $name {
-            type Base = $reg_base;
-
-            const OFFSET: usize = $offset;
-        }
-    };
-
-    // Implementations of fixed registers.
-    (@io_fixed $(#[$attr:meta])* $vis:vis $name:ident) => {
-        impl $crate::io::register::FixedRegister for $name {}
-
-        $(#[$attr])*
-        $vis const $name: $crate::io::register::FixedRegisterLoc<$name> =
-            $crate::io::register::FixedRegisterLoc::<$name>::new();
-    };
-
-    // Implementations of register arrays.
-    (@io_array $vis:vis $name:ident [ $size:expr, stride = $stride:expr ]) => {
-        impl $crate::io::register::Array for $name {}
-
-        impl $crate::io::register::RegisterArray for $name {
-            const SIZE: usize = $size;
-            const STRIDE: usize = $stride;
-        }
-    };
 }

-- 
2.54.0