From: Danilo Krummrich <dakr@kernel.org>
To: Daniel Almeida <daniel.almeida@collabora.com>
Cc: "Miguel Ojeda" <ojeda@kernel.org>,
"Alex Gaynor" <alex.gaynor@gmail.com>,
"Boqun Feng" <boqun.feng@gmail.com>,
"Gary Guo" <gary@garyguo.net>,
"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
"Benno Lossin" <benno.lossin@proton.me>,
"Andreas Hindborg" <a.hindborg@kernel.org>,
"Alice Ryhl" <aliceryhl@google.com>,
"Trevor Gross" <tmgross@umich.edu>,
"Greg Kroah-Hartman" <gregkh@linuxfoundation.org>,
"Rafael J. Wysocki" <rafael@kernel.org>,
rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH] rust: platform: add Io support
Date: Tue, 29 Oct 2024 14:42:02 +0100 [thread overview]
Message-ID: <e713fe2a-df7b-445d-9f2b-08a22161ff8e@kernel.org> (raw)
In-Reply-To: <20241024-topic-panthor-rs-platform_io_support-v1-1-3d1addd96e30@collabora.com>
On 10/24/24 4:20 PM, Daniel Almeida wrote:
> The IoMem is backed by ioremap_resource()
ioremap_resource()?
Also, that's a rather short commit message for such a core piece of
infrastructure, can you please expand on this?
>
> Signed-off-by: Daniel Almeida <daniel.almeida@collabora.com>
> ---
> The PCI/Platform abstractions are in-flight and can be found at:
>
> https://lore.kernel.org/rust-for-linux/Zxili5yze1l5p5GN@pollux/T/#t
> ---
> rust/bindings/bindings_helper.h | 1 +
> rust/helpers/io.c | 11 ++++++
> rust/kernel/platform.rs | 88 +++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 100 insertions(+)
>
> diff --git a/rust/bindings/bindings_helper.h b/rust/bindings/bindings_helper.h
> index 217c776615b9593a2fa921dee130c357dbd96761..90b2d29e7b99f33ceb313b4cc7f8232fef5eed17 100644
> --- a/rust/bindings/bindings_helper.h
> +++ b/rust/bindings/bindings_helper.h
> @@ -13,6 +13,7 @@
> #include <linux/errname.h>
> #include <linux/ethtool.h>
> #include <linux/firmware.h>
> +#include <linux/ioport.h>
> #include <linux/jiffies.h>
> #include <linux/mdio.h>
> #include <linux/of_device.h>
> diff --git a/rust/helpers/io.c b/rust/helpers/io.c
> index f9bb1bbf1fd5daedc970fc342eeacd8777a8d8ed..f708c09c4c87634c56af29ef22ebaa2bf51d82a9 100644
> --- a/rust/helpers/io.c
> +++ b/rust/helpers/io.c
> @@ -1,6 +1,7 @@
> // SPDX-License-Identifier: GPL-2.0
>
> #include <linux/io.h>
> +#include <linux/ioport.h>
>
> u8 rust_helper_readb(const volatile void __iomem *addr)
> {
> @@ -89,3 +90,13 @@ void rust_helper_writeq_relaxed(u64 value, volatile void __iomem *addr)
> writeq_relaxed(value, addr);
> }
> #endif
> +
> +resource_size_t rust_helper_resource_size(struct resource *res)
> +{
> + return resource_size(res);
> +}
> +
> +void __iomem *rust_helper_ioremap(resource_size_t addr, unsigned long size)
> +{
> + return ioremap(addr, size);
> +}
> diff --git a/rust/kernel/platform.rs b/rust/kernel/platform.rs
> index addf5356f44f3cf233503aed97f1aa0d32f4f062..d152432c80a4499ead30ddaebe8d87a9679bfa97 100644
> --- a/rust/kernel/platform.rs
> +++ b/rust/kernel/platform.rs
> @@ -4,11 +4,15 @@
> //!
> //! C header: [`include/linux/platform_device.h`](srctree/include/linux/platform_device.h)
>
> +use core::ops::Deref;
> +
> use crate::{
> bindings, container_of, device,
> device_id::RawDeviceId,
> + devres::Devres,
> driver,
> error::{to_result, Result},
> + io::Io,
> of,
> prelude::*,
> str::CStr,
> @@ -208,6 +212,49 @@ fn as_raw(&self) -> *mut bindings::platform_device {
> // embedded in `struct platform_device`.
> unsafe { container_of!(self.0.as_raw(), bindings::platform_device, dev) }.cast_mut()
> }
> +
> + /// Maps a platform resource through ioremap() where the size is known at
> + /// compile time.
> + pub fn ioremap_resource_sized<const SIZE: usize>(
> + &self,
> + resource: u32,
> + ) -> Result<Devres<IoMem<SIZE>>> {
> + let res = self.resource(resource)?;
> + let size = self.resource_len(resource)? as usize;
> +
> + // SAFETY: `res` is guaranteed to be a valid MMIO address and the size
> + // is given by the kernel as per `self.resource_len()`.
> + let io = unsafe { IoMem::new(res as _, size) }?;
> + let devres = Devres::new(self.as_ref(), io, GFP_KERNEL)?;
> +
> + Ok(devres)
> + }
> +
> + /// Maps a platform resource through ioremap().
> + pub fn ioremap_resource(&self, resource: u32) -> Result<Devres<IoMem>> {
> + self.ioremap_resource_sized::<0>(resource)
> + }
> +
> + /// Returns the resource len for `resource`, if it exists.
> + pub fn resource_len(&self, resource: u32) -> Result<bindings::resource_size_t> {
> + match self.resource(resource) {
> + // SAFETY: if a struct resource* is returned by the kernel, it is valid.
> + Ok(resource) => Ok(unsafe { bindings::resource_size(resource) }),
> + Err(e) => Err(e),
> + }
> + }
> +
> + fn resource(&self, resource: u32) -> Result<*mut bindings::resource> {
> + // SAFETY: By the type invariants, we know that `self.ptr` is non-null and valid.
> + let resource = unsafe {
> + bindings::platform_get_resource(self.as_raw(), bindings::IORESOURCE_MEM, resource)
> + };
> + if !resource.is_null() {
> + Ok(resource)
> + } else {
> + Err(EINVAL)
> + }
> + }
> }
>
> impl AsRef<device::Device> for Device {
> @@ -215,3 +262,44 @@ fn as_ref(&self) -> &device::Device {
> &self.0
> }
> }
> +
> +/// A I/O-mapped memory region for platform devices.
> +///
> +/// See also [`kernel::pci::Bar`].
> +pub struct IoMem<const SIZE: usize = 0>(Io<SIZE>);
Is this meant to be bus specific, such as `pci::Bar` is PCI specific?
If so, I think it'd be better to pass the platform device and resource index to
`platform::IoMem` (or whatever we want to call it) and let it take care of
everything.
> +
> +impl<const SIZE: usize> IoMem<SIZE> {
> + /// Creates a new `IoMem` instance.
> + ///
> + /// # Safety
> + ///
> + /// The caller must make sure that `paddr` is a valid MMIO address.
> + unsafe fn new(paddr: usize, size: usize) -> Result<Self> {
> + // SAFETY: the safety requirements assert that `paddr` is a valid MMIO address.
> + let addr = unsafe { bindings::ioremap(paddr as _, size as u64) };
Do we need to consider ioremap_uc(), ioremap_wc(), ioremap_np()?
Also, I think you're missing request_region() here.
> + if addr.is_null() {
> + return Err(ENOMEM);
> + }
> +
> + // SAFETY: `addr` is guaranteed to be the start of a valid I/O mapped memory region of
> + // size `size`.
> + let io = unsafe { Io::new(addr as _, size)? };
> +
> + Ok(IoMem(io))
> + }
> +}
> +
> +impl<const SIZE: usize> Drop for IoMem<SIZE> {
> + fn drop(&mut self) {
> + // SAFETY: Safe as by the invariant of `Io`.
> + unsafe { bindings::iounmap(self.0.base_addr() as _) };
> + }
> +}
> +
> +impl<const SIZE: usize> Deref for IoMem<SIZE> {
> + type Target = Io<SIZE>;
> +
> + fn deref(&self) -> &Self::Target {
> + &self.0
> + }
> +}
>
> ---
> base-commit: 2a5c159f49a5801603af03510c7cef89ff4c9850
> change-id: 20241023-topic-panthor-rs-platform_io_support-f97aeb2ea887
>
> Best regards,
next prev parent reply other threads:[~2024-10-29 13:42 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-10-24 14:20 [PATCH] rust: platform: add Io support Daniel Almeida
2024-10-28 15:37 ` Alice Ryhl
2024-10-28 18:22 ` Daniel Almeida
2024-10-29 13:46 ` Alice Ryhl
2024-11-04 21:28 ` Daniel Almeida
2024-11-05 10:09 ` Alice Ryhl
2024-10-29 13:42 ` Danilo Krummrich [this message]
2024-11-04 20:24 ` Daniel Almeida
2024-11-06 10:31 ` Alice Ryhl
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=e713fe2a-df7b-445d-9f2b-08a22161ff8e@kernel.org \
--to=dakr@kernel.org \
--cc=a.hindborg@kernel.org \
--cc=alex.gaynor@gmail.com \
--cc=aliceryhl@google.com \
--cc=benno.lossin@proton.me \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun.feng@gmail.com \
--cc=daniel.almeida@collabora.com \
--cc=gary@garyguo.net \
--cc=gregkh@linuxfoundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=ojeda@kernel.org \
--cc=rafael@kernel.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=tmgross@umich.edu \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).