mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
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

  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®