[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20251231214727.448776-1-jhubbard@nvidia.com>
Date: Wed, 31 Dec 2025 13:47:27 -0800
From: John Hubbard <jhubbard@...dia.com>
To: Danilo Krummrich <dakr@...nel.org>
Cc: Alexandre Courbot <acourbot@...dia.com>,
Joel Fernandes <joelagnelf@...dia.com>,
Timur Tabi <ttabi@...dia.com>,
Alistair Popple <apopple@...dia.com>,
Edwin Peer <epeer@...dia.com>,
Zhi Wang <zhiw@...dia.com>,
David Airlie <airlied@...il.com>,
Simona Vetter <simona@...ll.ch>,
Bjorn Helgaas <bhelgaas@...gle.com>,
Miguel Ojeda <ojeda@...nel.org>,
Alex Gaynor <alex.gaynor@...il.com>,
Boqun Feng <boqun.feng@...il.com>,
Gary Guo <gary@...yguo.net>,
Björn Roy Baron <bjorn3_gh@...tonmail.com>,
Benno Lossin <lossin@...nel.org>,
Andreas Hindborg <a.hindborg@...nel.org>,
Alice Ryhl <aliceryhl@...gle.com>,
Trevor Gross <tmgross@...ch.edu>,
nouveau@...ts.freedesktop.org,
rust-for-linux@...r.kernel.org,
LKML <linux-kernel@...r.kernel.org>,
John Hubbard <jhubbard@...dia.com>
Subject: [PATCH] gpu: nova-core: bitfield: use &mut self setters instead of builder pattern
The builder-pattern setters (self -> Self) enabled method chaining like:
reg.set_foo(x).set_sec(y).write(bar);
This made separate operations appear as a single expression, obscuring
that each setter is a distinct mutation. These setters are infallible,
so the chaining provides no error-propagation benefit—it just obscures
what are simple, independent assignments.
Change the bitfield!() macro to generate `&mut self` setters, so each
operation is a distinct statement:
reg.set_foo(x);
reg.set_sec(y);
reg.write(bar);
Update all call sites and change update() closures to take `&mut Self`.
Signed-off-by: John Hubbard <jhubbard@...dia.com>
---
drivers/gpu/nova-core/bitfield.rs | 4 +-
drivers/gpu/nova-core/falcon.rs | 98 ++++++++++++-----------
drivers/gpu/nova-core/falcon/gsp.rs | 6 +-
drivers/gpu/nova-core/falcon/hal/ga102.rs | 33 ++++----
drivers/gpu/nova-core/fb/hal/ga100.rs | 21 ++---
drivers/gpu/nova-core/fb/hal/tu102.rs | 6 +-
drivers/gpu/nova-core/gsp/cmdq.rs | 6 +-
drivers/gpu/nova-core/gsp/fw.rs | 7 +-
drivers/gpu/nova-core/regs/macros.rs | 41 ++++++----
9 files changed, 120 insertions(+), 102 deletions(-)
diff --git a/drivers/gpu/nova-core/bitfield.rs b/drivers/gpu/nova-core/bitfield.rs
index 16e143658c51..be152d1e08e0 100644
--- a/drivers/gpu/nova-core/bitfield.rs
+++ b/drivers/gpu/nova-core/bitfield.rs
@@ -284,13 +284,11 @@ impl $name {
#[doc=$comment]
)?
#[inline(always)]
- $vis fn [<set_ $field>](mut self, value: $to_type) -> Self {
+ $vis fn [<set_ $field>](&mut self, value: $to_type) {
const MASK: $storage = $name::[<$field:upper _MASK>];
const SHIFT: u32 = $name::[<$field:upper _SHIFT>];
let value = ($storage::from($prim_type::from(value)) << SHIFT) & MASK;
self.0 = (self.0 & !MASK) | value;
-
- self
}
);
};
diff --git a/drivers/gpu/nova-core/falcon.rs b/drivers/gpu/nova-core/falcon.rs
index 82c661aef594..66fd37c73a3a 100644
--- a/drivers/gpu/nova-core/falcon.rs
+++ b/drivers/gpu/nova-core/falcon.rs
@@ -413,12 +413,12 @@ fn reset_eng(&self, bar: &Bar0) -> Result {
Delta::from_micros(150),
);
- regs::NV_PFALCON_FALCON_ENGINE::update(bar, &E::ID, |v| v.set_reset(true));
+ regs::NV_PFALCON_FALCON_ENGINE::update(bar, &E::ID, |v| { v.set_reset(true); });
// TIMEOUT: falcon engine should not take more than 10us to reset.
fsleep(Delta::from_micros(10));
- regs::NV_PFALCON_FALCON_ENGINE::update(bar, &E::ID, |v| v.set_reset(false));
+ regs::NV_PFALCON_FALCON_ENGINE::update(bar, &E::ID, |v| { v.set_reset(false); });
self.reset_wait_mem_scrubbing(bar)?;
@@ -431,9 +431,9 @@ pub(crate) fn reset(&self, bar: &Bar0) -> Result {
self.hal.select_core(self, bar)?;
self.reset_wait_mem_scrubbing(bar)?;
- regs::NV_PFALCON_FALCON_RM::default()
- .set_value(regs::NV_PMC_BOOT_0::read(bar).into())
- .write(bar, &E::ID);
+ let mut reg = regs::NV_PFALCON_FALCON_RM::default();
+ reg.set_value(regs::NV_PMC_BOOT_0::read(bar).into());
+ reg.write(bar, &E::ID);
Ok(())
}
@@ -495,30 +495,32 @@ fn dma_wr<F: FalconFirmware<Target = E>>(
// Set up the base source DMA address.
- regs::NV_PFALCON_FALCON_DMATRFBASE::default()
- // CAST: `as u32` is used on purpose since we do want to strip the upper bits, which
- // will be written to `NV_PFALCON_FALCON_DMATRFBASE1`.
- .set_base((dma_start >> 8) as u32)
- .write(bar, &E::ID);
- regs::NV_PFALCON_FALCON_DMATRFBASE1::default()
- // CAST: `as u16` is used on purpose since the remaining bits are guaranteed to fit
- // within a `u16`.
- .set_base((dma_start >> 40) as u16)
- .write(bar, &E::ID);
-
- let cmd = regs::NV_PFALCON_FALCON_DMATRFCMD::default()
- .set_size(DmaTrfCmdSize::Size256B)
- .set_imem(target_mem == FalconMem::Imem)
- .set_sec(if sec { 1 } else { 0 });
+ // CAST: `as u32` is used on purpose since we do want to strip the upper bits, which
+ // will be written to `NV_PFALCON_FALCON_DMATRFBASE1`.
+ let mut reg = regs::NV_PFALCON_FALCON_DMATRFBASE::default();
+ reg.set_base((dma_start >> 8) as u32);
+ reg.write(bar, &E::ID);
+
+ // CAST: `as u16` is used on purpose since the remaining bits are guaranteed to fit
+ // within a `u16`.
+ let mut reg = regs::NV_PFALCON_FALCON_DMATRFBASE1::default();
+ reg.set_base((dma_start >> 40) as u16);
+ reg.write(bar, &E::ID);
+
+ let mut cmd = regs::NV_PFALCON_FALCON_DMATRFCMD::default();
+ cmd.set_size(DmaTrfCmdSize::Size256B);
+ cmd.set_imem(target_mem == FalconMem::Imem);
+ cmd.set_sec(if sec { 1 } else { 0 });
for pos in (0..num_transfers).map(|i| i * DMA_LEN) {
// Perform a transfer of size `DMA_LEN`.
- regs::NV_PFALCON_FALCON_DMATRFMOFFS::default()
- .set_offs(load_offsets.dst_start + pos)
- .write(bar, &E::ID);
- regs::NV_PFALCON_FALCON_DMATRFFBOFFS::default()
- .set_offs(src_start + pos)
- .write(bar, &E::ID);
+ let mut reg = regs::NV_PFALCON_FALCON_DMATRFMOFFS::default();
+ reg.set_offs(load_offsets.dst_start + pos);
+ reg.write(bar, &E::ID);
+
+ let mut reg = regs::NV_PFALCON_FALCON_DMATRFFBOFFS::default();
+ reg.set_offs(src_start + pos);
+ reg.write(bar, &E::ID);
cmd.write(bar, &E::ID);
// Wait for the transfer to complete.
@@ -539,8 +541,8 @@ fn dma_wr<F: FalconFirmware<Target = E>>(
pub(crate) fn dma_load<F: FalconFirmware<Target = E>>(&self, bar: &Bar0, fw: &F) -> Result {
self.dma_reset(bar);
regs::NV_PFALCON_FBIF_TRANSCFG::update(bar, &E::ID, 0, |v| {
- v.set_target(FalconFbifTarget::CoherentSysmem)
- .set_mem_type(FalconFbifMemType::Physical)
+ v.set_target(FalconFbifTarget::CoherentSysmem);
+ v.set_mem_type(FalconFbifMemType::Physical);
});
self.dma_wr(bar, fw, FalconMem::Imem, fw.imem_load_params(), true)?;
@@ -549,9 +551,9 @@ pub(crate) fn dma_load<F: FalconFirmware<Target = E>>(&self, bar: &Bar0, fw: &F)
self.hal.program_brom(self, bar, &fw.brom_params())?;
// Set `BootVec` to start of non-secure code.
- regs::NV_PFALCON_FALCON_BOOTVEC::default()
- .set_value(fw.boot_addr())
- .write(bar, &E::ID);
+ let mut reg = regs::NV_PFALCON_FALCON_BOOTVEC::default();
+ reg.set_value(fw.boot_addr());
+ reg.write(bar, &E::ID);
Ok(())
}
@@ -572,12 +574,16 @@ pub(crate) fn wait_till_halted(&self, bar: &Bar0) -> Result<()> {
/// Start the falcon CPU.
pub(crate) fn start(&self, bar: &Bar0) -> Result<()> {
match regs::NV_PFALCON_FALCON_CPUCTL::read(bar, &E::ID).alias_en() {
- true => regs::NV_PFALCON_FALCON_CPUCTL_ALIAS::default()
- .set_startcpu(true)
- .write(bar, &E::ID),
- false => regs::NV_PFALCON_FALCON_CPUCTL::default()
- .set_startcpu(true)
- .write(bar, &E::ID),
+ true => {
+ let mut reg = regs::NV_PFALCON_FALCON_CPUCTL_ALIAS::default();
+ reg.set_startcpu(true);
+ reg.write(bar, &E::ID);
+ }
+ false => {
+ let mut reg = regs::NV_PFALCON_FALCON_CPUCTL::default();
+ reg.set_startcpu(true);
+ reg.write(bar, &E::ID);
+ }
}
Ok(())
@@ -586,15 +592,15 @@ pub(crate) fn start(&self, bar: &Bar0) -> Result<()> {
/// Writes values to the mailbox registers if provided.
pub(crate) fn write_mailboxes(&self, bar: &Bar0, mbox0: Option<u32>, mbox1: Option<u32>) {
if let Some(mbox0) = mbox0 {
- regs::NV_PFALCON_FALCON_MAILBOX0::default()
- .set_value(mbox0)
- .write(bar, &E::ID);
+ let mut reg = regs::NV_PFALCON_FALCON_MAILBOX0::default();
+ reg.set_value(mbox0);
+ reg.write(bar, &E::ID);
}
if let Some(mbox1) = mbox1 {
- regs::NV_PFALCON_FALCON_MAILBOX1::default()
- .set_value(mbox1)
- .write(bar, &E::ID);
+ let mut reg = regs::NV_PFALCON_FALCON_MAILBOX1::default();
+ reg.set_value(mbox1);
+ reg.write(bar, &E::ID);
}
}
@@ -657,8 +663,8 @@ pub(crate) fn is_riscv_active(&self, bar: &Bar0) -> bool {
/// Write the application version to the OS register.
pub(crate) fn write_os_version(&self, bar: &Bar0, app_version: u32) {
- regs::NV_PFALCON_FALCON_OS::default()
- .set_value(app_version)
- .write(bar, &E::ID);
+ let mut reg = regs::NV_PFALCON_FALCON_OS::default();
+ reg.set_value(app_version);
+ reg.write(bar, &E::ID);
}
}
diff --git a/drivers/gpu/nova-core/falcon/gsp.rs b/drivers/gpu/nova-core/falcon/gsp.rs
index 67edef3636c1..ce76c75cfdc6 100644
--- a/drivers/gpu/nova-core/falcon/gsp.rs
+++ b/drivers/gpu/nova-core/falcon/gsp.rs
@@ -39,9 +39,9 @@ impl Falcon<Gsp> {
/// Clears the SWGEN0 bit in the Falcon's IRQ status clear register to
/// allow GSP to signal CPU for processing new messages in message queue.
pub(crate) fn clear_swgen0_intr(&self, bar: &Bar0) {
- regs::NV_PFALCON_FALCON_IRQSCLR::default()
- .set_swgen0(true)
- .write(bar, &Gsp::ID);
+ let mut reg = regs::NV_PFALCON_FALCON_IRQSCLR::default();
+ reg.set_swgen0(true);
+ reg.write(bar, &Gsp::ID);
}
/// Checks if GSP reload/resume has completed during the boot process.
diff --git a/drivers/gpu/nova-core/falcon/hal/ga102.rs b/drivers/gpu/nova-core/falcon/hal/ga102.rs
index 69a7a95cac16..4fb94c727b65 100644
--- a/drivers/gpu/nova-core/falcon/hal/ga102.rs
+++ b/drivers/gpu/nova-core/falcon/hal/ga102.rs
@@ -26,9 +26,9 @@
fn select_core_ga102<E: FalconEngine>(bar: &Bar0) -> Result {
let bcr_ctrl = regs::NV_PRISCV_RISCV_BCR_CTRL::read(bar, &E::ID);
if bcr_ctrl.core_select() != PeregrineCoreSelect::Falcon {
- regs::NV_PRISCV_RISCV_BCR_CTRL::default()
- .set_core_select(PeregrineCoreSelect::Falcon)
- .write(bar, &E::ID);
+ let mut reg = regs::NV_PRISCV_RISCV_BCR_CTRL::default();
+ reg.set_core_select(PeregrineCoreSelect::Falcon);
+ reg.write(bar, &E::ID);
// TIMEOUT: falcon core should take less than 10ms to report being enabled.
read_poll_timeout(
@@ -75,18 +75,21 @@ fn signature_reg_fuse_version_ga102(
}
fn program_brom_ga102<E: FalconEngine>(bar: &Bar0, params: &FalconBromParams) -> Result {
- regs::NV_PFALCON2_FALCON_BROM_PARAADDR::default()
- .set_value(params.pkc_data_offset)
- .write(bar, &E::ID, 0);
- regs::NV_PFALCON2_FALCON_BROM_ENGIDMASK::default()
- .set_value(u32::from(params.engine_id_mask))
- .write(bar, &E::ID);
- regs::NV_PFALCON2_FALCON_BROM_CURR_UCODE_ID::default()
- .set_ucode_id(params.ucode_id)
- .write(bar, &E::ID);
- regs::NV_PFALCON2_FALCON_MOD_SEL::default()
- .set_algo(FalconModSelAlgo::Rsa3k)
- .write(bar, &E::ID);
+ let mut reg = regs::NV_PFALCON2_FALCON_BROM_PARAADDR::default();
+ reg.set_value(params.pkc_data_offset);
+ reg.write(bar, &E::ID, 0);
+
+ let mut reg = regs::NV_PFALCON2_FALCON_BROM_ENGIDMASK::default();
+ reg.set_value(u32::from(params.engine_id_mask));
+ reg.write(bar, &E::ID);
+
+ let mut reg = regs::NV_PFALCON2_FALCON_BROM_CURR_UCODE_ID::default();
+ reg.set_ucode_id(params.ucode_id);
+ reg.write(bar, &E::ID);
+
+ let mut reg = regs::NV_PFALCON2_FALCON_MOD_SEL::default();
+ reg.set_algo(FalconModSelAlgo::Rsa3k);
+ reg.write(bar, &E::ID);
Ok(())
}
diff --git a/drivers/gpu/nova-core/fb/hal/ga100.rs b/drivers/gpu/nova-core/fb/hal/ga100.rs
index e0acc41aa7cd..027f2f59614f 100644
--- a/drivers/gpu/nova-core/fb/hal/ga100.rs
+++ b/drivers/gpu/nova-core/fb/hal/ga100.rs
@@ -19,16 +19,17 @@ pub(super) fn read_sysmem_flush_page_ga100(bar: &Bar0) -> u64 {
}
pub(super) fn write_sysmem_flush_page_ga100(bar: &Bar0, addr: u64) {
- regs::NV_PFB_NISO_FLUSH_SYSMEM_ADDR_HI::default()
- // CAST: `as u32` is used on purpose since the remaining bits are guaranteed to fit within
- // a `u32`.
- .set_adr_63_40((addr >> FLUSH_SYSMEM_ADDR_SHIFT_HI) as u32)
- .write(bar);
- regs::NV_PFB_NISO_FLUSH_SYSMEM_ADDR::default()
- // CAST: `as u32` is used on purpose since we want to strip the upper bits that have been
- // written to `NV_PFB_NISO_FLUSH_SYSMEM_ADDR_HI`.
- .set_adr_39_08((addr >> FLUSH_SYSMEM_ADDR_SHIFT) as u32)
- .write(bar);
+ // CAST: `as u32` is used on purpose since the remaining bits are guaranteed to fit within
+ // a `u32`.
+ let mut reg = regs::NV_PFB_NISO_FLUSH_SYSMEM_ADDR_HI::default();
+ reg.set_adr_63_40((addr >> FLUSH_SYSMEM_ADDR_SHIFT_HI) as u32);
+ reg.write(bar);
+
+ // CAST: `as u32` is used on purpose since we want to strip the upper bits that have been
+ // written to `NV_PFB_NISO_FLUSH_SYSMEM_ADDR_HI`.
+ let mut reg = regs::NV_PFB_NISO_FLUSH_SYSMEM_ADDR::default();
+ reg.set_adr_39_08((addr >> FLUSH_SYSMEM_ADDR_SHIFT) as u32);
+ reg.write(bar);
}
pub(super) fn display_enabled_ga100(bar: &Bar0) -> bool {
diff --git a/drivers/gpu/nova-core/fb/hal/tu102.rs b/drivers/gpu/nova-core/fb/hal/tu102.rs
index eec984f4e816..994a173dc6f4 100644
--- a/drivers/gpu/nova-core/fb/hal/tu102.rs
+++ b/drivers/gpu/nova-core/fb/hal/tu102.rs
@@ -21,9 +21,9 @@ pub(super) fn write_sysmem_flush_page_gm107(bar: &Bar0, addr: u64) -> Result {
u32::try_from(addr >> FLUSH_SYSMEM_ADDR_SHIFT)
.map_err(|_| EINVAL)
.map(|addr| {
- regs::NV_PFB_NISO_FLUSH_SYSMEM_ADDR::default()
- .set_adr_39_08(addr)
- .write(bar)
+ let mut reg = regs::NV_PFB_NISO_FLUSH_SYSMEM_ADDR::default();
+ reg.set_adr_39_08(addr);
+ reg.write(bar);
})
}
diff --git a/drivers/gpu/nova-core/gsp/cmdq.rs b/drivers/gpu/nova-core/gsp/cmdq.rs
index 6f946d14868a..358c97b96e9a 100644
--- a/drivers/gpu/nova-core/gsp/cmdq.rs
+++ b/drivers/gpu/nova-core/gsp/cmdq.rs
@@ -475,9 +475,9 @@ fn calculate_checksum<T: Iterator<Item = u8>>(it: T) -> u32 {
/// Notifies the GSP that we have updated the command queue pointers.
fn notify_gsp(bar: &Bar0) {
- regs::NV_PGSP_QUEUE_HEAD::default()
- .set_address(0)
- .write(bar);
+ let mut reg = regs::NV_PGSP_QUEUE_HEAD::default();
+ reg.set_address(0);
+ reg.write(bar);
}
/// Sends `command` to the GSP.
diff --git a/drivers/gpu/nova-core/gsp/fw.rs b/drivers/gpu/nova-core/gsp/fw.rs
index abffd6beec65..2436933ac8cd 100644
--- a/drivers/gpu/nova-core/gsp/fw.rs
+++ b/drivers/gpu/nova-core/gsp/fw.rs
@@ -772,9 +772,10 @@ impl MsgHeaderVersion {
const MINOR_TOT: u8 = 0;
fn new() -> Self {
- Self::default()
- .set_major(Self::MAJOR_TOT)
- .set_minor(Self::MINOR_TOT)
+ let mut v = Self::default();
+ v.set_major(Self::MAJOR_TOT);
+ v.set_minor(Self::MINOR_TOT);
+ v
}
}
diff --git a/drivers/gpu/nova-core/regs/macros.rs b/drivers/gpu/nova-core/regs/macros.rs
index fd1a815fa57d..6ab20e960399 100644
--- a/drivers/gpu/nova-core/regs/macros.rs
+++ b/drivers/gpu/nova-core/regs/macros.rs
@@ -49,10 +49,15 @@ pub(crate) trait RegisterBase<T> {
/// let chipset = boot0.chipset()?;
///
/// // Update some fields and write the value back.
-/// boot0.set_major_revision(3).set_minor_revision(10).write(&bar);
+/// boot0.set_major_revision(3);
+/// boot0.set_minor_revision(10);
+/// boot0.write(&bar);
///
/// // Or, just read and update the register in a single step:
-/// BOOT_0::update(&bar, |r| r.set_major_revision(3).set_minor_revision(10));
+/// BOOT_0::update(&bar, |r| {
+/// r.set_major_revision(3);
+/// r.set_minor_revision(10);
+/// });
/// ```
///
/// The documentation strings are optional. If present, they will be added to the type's
@@ -388,12 +393,13 @@ pub(crate) fn write<const SIZE: usize, T>(self, io: &T) where
#[inline(always)]
pub(crate) fn update<const SIZE: usize, T, F>(
io: &T,
- f: F,
+ mut f: F,
) where
T: ::core::ops::Deref<Target = ::kernel::io::Io<SIZE>>,
- F: ::core::ops::FnOnce(Self) -> Self,
+ F: ::core::ops::FnMut(&mut Self),
{
- let reg = f(Self::read(io));
+ let mut reg = Self::read(io);
+ f(&mut reg);
reg.write(io);
}
}
@@ -452,13 +458,14 @@ pub(crate) fn write<const SIZE: usize, T, B>(
pub(crate) fn update<const SIZE: usize, T, B, F>(
io: &T,
base: &B,
- f: F,
+ mut f: F,
) where
T: ::core::ops::Deref<Target = ::kernel::io::Io<SIZE>>,
B: crate::regs::macros::RegisterBase<$base>,
- F: ::core::ops::FnOnce(Self) -> Self,
+ F: ::core::ops::FnMut(&mut Self),
{
- let reg = f(Self::read(io, base));
+ let mut reg = Self::read(io, base);
+ f(&mut reg);
reg.write(io, base);
}
}
@@ -510,12 +517,13 @@ pub(crate) fn write<const SIZE: usize, T>(
pub(crate) fn update<const SIZE: usize, T, F>(
io: &T,
idx: usize,
- f: F,
+ mut f: F,
) where
T: ::core::ops::Deref<Target = ::kernel::io::Io<SIZE>>,
- F: ::core::ops::FnOnce(Self) -> Self,
+ F: ::core::ops::FnMut(&mut Self),
{
- let reg = f(Self::read(io, idx));
+ let mut reg = Self::read(io, idx);
+ f(&mut reg);
reg.write(io, idx);
}
@@ -568,7 +576,7 @@ pub(crate) fn try_update<const SIZE: usize, T, F>(
f: F,
) -> ::kernel::error::Result where
T: ::core::ops::Deref<Target = ::kernel::io::Io<SIZE>>,
- F: ::core::ops::FnOnce(Self) -> Self,
+ F: ::core::ops::FnMut(&mut Self),
{
if idx < Self::SIZE {
Ok(Self::update(io, idx, f))
@@ -640,13 +648,14 @@ pub(crate) fn update<const SIZE: usize, T, B, F>(
io: &T,
base: &B,
idx: usize,
- f: F,
+ mut f: F,
) where
T: ::core::ops::Deref<Target = ::kernel::io::Io<SIZE>>,
B: crate::regs::macros::RegisterBase<$base>,
- F: ::core::ops::FnOnce(Self) -> Self,
+ F: ::core::ops::FnMut(&mut Self),
{
- let reg = f(Self::read(io, base, idx));
+ let mut reg = Self::read(io, base, idx);
+ f(&mut reg);
reg.write(io, base, idx);
}
@@ -708,7 +717,7 @@ pub(crate) fn try_update<const SIZE: usize, T, B, F>(
) -> ::kernel::error::Result where
T: ::core::ops::Deref<Target = ::kernel::io::Io<SIZE>>,
B: crate::regs::macros::RegisterBase<$base>,
- F: ::core::ops::FnOnce(Self) -> Self,
+ F: ::core::ops::FnMut(&mut Self),
{
if idx < Self::SIZE {
Ok(Self::update(io, base, idx, f))
base-commit: 7acc70476f14661149774ab88d3fe23d83ba4249
--
2.52.0
Powered by blists - more mailing lists