summaryrefslogtreecommitdiff
path: root/drivers/gpu
diff options
context:
space:
mode:
authorDanilo Krummrich <dakr@kernel.org>2026-09-29 20:59:30 +0200
committerDanilo Krummrich <dakr@kernel.org>2026-10-10 22:15:45 +0200
commit700eed1364e8a5ec4318d457cf700611decdb175 (patch)
tree177a3b320b1f6cc84b5216c6631787547e54a5b4 /drivers/gpu
parent3e3404c52370595e37eb5b942df169884f38a124 (diff)
downloadlinux-700eed1364e8a5ec4318d457cf700611decdb175.tar.gz
linux-700eed1364e8a5ec4318d457cf700611decdb175.zip
rust: drm: Return impl PinInit from drm::Registration::new()
Convert drm::Registration to return an impl PinInit<Self, Error> rather than creating a separate allocation. This removes an otherwise unnecessary allocation. Update both in-tree callers (nova, tyr) to construct their bus device private data using try_pin_init!(). Reviewed-by: Alice Ryhl <aliceryhl@google.com> Link: https://patch.msgid.link/20260929190024.2248099-1-dakr@kernel.org Signed-off-by: Danilo Krummrich <dakr@kernel.org>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/nova/driver.rs27
-rw-r--r--drivers/gpu/drm/tyr/driver.rs138
2 files changed, 86 insertions, 79 deletions
diff --git a/drivers/gpu/drm/nova/driver.rs b/drivers/gpu/drm/nova/driver.rs
index 851d50b4dd15..7a51d49feb1f 100644
--- a/drivers/gpu/drm/nova/driver.rs
+++ b/drivers/gpu/drm/nova/driver.rs
@@ -25,10 +25,11 @@ use nova_core::api::{
pub(crate) struct NovaDriver;
+#[pin_data]
pub(crate) struct Nova<'bound> {
- #[expect(unused)]
drm: ARef<drm::Device<NovaDriver>>,
- _reg: drm::Registration<'bound, NovaDriver>,
+ #[pin]
+ reg: drm::Registration<'bound, NovaDriver>,
}
/// DRM registration data, accessible from ioctl handlers via the registration guard.
@@ -68,17 +69,19 @@ impl auxiliary::Driver for NovaDriver {
adev: &'bound auxiliary::Device<Core<'_>>,
_info: &'bound Self::IdInfo,
) -> impl PinInit<Self::Data<'bound>, Error> + 'bound {
- let drm = drm::UnregisteredDevice::<Self>::new(adev, Ok(()))?;
- let reg_data = DrmRegData {
- api: NovaCoreApi::of(adev)?,
- };
- // SAFETY: `reg` is stored in `Nova` and dropped when the driver is unbound; it is
- // never forgotten.
- let reg = unsafe { drm::Registration::new(adev.as_ref(), drm, reg_data, 0)? };
-
- Ok(Nova {
+ try_pin_init!(Self::Data {
+ reg <- {
+ let drm = drm::UnregisteredDevice::<Self>::new(adev, Ok(()))?;
+
+ let reg_data = DrmRegData {
+ api: NovaCoreApi::of(adev)?,
+ };
+
+ // SAFETY: `reg` is stored in `Self::Data` and dropped when the driver is unbound;
+ // it is never forgotten.
+ unsafe { drm::Registration::new(adev.as_ref(), drm, reg_data, 0) }
+ },
drm: reg.device().into(),
- _reg: reg,
})
}
}
diff --git a/drivers/gpu/drm/tyr/driver.rs b/drivers/gpu/drm/tyr/driver.rs
index 730b84e37a54..6e1008290b5f 100644
--- a/drivers/gpu/drm/tyr/driver.rs
+++ b/drivers/gpu/drm/tyr/driver.rs
@@ -57,6 +57,7 @@ pub(crate) struct TyrPlatformDriver;
#[pin_data(PinnedDrop)]
pub(crate) struct TyrPlatformDriverData<'bound> {
+ #[pin]
_reg: drm::Registration<'bound, TyrDrmDriver>,
}
@@ -117,73 +118,76 @@ impl platform::Driver for TyrPlatformDriver {
pdev: &'bound platform::Device<Core<'_>>,
_info: Option<&'bound Self::IdInfo>,
) -> impl PinInit<Self::Data<'bound>, Error> + 'bound {
- let core_clk = Clk::get(pdev.as_ref(), Some(c"core"))?;
- let stacks_clk = OptionalClk::get(pdev.as_ref(), Some(c"stacks"))?;
- let coregroup_clk = OptionalClk::get(pdev.as_ref(), Some(c"coregroup"))?;
-
- core_clk.prepare_enable()?;
- stacks_clk.prepare_enable()?;
- coregroup_clk.prepare_enable()?;
-
- let mali_regulator = Regulator::<regulator::Enabled>::get(pdev.as_ref(), c"mali")?;
- let sram_regulator = Regulator::<regulator::Enabled>::get(pdev.as_ref(), c"sram")?;
-
- let request = pdev.io_request_by_index(0).ok_or(ENODEV)?;
-
- let iomem = Arc::new(request.iomap_sized::<SZ_2M>()?, GFP_KERNEL)?;
-
- issue_soft_reset(pdev.as_ref(), &iomem)?;
- gpu::l2_power_on(pdev.as_ref(), &iomem)?;
-
- let gpu_info = GpuInfo::new(&iomem);
- gpu_info.log(pdev.as_ref());
-
- let pa_bits = MMU_FEATURES::from_raw(gpu_info.mmu_features)
- .pa_bits()
- .get();
- // SAFETY: No concurrent DMA allocations or mappings can be made because
- // the device is still being probed and therefore isn't being used by
- // other threads of execution.
- unsafe { pdev.dma_set_mask_and_coherent(DmaMask::try_new(pa_bits)?)? };
-
- let unreg_dev = drm::UnregisteredDevice::<TyrDrmDriver>::new(pdev, Ok(()))?;
-
- let mmu = Mmu::new(pdev.as_ref(), iomem.as_arc_borrow(), &gpu_info)?;
-
- let firmware = Firmware::new(
- pdev.as_ref(),
- iomem.clone(),
- &unreg_dev,
- mmu.as_arc_borrow(),
- &gpu_info,
- )?;
-
- firmware.boot()?;
-
- let reg_data = pin_init!(TyrDrmRegistrationData {
- pdev,
- fw: firmware,
- clks <- new_mutex!(Clocks {
- core: core_clk,
- stacks: stacks_clk,
- coregroup: coregroup_clk,
- }),
- regulators <- new_mutex!(Regulators {
- _mali: mali_regulator,
- _sram: sram_regulator,
- }),
- iomem,
- gpu_info,
- });
-
- // SAFETY: `reg` is stored in `TyrPlatformDriverData` and dropped when the driver is
- // unbound; it is never forgotten.
- let reg = unsafe { drm::Registration::new(pdev.as_ref(), unreg_dev, reg_data, 0)? };
-
- let driver = TyrPlatformDriverData { _reg: reg };
-
- dev_dbg!(pdev, "Tyr initialized correctly.");
- Ok(driver)
+ pin_init::pin_init_scope(move || {
+ let core_clk = Clk::get(pdev.as_ref(), Some(c"core"))?;
+ let stacks_clk = OptionalClk::get(pdev.as_ref(), Some(c"stacks"))?;
+ let coregroup_clk = OptionalClk::get(pdev.as_ref(), Some(c"coregroup"))?;
+
+ core_clk.prepare_enable()?;
+ stacks_clk.prepare_enable()?;
+ coregroup_clk.prepare_enable()?;
+
+ let mali_regulator = Regulator::<regulator::Enabled>::get(pdev.as_ref(), c"mali")?;
+ let sram_regulator = Regulator::<regulator::Enabled>::get(pdev.as_ref(), c"sram")?;
+
+ let request = pdev.io_request_by_index(0).ok_or(ENODEV)?;
+
+ let iomem = Arc::new(request.iomap_sized::<SZ_2M>()?, GFP_KERNEL)?;
+
+ issue_soft_reset(pdev.as_ref(), &iomem)?;
+ gpu::l2_power_on(pdev.as_ref(), &iomem)?;
+
+ let gpu_info = GpuInfo::new(&iomem);
+ gpu_info.log(pdev.as_ref());
+
+ let pa_bits = MMU_FEATURES::from_raw(gpu_info.mmu_features)
+ .pa_bits()
+ .get();
+ // SAFETY: No concurrent DMA allocations or mappings can be made because
+ // the device is still being probed and therefore isn't being used by
+ // other threads of execution.
+ unsafe { pdev.dma_set_mask_and_coherent(DmaMask::try_new(pa_bits)?)? };
+
+ let unreg_dev = drm::UnregisteredDevice::<TyrDrmDriver>::new(pdev, Ok(()))?;
+
+ let mmu = Mmu::new(pdev.as_ref(), iomem.as_arc_borrow(), &gpu_info)?;
+
+ let firmware = Firmware::new(
+ pdev.as_ref(),
+ iomem.clone(),
+ &unreg_dev,
+ mmu.as_arc_borrow(),
+ &gpu_info,
+ )?;
+
+ firmware.boot()?;
+
+ Ok(try_pin_init!(TyrPlatformDriverData {
+ // SAFETY: `_reg` is stored in `TyrPlatformDriverData` and dropped when the
+ // driver is unbound; it is never forgotten.
+ _reg <- unsafe { drm::Registration::new(
+ pdev.as_ref(),
+ unreg_dev,
+ pin_init!(TyrDrmRegistrationData {
+ pdev,
+ fw: firmware,
+ clks <- new_mutex!(Clocks {
+ core: core_clk,
+ stacks: stacks_clk,
+ coregroup: coregroup_clk,
+ }),
+ regulators <- new_mutex!(Regulators {
+ _mali: mali_regulator,
+ _sram: sram_regulator,
+ }),
+ iomem,
+ gpu_info,
+ }),
+ 0,
+ )},
+ _: { dev_dbg!(pdev, "Tyr initialized correctly.") },
+ }))
+ })
}
}