Messages in this thread Patch in this message |  | | From | Danilo Krummrich <> | | Subject | [PATCH 05/24] rust: driver: make Adapter trait lifetime-parameterized | | Date | Tue, 28 Apr 2026 00:11:03 +0200 |
| |
Parameterize the Adapter trait with a lifetime, changing the id_info(), of_id_info() and acpi_id_info() methods to take &'a Device<Bound> and return &'a Self::IdInfo instead of &'static.
This is needed for the ForLt conversion of bus driver traits. Once Driver becomes lifetime-parameterized, its IdInfo associated type may depend on the lifetime parameter. With Adapter<'a>, the impl can set IdInfo = <F::Of<'a> as Driver<'a>>::IdInfo and the lifetime flows through naturally, avoiding the need for transmute.
For the current non-lifetime-parameterized Driver trait, this is a no-op type relaxation; IdInfo is 'static and &'static coerces to &'a.
Signed-off-by: Danilo Krummrich <dakr@kernel.org> --- rust/kernel/driver.rs | 16 ++++++++++------ rust/kernel/i2c.rs | 10 +++++----- rust/kernel/platform.rs | 4 ++-- 3 files changed, 17 insertions(+), 13 deletions(-)
diff --git a/rust/kernel/driver.rs b/rust/kernel/driver.rs index 29a67b12c872..91490040d77e 100644 --- a/rust/kernel/driver.rs +++ b/rust/kernel/driver.rs @@ -96,7 +96,11 @@ use crate::{ acpi, - device, + device::{ + self, + Bound, + Device, // + }, of, prelude::*, types::{ @@ -192,7 +196,7 @@ extern "C" fn post_unbind_callback(dev: *mut bindings::device) { // a `struct device`. // // INVARIANT: `dev` is valid for the duration of the `post_unbind_callback()`. - let dev = unsafe { &*dev.cast::<device::Device<device::CoreInternal>>() }; + let dev = unsafe { &*dev.cast::<Device<device::CoreInternal>>() }; // `remove()` has been completed at this point; devres resources are still valid and will // be released after the driver's bus device private data is dropped. @@ -289,7 +293,7 @@ fn init( /// of a device and a driver. /// /// It provides bus independent functions for device / driver interactions. -pub trait Adapter { +pub trait Adapter<'a> { /// The type holding driver private data about each device id supported by the driver. type IdInfo: 'static; @@ -299,7 +303,7 @@ pub trait Adapter { /// Returns the driver's private data from the matching entry in the [`acpi::IdTable`], if any. /// /// If this returns `None`, it means there is no match with an entry in the [`acpi::IdTable`]. - fn acpi_id_info(dev: &device::Device) -> Option<&'static Self::IdInfo> { + fn acpi_id_info(dev: &'a Device<Bound>) -> Option<&'a Self::IdInfo> { #[cfg(not(CONFIG_ACPI))] { let _ = dev; @@ -333,7 +337,7 @@ fn acpi_id_info(dev: &device::Device) -> Option<&'static Self::IdInfo> { /// Returns the driver's private data from the matching entry in the [`of::IdTable`], if any. /// /// If this returns `None`, it means there is no match with an entry in the [`of::IdTable`]. - fn of_id_info(dev: &device::Device) -> Option<&'static Self::IdInfo> { + fn of_id_info(dev: &'a Device<Bound>) -> Option<&'a Self::IdInfo> { #[cfg(not(CONFIG_OF))] { let _ = dev; @@ -369,7 +373,7 @@ fn of_id_info(dev: &device::Device) -> Option<&'static Self::IdInfo> { /// /// If this returns `None`, it means that there is no match in any of the ID tables directly /// associated with a [`device::Device`]. - fn id_info(dev: &device::Device) -> Option<&'static Self::IdInfo> { + fn id_info(dev: &'a Device<Bound>) -> Option<&'a Self::IdInfo> { let id = Self::acpi_id_info(dev); if id.is_some() { return id; diff --git a/rust/kernel/i2c.rs b/rust/kernel/i2c.rs index cde3dd7a6cc7..08d310aa9d6b 100644 --- a/rust/kernel/i2c.rs +++ b/rust/kernel/i2c.rs @@ -162,8 +162,8 @@ extern "C" fn probe_callback(idev: *mut bindings::i2c_client) -> kernel::ffi::c_ // INVARIANT: `idev` is valid for the duration of `probe_callback()`. let idev = unsafe { &*idev.cast::<I2cClient<device::CoreInternal>>() }; - let info = - Self::i2c_id_info(idev).or_else(|| <Self as driver::Adapter>::id_info(idev.as_ref())); + let info = Self::i2c_id_info(idev) + .or_else(|| <Self as driver::Adapter<'_>>::id_info(idev.as_ref())); from_result(|| { let data = T::probe(idev, info); @@ -198,14 +198,14 @@ extern "C" fn shutdown_callback(idev: *mut bindings::i2c_client) { } /// The [`i2c::IdTable`] of the corresponding driver. - fn i2c_id_table() -> Option<IdTable<<Self as driver::Adapter>::IdInfo>> { + fn i2c_id_table() -> Option<IdTable<<Self as driver::Adapter<'static>>::IdInfo>> { T::I2C_ID_TABLE } /// Returns the driver's private data from the matching entry in the [`i2c::IdTable`], if any. /// /// If this returns `None`, it means there is no match with an entry in the [`i2c::IdTable`]. - fn i2c_id_info(dev: &I2cClient) -> Option<&'static <Self as driver::Adapter>::IdInfo> { + fn i2c_id_info(dev: &I2cClient) -> Option<&'static <Self as driver::Adapter<'static>>::IdInfo> { let table = Self::i2c_id_table()?; // SAFETY: @@ -225,7 +225,7 @@ fn i2c_id_info(dev: &I2cClient) -> Option<&'static <Self as driver::Adapter>::Id } } -impl<T: Driver + 'static> driver::Adapter for Adapter<T> { +impl<'a, T: Driver + 'static> driver::Adapter<'a> for Adapter<T> { type IdInfo = T::IdInfo; fn of_id_table() -> Option<of::IdTable<Self::IdInfo>> { diff --git a/rust/kernel/platform.rs b/rust/kernel/platform.rs index 7ff69e3eea90..1585b6a1ac45 100644 --- a/rust/kernel/platform.rs +++ b/rust/kernel/platform.rs @@ -101,7 +101,7 @@ extern "C" fn probe_callback(pdev: *mut bindings::platform_device) -> kernel::ff // // INVARIANT: `pdev` is valid for the duration of `probe_callback()`. let pdev = unsafe { &*pdev.cast::<Device<device::CoreInternal>>() }; - let info = <Self as driver::Adapter>::id_info(pdev.as_ref()); + let info = <Self as driver::Adapter<'_>>::id_info(pdev.as_ref()); from_result(|| { let data = T::probe(pdev, info); @@ -127,7 +127,7 @@ extern "C" fn remove_callback(pdev: *mut bindings::platform_device) { } } -impl<T: Driver + 'static> driver::Adapter for Adapter<T> { +impl<'a, T: Driver + 'static> driver::Adapter<'a> for Adapter<T> { type IdInfo = T::IdInfo; fn of_id_table() -> Option<of::IdTable<Self::IdInfo>> { -- 2.54.0
|  |