[PATCH v2 08/21] gpu: nova-core: introduce helper macro for register access

Alexandre Courbot acourbot at nvidia.com
Thu May 1 12:58:26 UTC 2025


Acquiring the BAR temporarily to access is going to be a very common
pattern, that typically takes two lines of code and introduces a
short-lived local variable.

Add the Nova-local convenience with_bar!() macro, which uses
Revocable::try_access_with() and converts its returned Option into the
proper error as needed.

Signed-off-by: Alexandre Courbot <acourbot at nvidia.com>
---
 drivers/gpu/nova-core/gpu.rs         |  3 +--
 drivers/gpu/nova-core/nova_core.rs   | 18 ++++++++++++++++++
 drivers/gpu/nova-core/regs/macros.rs |  1 +
 3 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/nova-core/gpu.rs b/drivers/gpu/nova-core/gpu.rs
index 64c38425098c19360a7c938f2b86a55ca3c48880..275b005d262e0a01a9ef1498836ef3c3019cb497 100644
--- a/drivers/gpu/nova-core/gpu.rs
+++ b/drivers/gpu/nova-core/gpu.rs
@@ -148,8 +148,7 @@ pub(crate) struct Spec {
 
 impl Spec {
     fn new(bar: &Devres<Bar0>) -> Result<Spec> {
-        let bar = bar.try_access().ok_or(ENXIO)?;
-        let boot0 = regs::NV_PMC_BOOT_0::read(&*bar);
+        let boot0 = with_bar!(bar, regs::NV_PMC_BOOT_0::read)?;
 
         Ok(Self {
             chipset: boot0.chipset()?,
diff --git a/drivers/gpu/nova-core/nova_core.rs b/drivers/gpu/nova-core/nova_core.rs
index a91cd924054b49966937a8db6aab9cd0614f10de..0eecd612e34efc046dad852e6239de6ffa5fdd62 100644
--- a/drivers/gpu/nova-core/nova_core.rs
+++ b/drivers/gpu/nova-core/nova_core.rs
@@ -2,6 +2,24 @@
 
 //! Nova Core GPU Driver
 
+#[macro_use]
+mod macros {
+    /// Convenience macro to run a closure while holding [`crate::driver::Bar0`].
+    ///
+    /// If the bar cannot be acquired, then `ENXIO` is returned.
+    ///
+    /// If a `?` is present before the `bar` argument, then the `Result` returned by the closure is
+    /// merged into the `Result` of the macro itself to avoid having a `Result<Result<>>`.
+    macro_rules! with_bar {
+        ($bar:expr, $closure:expr) => {
+            $bar.try_access_with($closure).ok_or(ENXIO)
+        };
+        (? $bar:expr, $closure:expr) => {
+            with_bar!($bar, $closure).and_then(|r| r)
+        };
+    }
+}
+
 mod driver;
 mod firmware;
 mod gpu;
diff --git a/drivers/gpu/nova-core/regs/macros.rs b/drivers/gpu/nova-core/regs/macros.rs
index a08d4f2aa0a32b00e80dae4e6b2c79d072241734..7ecc70efb3cd723b673cd72915e72b8a4a009f06 100644
--- a/drivers/gpu/nova-core/regs/macros.rs
+++ b/drivers/gpu/nova-core/regs/macros.rs
@@ -68,6 +68,7 @@
 ///
 /// // Flip the `start` switch for the CPU core which base address is at `CPU_BASE`.
 /// let cpuctl = CPU_CTL::read(&bar, CPU_BASE);
+/// pr_info!("CPU CTL: {:#x}", cpuctl);
 /// cpuctl.set_start(true).write(&bar, CPU_BASE);
 /// ```
 macro_rules! register {

-- 
2.49.0



More information about the dri-devel mailing list