summaryrefslogtreecommitdiff
path: root/rust/kernel
diff options
context:
space:
mode:
authorDaniel Almeida <daniel.almeida@collabora.com>2025-07-17 12:55:24 -0300
committerDanilo Krummrich <dakr@kernel.org>2025-07-20 19:43:14 +0200
commitbc4f9045a59963abb142f6a648195ccd73ec39dd (patch)
tree9738ef743455b4f0933d53b17b71fbc69e617855 /rust/kernel
parent1d0d4b28513b5e0e9e87e09c8da289e1b8d88f84 (diff)
rust: platform: add resource accessors
The previous patches have added the abstractions for Resources and the ability to map them and therefore read and write the underlying memory . The only thing missing to make this accessible for platform devices is to provide accessors that return instances of IoRequest<'a>. These ensure that the resource are valid only for the lifetime of the platform device, and that the platform device is in the Bound state. Therefore, add these accessors. Also make it possible to retrieve resources from platform devices in Rust using either a name or an index. Acked-by: Miguel Ojeda <ojeda@kernel.org> Signed-off-by: Daniel Almeida <daniel.almeida@collabora.com> Link: https://lore.kernel.org/r/20250717-topics-tyr-platform_iomem-v15-3-beca780b77e3@collabora.com [ Remove #[expect(dead_code)] from IoRequest::new() and move SAFETY comments right on top of unsafe blocks to avoid clippy warnings for some (older) clippy versions. - Danilo ] Signed-off-by: Danilo Krummrich <dakr@kernel.org>
Diffstat (limited to 'rust/kernel')
-rw-r--r--rust/kernel/io/mem.rs1
-rw-r--r--rust/kernel/platform.rs60
2 files changed, 59 insertions, 2 deletions
diff --git a/rust/kernel/io/mem.rs b/rust/kernel/io/mem.rs
index 8e4dfd79079e..50d4ec3eb623 100644
--- a/rust/kernel/io/mem.rs
+++ b/rust/kernel/io/mem.rs
@@ -28,7 +28,6 @@ impl<'a> IoRequest<'a> {
///
/// Callers must ensure that `resource` is valid for `device` during the
/// lifetime `'a`.
- #[expect(dead_code)]
pub(crate) unsafe fn new(device: &'a Device<Bound>, resource: &'a Resource) -> Self {
IoRequest { device, resource }
}
diff --git a/rust/kernel/platform.rs b/rust/kernel/platform.rs
index 3c0c507c2432..b4d3087aff52 100644
--- a/rust/kernel/platform.rs
+++ b/rust/kernel/platform.rs
@@ -5,8 +5,11 @@
//! C header: [`include/linux/platform_device.h`](srctree/include/linux/platform_device.h)
use crate::{
- acpi, bindings, container_of, device, driver,
+ acpi, bindings, container_of,
+ device::{self, Bound},
+ driver,
error::{from_result, to_result, Result},
+ io::{mem::IoRequest, Resource},
of,
prelude::*,
types::Opaque,
@@ -224,6 +227,61 @@ impl<Ctx: device::DeviceContext> Device<Ctx> {
fn as_raw(&self) -> *mut bindings::platform_device {
self.0.get()
}
+
+ /// Returns the resource at `index`, if any.
+ pub fn resource_by_index(&self, index: u32) -> Option<&Resource> {
+ // SAFETY: `self.as_raw()` returns a valid pointer to a `struct platform_device`.
+ let resource = unsafe {
+ bindings::platform_get_resource(self.as_raw(), bindings::IORESOURCE_MEM, index)
+ };
+
+ if resource.is_null() {
+ return None;
+ }
+
+ // SAFETY: `resource` is a valid pointer to a `struct resource` as
+ // returned by `platform_get_resource`.
+ Some(unsafe { Resource::from_raw(resource) })
+ }
+
+ /// Returns the resource with a given `name`, if any.
+ pub fn resource_by_name(&self, name: &CStr) -> Option<&Resource> {
+ // SAFETY: `self.as_raw()` returns a valid pointer to a `struct
+ // platform_device` and `name` points to a valid C string.
+ let resource = unsafe {
+ bindings::platform_get_resource_byname(
+ self.as_raw(),
+ bindings::IORESOURCE_MEM,
+ name.as_char_ptr(),
+ )
+ };
+
+ if resource.is_null() {
+ return None;
+ }
+
+ // SAFETY: `resource` is a valid pointer to a `struct resource` as
+ // returned by `platform_get_resource`.
+ Some(unsafe { Resource::from_raw(resource) })
+ }
+}
+
+impl Device<Bound> {
+ /// Returns an `IoRequest` for the resource at `index`, if any.
+ pub fn io_request_by_index(&self, index: u32) -> Option<IoRequest<'_>> {
+ self.resource_by_index(index)
+ // SAFETY: `resource` is a valid resource for `&self` during the
+ // lifetime of the `IoRequest`.
+ .map(|resource| unsafe { IoRequest::new(self.as_ref(), resource) })
+ }
+
+ /// Returns an `IoRequest` for the resource with a given `name`, if any.
+ pub fn io_request_by_name(&self, name: &CStr) -> Option<IoRequest<'_>> {
+ self.resource_by_name(name)
+ // SAFETY: `resource` is a valid resource for `&self` during the
+ // lifetime of the `IoRequest`.
+ .map(|resource| unsafe { IoRequest::new(self.as_ref(), resource) })
+ }
}
// SAFETY: `Device` is a transparent wrapper of a type that doesn't depend on `Device`'s generic