rust/kernel/device.rs | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+)
Implement generic accessors for the platform data of a device.
Platform data is typically set by platform code when creating the device
and points to platform-specific data structures. The accessor provides
type-safe access to this data without requiring unsafe code at the call
site.
The accessor is implemented for Device<Bound>, allowing drivers to access
platform data during probe() and other device lifecycle callbacks. Unlike
drvdata, platform data is managed by platform code and has a lifetime
tied to the device itself.
Signed-off-by: pengfuyuan <pengfuyuan@kylinos.cn>
---
rust/kernel/device.rs | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/rust/kernel/device.rs b/rust/kernel/device.rs
index c79be2e2bfe3..e16f8eaa52e0 100644
--- a/rust/kernel/device.rs
+++ b/rust/kernel/device.rs
@@ -325,6 +325,31 @@ pub fn drvdata<T: 'static>(&self) -> Result<Pin<&T>> {
// - We've just checked that the type of the driver's private data is in fact `T`.
Ok(unsafe { self.drvdata_unchecked() })
}
+
+ /// Access the platform data for this device.
+ ///
+ /// The lifetime of the platform data is tied to the device's lifetime.
+ /// Returns a reference to the platform data of type `T`, or [`ENOENT`] if no platform data
+ /// is set.
+ ///
+ /// # Type Safety
+ ///
+ /// This function does not perform runtime type checking. The caller must ensure that the
+ /// platform data structure actually matches the type `T` for the specific platform device.
+ /// Incorrect type usage will result in undefined behavior.
+ pub fn platdata<T>(&self) -> Result<&T> {
+ // SAFETY: By the type invariants, `self.as_raw()` is a valid pointer to a `struct device`.
+ let ptr = unsafe { (*self.as_raw()).platform_data };
+
+ if ptr.is_null() {
+ return Err(ENOENT);
+ }
+
+ // SAFETY:
+ // - `ptr` is not null, so it points to valid memory.
+ // - The caller must ensure that the platform data structure matches type `T`.
+ Ok(unsafe { &*ptr.cast::<T>() })
+ }
}
impl<Ctx: DeviceContext> Device<Ctx> {
--
2.25.1
On Thu Jan 8, 2026 at 9:55 AM CET, pengfuyuan wrote:
> Implement generic accessors for the platform data of a device.
As Greg already mentioned, please provide provide a user for the API. Even an
RFC is fine for me as long as it is not too far from an upstreamable state and
the corresponding subsystem maintainers show willingness to take the code.
> Platform data is typically set by platform code when creating the device
> and points to platform-specific data structures. The accessor provides
> type-safe access to this data without requiring unsafe code at the call
> site.
That seems wrong; at least with the current implementation this method is unsafe
for two reasons:
(1) The caller has to assert that T is in fact the type of the data set by the
platform code.
(2) T is (most likely) a C type, which does not guarantee that it is valid to
create a reference, i.e. &T, of. For instance, it might not be properly
initialized.
I think (1) is not fixable (at least as long as the platform code is in C), so
it unfortunately has to be unsafe.
As for (2), I'd just return an &Opaque<T> instead and then have an FFI wrapper
in the driver.
> The accessor is implemented for Device<Bound>, allowing drivers to access
> platform data during probe() and other device lifecycle callbacks. Unlike
> drvdata, platform data is managed by platform code and has a lifetime
> tied to the device itself.
I don't think this accessor has to be on Device<Bound>, as you say platform data
is always valid.
- Danilo
This is version 2 of the platform data accessor patch series. Changes since v1: - Changed return type from &T to &Opaque<T> as suggested by Danilo - Marked the function as unsafe due to type mismatch risks (no runtime type checking) - Made the API available for all device states, not just Device<Bound> - Fixed documentation to use the standard "Safety" section - Rewrote safety comments to explain why the conditions are upheld Other notes: 1. AI usage disclosure: Yes, I used AI tools to assist with writing documentation comments and analyzing existing Rust for Linux code patterns. The code implementation itself was written by me, but I should have disclosed the AI assistance. I will ensure proper disclosure in future submissions. Thanks to Miguel Ojeda and Danilo for their detailed feedback. Regarding the user/driver: - The driver we're developing (a simplefb-like display driver) will indeed use this API. Given the API needs redesign based on your feedback, I've redesigned and resubmitted the platform data accessor API. - However, since the driver is still under active development, it's not yet ready for submission. I understand Linux kernel development requires no speculative APIs (APIs must have actual users). I hope you could review this implementation for feasibility (without merging it for now). If acceptable, I'll continue driver development based on this API and submit both together once the driver is complete. Thank you again for your detailed review. pengfuyuan (1): rust: device: add platdata accessors rust/kernel/device.rs | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) -- 2.25.1
Implement generic accessors for the platform data of a device.
Platform data is typically set by platform code when creating the device (e.g.
via `platform_device_add_data()`). Drivers may use it to obtain per-device,
platform-provided configuration.
The accessor is `unsafe` because the caller must ensure that the chosen `T`
matches the actual object referenced by `platform_data`.
Platform data is generally a C type, so the method returns `&Opaque<T>` to
avoid creating a Rust reference to potentially uninitialised or otherwise
invalid C data. Drivers can then perform the FFI dereference behind an explicit
`unsafe` block.
The method is implemented for `Device<Ctx>` so it is available in all device
states. If no platform data is present, `-ENOENT` is returned.
Signed-off-by: pengfuyuan <pengfuyuan@kylinos.cn>
---
rust/kernel/device.rs | 31 +++++++++++++++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/rust/kernel/device.rs b/rust/kernel/device.rs
index c79be2e2bfe3..90ccc433dfe7 100644
--- a/rust/kernel/device.rs
+++ b/rust/kernel/device.rs
@@ -483,6 +483,37 @@ pub fn fwnode(&self) -> Option<&property::FwNode> {
// defined as a `#[repr(transparent)]` wrapper around `fwnode_handle`.
Some(unsafe { &*fwnode_handle.cast() })
}
+
+ /// Access the platform data for this device.
+ ///
+ /// Platform data is typically set by platform code when creating the device and is expected
+ /// to remain valid while the device is alive.
+ ///
+ /// Returns a reference to the opaque platform data, or [`ENOENT`] if no platform data
+ /// is set.
+ ///
+ /// # Safety
+ ///
+ /// Callers must ensure that:
+ /// - If platform data is set (i.e., `platform_data` is not null), the pointer points to valid,
+ /// properly aligned storage for `T` and remains valid for the lifetime of the returned
+ /// reference.
+ /// - The type `T` matches the type of the platform data structure set by platform code.
+ pub unsafe fn platdata<T>(&self) -> Result<&Opaque<T>> {
+ // SAFETY: By the type invariants, `self.as_raw()` is a valid pointer to a `struct device`.
+ let ptr = unsafe { (*self.as_raw()).platform_data };
+
+ if ptr.is_null() {
+ return Err(ENOENT);
+ }
+
+ // SAFETY:
+ // - `ptr` is not null (checked above).
+ // - By the safety requirements of this function, `ptr` points to valid, properly aligned
+ // storage for `T` and remains valid for the lifetime of the returned reference.
+ // - `Opaque<T>` allows any bit pattern, so we can safely create a reference to it.
+ Ok(unsafe { &*ptr.cast::<Opaque<T>>() })
+ }
}
// SAFETY: `Device` is a transparent wrapper of a type that doesn't depend on `Device`'s generic
--
2.25.1
On Fri, Jan 09, 2026 at 04:05:28PM +0800, pengfuyuan wrote:
> Implement generic accessors for the platform data of a device.
There is only one "accessor" being added here.
> Platform data is typically set by platform code when creating the device (e.g.
> via `platform_device_add_data()`). Drivers may use it to obtain per-device,
> platform-provided configuration.
No rust binding to set this? Who would be setting this data but not
reading it? Or can you already call platform_device_add_data() from a
rust driver?
> The accessor is `unsafe` because the caller must ensure that the chosen `T`
> matches the actual object referenced by `platform_data`.
>
> Platform data is generally a C type, so the method returns `&Opaque<T>` to
> avoid creating a Rust reference to potentially uninitialised or otherwise
> invalid C data. Drivers can then perform the FFI dereference behind an explicit
> `unsafe` block.
>
> The method is implemented for `Device<Ctx>` so it is available in all device
> states. If no platform data is present, `-ENOENT` is returned.
>
> Signed-off-by: pengfuyuan <pengfuyuan@kylinos.cn>
> ---
> rust/kernel/device.rs | 31 +++++++++++++++++++++++++++++++
> 1 file changed, 31 insertions(+)
>
> diff --git a/rust/kernel/device.rs b/rust/kernel/device.rs
> index c79be2e2bfe3..90ccc433dfe7 100644
> --- a/rust/kernel/device.rs
> +++ b/rust/kernel/device.rs
> @@ -483,6 +483,37 @@ pub fn fwnode(&self) -> Option<&property::FwNode> {
> // defined as a `#[repr(transparent)]` wrapper around `fwnode_handle`.
> Some(unsafe { &*fwnode_handle.cast() })
> }
> +
> + /// Access the platform data for this device.
> + ///
> + /// Platform data is typically set by platform code when creating the device and is expected
> + /// to remain valid while the device is alive.
> + ///
> + /// Returns a reference to the opaque platform data, or [`ENOENT`] if no platform data
> + /// is set.
> + ///
> + /// # Safety
> + ///
> + /// Callers must ensure that:
> + /// - If platform data is set (i.e., `platform_data` is not null), the pointer points to valid,
> + /// properly aligned storage for `T` and remains valid for the lifetime of the returned
> + /// reference.
> + /// - The type `T` matches the type of the platform data structure set by platform code.
> + pub unsafe fn platdata<T>(&self) -> Result<&Opaque<T>> {
> + // SAFETY: By the type invariants, `self.as_raw()` is a valid pointer to a `struct device`.
> + let ptr = unsafe { (*self.as_raw()).platform_data };
Why isn't dev_get_platdata() being used here?
Also, we still need to see a user of this before we can properly review
it.
thanks,
greg k-h
On Thu, Jan 8, 2026 at 9:56 AM pengfuyuan <pengfuyuan@kylinos.cn> wrote:
>
> + /// # Type Safety
> + ///
> + /// This function does not perform runtime type checking. The caller must ensure that the
> + /// platform data structure actually matches the type `T` for the specific platform device.
> + /// Incorrect type usage will result in undefined behavior.
I didn't check the code, but I noticed this header -- why "Type Safety"?
The standard header we use for this is "Safety", i.e. we don't specify
"kinds of safety" (as soon as you break one "kind" you could in
principle break everything, so it is either unsafe or not).
Also, we generally try to be concise in these, e.g. the
precondition/paragraph could perhaps be reworded like:
/// The type `T` must match the type of ...
It is always the case that there is UB if the preconditions of a
"Safety" section are not upheld, so there is no need to remark that
either.
> + // - The caller must ensure that the platform data structure matches type `T`.
I would expect this wording in a "Safety" section, not in a `//
SAFETY:` comment.
i.e. the safety precondition is there, but in this comment you need to
justify why the caller has ensured it, not that they "must" do it.
Does that make sense?
Instead, you can say e.g. "The caller ensures" or similar (we use
several ways of saying it, which eventually we could normalize). You
may even see sometimes an explicit "// SAFETY: By the safety
precondition, ...", but for this kind "The caller promises" or similar
is already understood like that.
Thanks!
Cheers,
Miguel
On Thu, Jan 8, 2026 at 11:46 AM Miguel Ojeda <miguel.ojeda.sandonis@gmail.com> wrote: > > Thanks! By the way, was this LLM-generated? I am asking since tools usage is supposed to be disclosed (the kernel will probably codify this soon explicitly), and given the comments and documentation here sounded to me a bit like that, and since someone from your email domain also said recently that they used AI. Thanks! Cheers, Miguel
On Thu, Jan 08, 2026 at 04:55:45PM +0800, pengfuyuan wrote: > Implement generic accessors for the platform data of a device. > > Platform data is typically set by platform code when creating the device > and points to platform-specific data structures. The accessor provides > type-safe access to this data without requiring unsafe code at the call > site. > > The accessor is implemented for Device<Bound>, allowing drivers to access > platform data during probe() and other device lifecycle callbacks. Unlike > drvdata, platform data is managed by platform code and has a lifetime > tied to the device itself. > > Signed-off-by: pengfuyuan <pengfuyuan@kylinos.cn> Again, use your name, not your email alias, to sign off on something. thanks, greg k-h
© 2016 - 2026 Red Hat, Inc.