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

From: Gary Guo

Date: Wed Aug 19 2026 - 07:18:55 EST


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 <gary@xxxxxxxxxxx>
---
rust/kernel/io/register.rs | 22 +++++++++++++---------
rust/macros/io/register.rs | 12 ++++++------
2 files changed, 19 insertions(+), 15 deletions(-)

diff --git a/rust/kernel/io/register.rs b/rust/kernel/io/register.rs
index 4d4afd3ae94a..6aeee6c0a5f2 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>;

@@ -294,7 +298,7 @@ fn into_io_op(self) -> (FixedRegisterLoc<T>, T) {
/// This is used to enforce base matching. Only called during const eval.
#[doc(hidden)]
#[inline(always)]
-pub const fn alias_offset<Base: ?Sized, Alias: Register<Base = Base>>() -> usize {
+pub const fn alias_offset<Base: ?Sized, Alias: FixedRegister<Base = Base>>() -> usize {
Alias::OFFSET
}

diff --git a/rust/macros/io/register.rs b/rust/macros/io/register.rs
index 757ea8094f61..e0bba6b71ebc 100644
--- a/rust/macros/io/register.rs
+++ b/rust/macros/io/register.rs
@@ -213,11 +213,6 @@ pub(crate) fn register(def: RegDef) -> Result<TokenStream> {
#[allow(non_camel_case_types)]
#(#attrs)* #vis struct #name(#storage) #args
);
-
- impl ::kernel::io::register::Register for #name {
- type Base = #base;
- const OFFSET: usize = #offset;
- }
));
}

@@ -233,7 +228,10 @@ impl ::kernel::io::register::Register for #name {
))?,

None => outputs.extend(quote_spanned!(span =>
- impl ::kernel::io::register::FixedRegister for #name {}
+ impl ::kernel::io::register::FixedRegister for #name {
+ type Base = #base;
+ const OFFSET: usize = #offset;
+ }

#(#attrs)* #vis const #name: ::kernel::io::register::FixedRegisterLoc<#name> =
::kernel::io::register::FixedRegisterLoc::<#name>::new();
@@ -256,6 +254,8 @@ impl ::kernel::io::register::FixedRegister for #name {}
impl ::kernel::io::register::Array for #name {}

impl ::kernel::io::register::RegisterArray for #name {
+ type Base = #base;
+ const OFFSET: usize = #offset;
const SIZE: usize = #size;
const STRIDE: usize = #stride;
}

--
2.54.0