summaryrefslogtreecommitdiff
path: root/drivers/gpu/nova-core
diff options
context:
space:
mode:
authorDanilo Krummrich <dakr@kernel.org>2026-05-29 00:53:14 +0200
committerDanilo Krummrich <dakr@kernel.org>2026-05-29 00:53:14 +0200
commita3e50e7279996cd987001fd8a3db36e72665f8f7 (patch)
treed5abdce1f60809b46565e2f15dd0ede0dea39994 /drivers/gpu/nova-core
parent9c81596851a342e68ec200f69fc1d5c1dbede289 (diff)
parentd18f3646184fc805d213fc049fc3b5d9fb9a6a27 (diff)
downloadlwn-a3e50e7279996cd987001fd8a3db36e72665f8f7.tar.gz
lwn-a3e50e7279996cd987001fd8a3db36e72665f8f7.zip
Merge tag 'dd-lifetimes-7.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/driver-core/driver-core into drm-rust-next
Higher-Ranked Lifetime Types for Rust device drivers Replace drvdata() with registration data on the auxiliary bus. Private data is now scoped to the registration object, removing the ordering constraints and lifetime complications that came with drvdata(). Add Higher-Ranked Lifetime Types (HRT) so driver structs can borrow device resources like pci::Bar and IoMem directly, tied to the device binding scope. This removes the need for Devres indirection and ARef<Device> in most driver code. This is a stable tag for other trees to merge. Signed-off-by: Danilo Krummrich <dakr@kernel.org>
Diffstat (limited to 'drivers/gpu/nova-core')
-rw-r--r--drivers/gpu/nova-core/driver.rs38
-rw-r--r--drivers/gpu/nova-core/gpu.rs2
-rw-r--r--drivers/gpu/nova-core/nova_core.rs2
3 files changed, 25 insertions, 17 deletions
diff --git a/drivers/gpu/nova-core/driver.rs b/drivers/gpu/nova-core/driver.rs
index 84b0e1703150..d3f2245ba2e0 100644
--- a/drivers/gpu/nova-core/driver.rs
+++ b/drivers/gpu/nova-core/driver.rs
@@ -3,7 +3,6 @@
use kernel::{
auxiliary,
device::Core,
- devres::Devres,
dma::Device,
dma::DmaMask,
pci,
@@ -21,6 +20,7 @@ use kernel::{
},
Arc,
},
+ types::ForLt,
};
use crate::gpu::Gpu;
@@ -29,13 +29,15 @@ use crate::gpu::Gpu;
static AUXILIARY_ID_COUNTER: Atomic<u32> = Atomic::new(0);
#[pin_data]
-pub(crate) struct NovaCore {
+pub(crate) struct NovaCore<'bound> {
#[pin]
pub(crate) gpu: Gpu,
- #[pin]
- _reg: Devres<auxiliary::Registration>,
+ #[allow(clippy::type_complexity)]
+ _reg: auxiliary::Registration<'bound, ForLt!(())>,
}
+pub(crate) struct NovaCoreDriver;
+
const BAR0_SIZE: usize = SZ_16M;
// For now we only support Ampere which can use up to 47-bit DMA addresses.
@@ -46,12 +48,12 @@ const BAR0_SIZE: usize = SZ_16M;
// DMA addresses. These systems should be quite rare.
const GPU_DMA_BITS: u32 = 47;
-pub(crate) type Bar0 = pci::Bar<BAR0_SIZE>;
+pub(crate) type Bar0 = pci::Bar<'static, BAR0_SIZE>;
kernel::pci_device_table!(
PCI_TABLE,
MODULE_PCI_TABLE,
- <NovaCore as pci::Driver>::IdInfo,
+ <NovaCoreDriver as pci::Driver>::IdInfo,
[
// Modern NVIDIA GPUs will show up as either VGA or 3D controllers.
(
@@ -73,11 +75,15 @@ kernel::pci_device_table!(
]
);
-impl pci::Driver for NovaCore {
+impl pci::Driver for NovaCoreDriver {
type IdInfo = ();
+ type Data<'bound> = NovaCore<'bound>;
const ID_TABLE: pci::IdTable<Self::IdInfo> = &PCI_TABLE;
- fn probe(pdev: &pci::Device<Core>, _info: &Self::IdInfo) -> impl PinInit<Self, Error> {
+ fn probe<'bound>(
+ pdev: &'bound pci::Device<Core<'_>>,
+ _info: &'bound Self::IdInfo,
+ ) -> impl PinInit<Self::Data<'bound>, Error> + 'bound {
pin_init::pin_init_scope(move || {
dev_dbg!(pdev, "Probe Nova Core GPU driver.\n");
@@ -89,26 +95,28 @@ impl pci::Driver for NovaCore {
// other threads of execution.
unsafe { pdev.dma_set_mask_and_coherent(DmaMask::new::<GPU_DMA_BITS>())? };
- let bar = Arc::pin_init(
- pdev.iomap_region_sized::<BAR0_SIZE>(0, c"nova-core/bar0"),
+ let bar = Arc::new(
+ pdev.iomap_region_sized::<BAR0_SIZE>(0, c"nova-core/bar0")?
+ .into_devres()?,
GFP_KERNEL,
)?;
- Ok(try_pin_init!(Self {
+ Ok(try_pin_init!(NovaCore {
gpu <- Gpu::new(pdev, bar.clone(), bar.access(pdev.as_ref())?),
- _reg <- auxiliary::Registration::new(
+ _reg: auxiliary::Registration::new(
pdev.as_ref(),
c"nova-drm",
// TODO[XARR]: Use XArray or perhaps IDA for proper ID allocation/recycling. For
// now, use a simple atomic counter that never recycles IDs.
AUXILIARY_ID_COUNTER.fetch_add(1, Relaxed),
- crate::MODULE_NAME
- ),
+ crate::MODULE_NAME,
+ (),
+ )?,
}))
})
}
- fn unbind(pdev: &pci::Device<Core>, this: Pin<&Self>) {
+ fn unbind<'bound>(pdev: &'bound pci::Device<Core<'_>>, this: Pin<&Self::Data<'bound>>) {
this.gpu.unbind(pdev.as_ref());
}
}
diff --git a/drivers/gpu/nova-core/gpu.rs b/drivers/gpu/nova-core/gpu.rs
index 659f6a24ee13..78c4195e6132 100644
--- a/drivers/gpu/nova-core/gpu.rs
+++ b/drivers/gpu/nova-core/gpu.rs
@@ -300,7 +300,7 @@ impl Gpu {
/// Called when the corresponding [`Device`](device::Device) is unbound.
///
/// Note: This method must only be called from `Driver::unbind`.
- pub(crate) fn unbind(&self, dev: &device::Device<device::Core>) {
+ pub(crate) fn unbind(&self, dev: &device::Device<device::Core<'_>>) {
kernel::warn_on!(self
.bar
.access(dev)
diff --git a/drivers/gpu/nova-core/nova_core.rs b/drivers/gpu/nova-core/nova_core.rs
index c488058880be..5a260062295f 100644
--- a/drivers/gpu/nova-core/nova_core.rs
+++ b/drivers/gpu/nova-core/nova_core.rs
@@ -46,7 +46,7 @@ struct NovaCoreModule {
// Fields are dropped in declaration order, so `_driver` is dropped first,
// then `_debugfs_guard` clears `DEBUGFS_ROOT`.
#[pin]
- _driver: Registration<pci::Adapter<driver::NovaCore>>,
+ _driver: Registration<pci::Adapter<driver::NovaCoreDriver>>,
_debugfs_guard: DebugfsRootGuard,
}