All of lore.kernel.org
 help / color / mirror / Atom feed
From: Danilo Krummrich <dakr@kernel.org>
To: gregkh@linuxfoundation.org, rafael@kernel.org,
	acourbot@nvidia.com, aliceryhl@google.com,
	david.m.ertman@intel.com, ira.weiny@intel.com, leon@kernel.org,
	viresh.kumar@linaro.org, m.wilczynski@samsung.com,
	ukleinek@kernel.org, bhelgaas@google.com, kwilczynski@kernel.org,
	abdiel.janulgue@gmail.com, robin.murphy@arm.com,
	markus.probst@posteo.de, ojeda@kernel.org, boqun@kernel.org,
	gary@garyguo.net, bjorn3_gh@protonmail.com, lossin@kernel.org,
	a.hindborg@kernel.org, tmgross@umich.edu, igor.korotin@linux.dev,
	daniel.almeida@collabora.com
Cc: driver-core@lists.linux.dev, linux-kernel@vger.kernel.org,
	nova-gpu@lists.linux.dev, dri-devel@lists.freedesktop.org,
	linux-pm@vger.kernel.org, linux-pwm@vger.kernel.org,
	linux-pci@vger.kernel.org, rust-for-linux@vger.kernel.org,
	Danilo Krummrich <dakr@kernel.org>
Subject: [PATCH 3/3] rust: io: mem: return DevresLt from IoMem/ExclusiveIoMem::into_devres()
Date: Wed,  6 May 2026 23:58:35 +0200	[thread overview]
Message-ID: <20260506220012.855173-4-dakr@kernel.org> (raw)
In-Reply-To: <20260506220012.855173-1-dakr@kernel.org>

Implement ForLt for IoMem<'static, SIZE> and ExclusiveIoMem<'static,
SIZE> so that DevresLt can shorten the stored 'static lifetime back to
the caller's borrow lifetime via ForLt::cast_ref.

Change into_devres() to return DevresLt instead of Devres; add
DevresIoMem<SIZE> and DevresExclusiveIoMem<SIZE> type aliases.

Signed-off-by: Danilo Krummrich <dakr@kernel.org>
---
 drivers/pwm/pwm_th1520.rs |  5 ++--
 rust/kernel/io/mem.rs     | 55 ++++++++++++++++++++++++++++-----------
 2 files changed, 42 insertions(+), 18 deletions(-)

diff --git a/drivers/pwm/pwm_th1520.rs b/drivers/pwm/pwm_th1520.rs
index 3deb39d8e0fc..6b094be35310 100644
--- a/drivers/pwm/pwm_th1520.rs
+++ b/drivers/pwm/pwm_th1520.rs
@@ -24,9 +24,8 @@
 use kernel::{
     clk::Clk,
     device::{Bound, Core, Device},
-    devres,
     io::{
-        mem::IoMem,
+        mem::DevresIoMem,
         Io, //
     },
     of, platform,
@@ -92,7 +91,7 @@ struct Th1520WfHw {
 #[pin_data(PinnedDrop)]
 struct Th1520PwmDriverData {
     #[pin]
-    iomem: devres::Devres<IoMem<'static, TH1520_PWM_REG_SIZE>>,
+    iomem: DevresIoMem<TH1520_PWM_REG_SIZE>,
     clk: Clk,
 }
 
diff --git a/rust/kernel/io/mem.rs b/rust/kernel/io/mem.rs
index a4cb12ee70d3..928aa7742490 100644
--- a/rust/kernel/io/mem.rs
+++ b/rust/kernel/io/mem.rs
@@ -9,7 +9,7 @@
         Bound,
         Device, //
     },
-    devres::Devres,
+    devres::DevresLt,
     io::{
         self,
         resource::{
@@ -20,6 +20,7 @@
         MmioRaw, //
     },
     prelude::*,
+    types::ForLt, //
 };
 
 /// An IO request for a specific device and resource.
@@ -170,6 +171,18 @@ pub struct ExclusiveIoMem<'bound, const SIZE: usize> {
     _region: Region,
 }
 
+// SAFETY: `ExclusiveIoMem<'bound, SIZE>` is covariant over `'bound` --
+// it holds an `IoMem<'bound, SIZE>`, which holds
+// `&'bound Device<Bound>`, which is covariant.
+unsafe impl<const SIZE: usize> ForLt for ExclusiveIoMem<'static, SIZE> {
+    type Of<'bound> = ExclusiveIoMem<'bound, SIZE>;
+}
+
+/// A device-managed exclusive I/O memory region.
+///
+/// See [`ExclusiveIoMem::into_devres`].
+pub type DevresExclusiveIoMem<const SIZE: usize> = DevresLt<ExclusiveIoMem<'static, SIZE>>;
+
 impl<'bound, const SIZE: usize> ExclusiveIoMem<'bound, SIZE> {
     /// Creates a new `ExclusiveIoMem` instance.
     fn ioremap(dev: &'bound Device<Bound>, resource: &Resource) -> Result<Self> {
@@ -196,15 +209,16 @@ fn ioremap(dev: &'bound Device<Bound>, resource: &Resource) -> Result<Self> {
 
     /// Consume the `ExclusiveIoMem` and register it as a device-managed resource.
     ///
-    /// The returned `Devres<ExclusiveIoMem<'static, SIZE>>` can outlive the original lifetime
-    /// `'bound`. Access to the I/O memory is revoked when the device is unbound.
-    pub fn into_devres(self) -> Result<Devres<ExclusiveIoMem<'static, SIZE>>> {
-        // SAFETY: Casting to `'static` is sound because `Devres` guarantees the
+    /// Access methods on the returned [`DevresLt`] shorten the inner lifetime via
+    /// [`ForLt::cast_ref`], so the transmuted `'static` is never exposed to callers.
+    pub fn into_devres(self) -> Result<DevresLt<ExclusiveIoMem<'static, SIZE>>> {
+        // SAFETY: Casting to `'static` is sound because `DevresLt` guarantees the
         // `ExclusiveIoMem` does not actually outlive the device -- access is revoked and the
-        // resource is released when the device is unbound.
+        // resource is released when the device is unbound. The `ForLt` encoding ensures
+        // `access()` shortens the lifetime back to the caller's borrow.
         let iomem: ExclusiveIoMem<'static, SIZE> = unsafe { core::mem::transmute(self) };
         let dev = iomem.iomem.dev;
-        Devres::new(dev, iomem)
+        DevresLt::new(dev, iomem)
     }
 }
 
@@ -230,6 +244,17 @@ pub struct IoMem<'bound, const SIZE: usize = 0> {
     io: MmioRaw<SIZE>,
 }
 
+// SAFETY: `IoMem<'bound, SIZE>` is covariant over `'bound` -- it holds
+// `&'bound Device<Bound>`, which is covariant.
+unsafe impl<const SIZE: usize> ForLt for IoMem<'static, SIZE> {
+    type Of<'bound> = IoMem<'bound, SIZE>;
+}
+
+/// A device-managed I/O memory region.
+///
+/// See [`IoMem::into_devres`].
+pub type DevresIoMem<const SIZE: usize> = DevresLt<IoMem<'static, SIZE>>;
+
 impl<'bound, const SIZE: usize> IoMem<'bound, SIZE> {
     fn ioremap(dev: &'bound Device<Bound>, resource: &Resource) -> Result<Self> {
         // Note: Some ioremap() implementations use types that depend on the CPU
@@ -269,16 +294,16 @@ fn ioremap(dev: &'bound Device<Bound>, resource: &Resource) -> Result<Self> {
 
     /// Consume the `IoMem` and register it as a device-managed resource.
     ///
-    /// The returned `Devres<IoMem<'static, SIZE>>` can outlive the original
-    /// lifetime `'bound`. Access to the I/O memory is revoked when the device
-    /// is unbound.
-    pub fn into_devres(self) -> Result<Devres<IoMem<'static, SIZE>>> {
-        // SAFETY: Casting to `'static` is sound because `Devres` guarantees the `IoMem` does not
-        // actually outlive the device -- access is revoked and the resource is released when the
-        // device is unbound.
+    /// Access methods on the returned [`DevresLt`] shorten the inner lifetime via
+    /// [`ForLt::cast_ref`], so the transmuted `'static` is never exposed to callers.
+    pub fn into_devres(self) -> Result<DevresLt<IoMem<'static, SIZE>>> {
+        // SAFETY: Casting to `'static` is sound because `DevresLt` guarantees the `IoMem` does
+        // not actually outlive the device -- access is revoked and the resource is released when
+        // the device is unbound. The `ForLt` encoding ensures `access()` shortens the lifetime
+        // back to the caller's borrow.
         let iomem: IoMem<'static, SIZE> = unsafe { core::mem::transmute(self) };
         let dev = iomem.dev;
-        Devres::new(dev, iomem)
+        DevresLt::new(dev, iomem)
     }
 }
 
-- 
2.54.0


      parent reply	other threads:[~2026-05-06 22:00 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-06 21:58 [PATCH 0/3] rust: devres: add DevresLt for ForLt-aware device resource access Danilo Krummrich
2026-05-06 21:58 ` [PATCH 1/3] " Danilo Krummrich
2026-05-06 21:58 ` [PATCH 2/3] rust: pci: return DevresLt from Bar::into_devres() Danilo Krummrich
2026-05-06 21:58 ` Danilo Krummrich [this message]

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=20260506220012.855173-4-dakr@kernel.org \
    --to=dakr@kernel.org \
    --cc=a.hindborg@kernel.org \
    --cc=abdiel.janulgue@gmail.com \
    --cc=acourbot@nvidia.com \
    --cc=aliceryhl@google.com \
    --cc=bhelgaas@google.com \
    --cc=bjorn3_gh@protonmail.com \
    --cc=boqun@kernel.org \
    --cc=daniel.almeida@collabora.com \
    --cc=david.m.ertman@intel.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=driver-core@lists.linux.dev \
    --cc=gary@garyguo.net \
    --cc=gregkh@linuxfoundation.org \
    --cc=igor.korotin@linux.dev \
    --cc=ira.weiny@intel.com \
    --cc=kwilczynski@kernel.org \
    --cc=leon@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=linux-pwm@vger.kernel.org \
    --cc=lossin@kernel.org \
    --cc=m.wilczynski@samsung.com \
    --cc=markus.probst@posteo.de \
    --cc=nova-gpu@lists.linux.dev \
    --cc=ojeda@kernel.org \
    --cc=rafael@kernel.org \
    --cc=robin.murphy@arm.com \
    --cc=rust-for-linux@vger.kernel.org \
    --cc=tmgross@umich.edu \
    --cc=ukleinek@kernel.org \
    --cc=viresh.kumar@linaro.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.