Skip to content

Commit bc4f904

Browse files
danielalmeida-collaboraDanilo Krummrich
authored andcommitted
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>
1 parent 1d0d4b2 commit bc4f904

2 files changed

Lines changed: 59 additions & 2 deletions

File tree

rust/kernel/io/mem.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ impl<'a> IoRequest<'a> {
2828
///
2929
/// Callers must ensure that `resource` is valid for `device` during the
3030
/// lifetime `'a`.
31-
#[expect(dead_code)]
3231
pub(crate) unsafe fn new(device: &'a Device<Bound>, resource: &'a Resource) -> Self {
3332
IoRequest { device, resource }
3433
}

rust/kernel/platform.rs

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@
55
//! C header: [`include/linux/platform_device.h`](srctree/include/linux/platform_device.h)
66
77
use crate::{
8-
acpi, bindings, container_of, device, driver,
8+
acpi, bindings, container_of,
9+
device::{self, Bound},
10+
driver,
911
error::{from_result, to_result, Result},
12+
io::{mem::IoRequest, Resource},
1013
of,
1114
prelude::*,
1215
types::Opaque,
@@ -224,6 +227,61 @@ impl<Ctx: device::DeviceContext> Device<Ctx> {
224227
fn as_raw(&self) -> *mut bindings::platform_device {
225228
self.0.get()
226229
}
230+
231+
/// Returns the resource at `index`, if any.
232+
pub fn resource_by_index(&self, index: u32) -> Option<&Resource> {
233+
// SAFETY: `self.as_raw()` returns a valid pointer to a `struct platform_device`.
234+
let resource = unsafe {
235+
bindings::platform_get_resource(self.as_raw(), bindings::IORESOURCE_MEM, index)
236+
};
237+
238+
if resource.is_null() {
239+
return None;
240+
}
241+
242+
// SAFETY: `resource` is a valid pointer to a `struct resource` as
243+
// returned by `platform_get_resource`.
244+
Some(unsafe { Resource::from_raw(resource) })
245+
}
246+
247+
/// Returns the resource with a given `name`, if any.
248+
pub fn resource_by_name(&self, name: &CStr) -> Option<&Resource> {
249+
// SAFETY: `self.as_raw()` returns a valid pointer to a `struct
250+
// platform_device` and `name` points to a valid C string.
251+
let resource = unsafe {
252+
bindings::platform_get_resource_byname(
253+
self.as_raw(),
254+
bindings::IORESOURCE_MEM,
255+
name.as_char_ptr(),
256+
)
257+
};
258+
259+
if resource.is_null() {
260+
return None;
261+
}
262+
263+
// SAFETY: `resource` is a valid pointer to a `struct resource` as
264+
// returned by `platform_get_resource`.
265+
Some(unsafe { Resource::from_raw(resource) })
266+
}
267+
}
268+
269+
impl Device<Bound> {
270+
/// Returns an `IoRequest` for the resource at `index`, if any.
271+
pub fn io_request_by_index(&self, index: u32) -> Option<IoRequest<'_>> {
272+
self.resource_by_index(index)
273+
// SAFETY: `resource` is a valid resource for `&self` during the
274+
// lifetime of the `IoRequest`.
275+
.map(|resource| unsafe { IoRequest::new(self.as_ref(), resource) })
276+
}
277+
278+
/// Returns an `IoRequest` for the resource with a given `name`, if any.
279+
pub fn io_request_by_name(&self, name: &CStr) -> Option<IoRequest<'_>> {
280+
self.resource_by_name(name)
281+
// SAFETY: `resource` is a valid resource for `&self` during the
282+
// lifetime of the `IoRequest`.
283+
.map(|resource| unsafe { IoRequest::new(self.as_ref(), resource) })
284+
}
227285
}
228286

229287
// SAFETY: `Device` is a transparent wrapper of a type that doesn't depend on `Device`'s generic

0 commit comments

Comments
 (0)