From: "Onur Özkan" <work@onurozkan.dev>
To: linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org,
dri-devel@lists.freedesktop.org
Cc: dakr@kernel.org, aliceryhl@google.com,
daniel.almeida@collabora.com, airlied@gmail.com, simona@ffwll.ch,
ojeda@kernel.org, boqun@kernel.org, gary@garyguo.net,
bjorn3_gh@protonmail.com, lossin@kernel.org,
a.hindborg@kernel.org, tmgross@umich.edu,
"Onur Özkan" <work@onurozkan.dev>
Subject: [PATCH 1/2] drm/tyr: move reset work to platform driver data
Date: Sun, 23 Aug 2026 13:50:07 +0300 [thread overview]
Message-ID: <20260823-tyr-gpu-unplug-b4-v1-1-e99c07d4c785@onurozkan.dev> (raw)
In-Reply-To: <20260823-tyr-gpu-unplug-b4-v1-0-e99c07d4c785@onurozkan.dev>
Move ResetHandle out of DRM registration data and store it as the first
field of platform driver data. This makes platform teardown drain queued
or running reset work before dropping the DRM registration and the
resources it owns.
Signed-off-by: Onur Özkan <work@onurozkan.dev>
---
drivers/gpu/drm/tyr/driver.rs | 172 ++++++++++++++++++++++--------------------
1 file changed, 89 insertions(+), 83 deletions(-)
diff --git a/drivers/gpu/drm/tyr/driver.rs b/drivers/gpu/drm/tyr/driver.rs
index c326192f8af2..92ed0de0b4e4 100644
--- a/drivers/gpu/drm/tyr/driver.rs
+++ b/drivers/gpu/drm/tyr/driver.rs
@@ -51,8 +51,13 @@
#[pin_data(PinnedDrop)]
pub(crate) struct TyrPlatformDriverData<'bound> {
- _device: ARef<TyrDrmDevice>,
+ // `ResetHandle::drop()` drains queued/running works and this must happen
+ // before clocks/regulators are dropped. So keep this field before them to
+ // ensure the correct drop order.
+ #[pin]
+ _reset: reset::ResetHandle<'bound>,
_reg: drm::Registration<'bound, TyrDrmDriver>,
+ _device: ARef<TyrDrmDevice>,
}
/// Resources kept alive by the DRM registration.
@@ -61,12 +66,6 @@ pub(crate) struct TyrDrmRegistrationData<'bound> {
/// Parent platform device.
pub(crate) pdev: &'bound platform::Device<Bound>,
- // `ResetHandle::drop()` drains queued/running works and this must happen
- // before clocks/regulators are dropped. So keep this field before them to
- // ensure the correct drop order.
- #[pin]
- pub(crate) reset: reset::ResetHandle<'bound>,
-
/// Firmware sections.
pub(crate) fw: Arc<Firmware<'bound>>,
@@ -101,82 +100,89 @@ fn probe<'bound>(
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 hw = Arc::pin_init(
- reset::HwGate::new(request.iomap_sized::<SZ_2M>()?),
- GFP_KERNEL,
- )?;
-
- reset::run_reset(pdev.as_ref(), &hw)?;
-
- let gpu_info = {
- let hw_guard = hw.access();
- let gpu_info = GpuInfo::new(hw_guard.iomem());
- gpu_info.log(pdev.as_ref());
- gpu_info
- };
-
- 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(hw.clone(), &gpu_info)?;
-
- let firmware = Firmware::new(pdev, hw.clone(), &unreg_dev, mmu.as_arc_borrow(), &gpu_info)?;
-
- firmware.boot()?;
- firmware.enable_global_interface(&gpu_info, &core_clk)?;
-
- let reg_data = try_pin_init!(TyrDrmRegistrationData {
- pdev,
- // SAFETY: `ResetHandle` is stored in registration data created with `new_with_lt`
- // and is dropped before the borrowed device and MMIO references expire.
- reset <- unsafe { reset::ResetHandle::new(pdev, hw.clone())? },
- 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,
- }),
- gpu_info,
- });
-
- // SAFETY: `reg` is stored in the platform driver data and is not leaked or
- // forgotten, so it is dropped before the `'bound` registration data can become
- // invalid.
- let reg = unsafe { drm::Registration::new_with_lt(pdev.as_ref(), unreg_dev, reg_data, 0)? };
-
- let driver = TyrPlatformDriverData {
- _device: reg.device().into(),
- _reg: reg,
- };
-
- // We need this to be dev_info!() because dev_dbg!() does not work at
- // all in Rust for now, and we need to see whether probe succeeded.
- dev_info!(pdev, "Tyr initialized correctly.\n");
- 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 hw = Arc::pin_init(
+ reset::HwGate::new(request.iomap_sized::<SZ_2M>()?),
+ GFP_KERNEL,
+ )?;
+
+ reset::run_reset(pdev.as_ref(), &hw)?;
+
+ let gpu_info = {
+ let hw_guard = hw.access();
+ let gpu_info = GpuInfo::new(hw_guard.iomem());
+ gpu_info.log(pdev.as_ref());
+ gpu_info
+ };
+
+ 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(hw.clone(), &gpu_info)?;
+
+ let firmware =
+ Firmware::new(pdev, hw.clone(), &unreg_dev, mmu.as_arc_borrow(), &gpu_info)?;
+
+ firmware.boot()?;
+ firmware.enable_global_interface(&gpu_info, &core_clk)?;
+
+ let reg_data = try_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,
+ }),
+ gpu_info,
+ });
+
+ // SAFETY: `reg` is stored in the platform driver data and is not leaked or
+ // forgotten, so it is dropped before the `'bound` registration data can become
+ // invalid.
+ let reg =
+ unsafe { drm::Registration::new_with_lt(pdev.as_ref(), unreg_dev, reg_data, 0)? };
+ let device = reg.device().into();
+
+ let driver = try_pin_init!(TyrPlatformDriverData {
+ // SAFETY: `ResetHandle` is stored in platform driver data and is
+ // dropped before the borrowed device and MMIO references expire.
+ _reset <- unsafe { reset::ResetHandle::new(pdev, hw)? },
+ _reg: reg,
+ _device: device,
+ _: {
+ // We need this to be dev_info!() because dev_dbg!() does not work at
+ // all in Rust for now, and we need to see whether probe succeeded.
+ dev_info!(pdev, "Tyr initialized correctly.\n");
+ },
+ });
+
+ Ok(driver)
+ })
}
}
--
2.51.2
next prev parent reply other threads:[~2026-08-23 10:51 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-23 10:50 [PATCH 0/2] drm/tyr: unplug the GPU when reset fails Onur Özkan
2026-08-23 10:50 ` Onur Özkan [this message]
2026-08-24 17:27 ` [PATCH 1/2] drm/tyr: move reset work to platform driver data Daniel Almeida
2026-08-23 10:50 ` [PATCH 2/2] drm/tyr: unplug the GPU when reset fails Onur Özkan
2026-08-26 14:05 ` Daniel Almeida
2026-09-12 8:03 ` Onur Özkan
2026-10-21 9:38 ` Alice Ryhl
2026-10-25 11:23 ` Onur Özkan
2026-10-25 12:05 ` Alice Ryhl
2026-10-26 4:55 ` Onur Özkan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260823-tyr-gpu-unplug-b4-v1-1-e99c07d4c785@onurozkan.dev \
--to=work@onurozkan.dev \
--cc=a.hindborg@kernel.org \
--cc=airlied@gmail.com \
--cc=aliceryhl@google.com \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun@kernel.org \
--cc=dakr@kernel.org \
--cc=daniel.almeida@collabora.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=gary@garyguo.net \
--cc=linux-kernel@vger.kernel.org \
--cc=lossin@kernel.org \
--cc=ojeda@kernel.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=simona@ffwll.ch \
--cc=tmgross@umich.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®