mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Daniel Almeida <daniel.almeida@collabora.com>
To: "Danilo Krummrich" <dakr@kernel.org>,
	"Abdiel Janulgue" <abdiel.janulgue@gmail.com>,
	"Robin Murphy" <robin.murphy@arm.com>,
	"Andreas Hindborg" <a.hindborg@kernel.org>,
	"Miguel Ojeda" <ojeda@kernel.org>,
	"Boqun Feng" <boqun@kernel.org>, "Gary Guo" <gary@garyguo.net>,
	"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
	"Benno Lossin" <lossin@kernel.org>,
	"Alice Ryhl" <aliceryhl@google.com>,
	"Trevor Gross" <tmgross@umich.edu>,
	"Tamir Duberstein" <tamird@kernel.org>,
	"Alexandre Courbot" <acourbot@nvidia.com>,
	"Onur Özkan" <work@onurozkan.dev>,
	"Bjorn Helgaas" <bhelgaas@google.com>,
	"Krzysztof Wilczyński" <kwilczynski@kernel.org>,
	"David Airlie" <airlied@gmail.com>,
	"Simona Vetter" <simona@ffwll.ch>
Cc: driver-core@lists.linux.dev, rust-for-linux@vger.kernel.org,
	 linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org,
	 dri-devel@lists.freedesktop.org,
	 Daniel Almeida <daniel.almeida@collabora.com>
Subject: [PATCH 1/7] rust: io: split IoCapable into IoReadable and IoWritable
Date: Thu, 15 Oct 2026 09:39:05 -0300	[thread overview]
Message-ID: <20261015-io-access-modes-v1-1-93611b84b5e3@collabora.com> (raw)
In-Reply-To: <20261015-io-access-modes-v1-0-93611b84b5e3@collabora.com>

`IoCapable<T>` provides both `io_read` and `io_write`, so a backend that
supports accesses of type `T` supports them in both directions, and every
(non-copy) `Io` method that reads or writes a value requires both. There
is no way to express a backend, or a view, that can only be read or only
be written.

Thus, replace `IoCapable<T>` with an `IoReadable<T>` trait holding
`io_read` and an `IoWritable<T>` trait holding `io_write`, and implement
both for all existing backends. The non-copy `Io` methods that read a
value now require `IoReadable` and those that write one require
`IoWritable`. `update` and `try_update` read and then write, so they
require both.

The copy methods use `IoCopyable` and are not changed here.

No functional change intended. This prepares for read-only and write-only
views, added in a following patch.

Signed-off-by: Daniel Almeida <daniel.almeida@collabora.com>
---
 rust/kernel/dma.rs    |  12 ++++--
 rust/kernel/io.rs     | 101 +++++++++++++++++++++++++++++---------------------
 rust/kernel/pci/io.rs |  10 +++--
 3 files changed, 75 insertions(+), 48 deletions(-)

diff --git a/rust/kernel/dma.rs b/rust/kernel/dma.rs
index 4ce914b7d1da..7216a78d38c9 100644
--- a/rust/kernel/dma.rs
+++ b/rust/kernel/dma.rs
@@ -17,8 +17,9 @@
     io::{
         IoBackend,
         IoBase,
-        IoCapable,
         IoCopyable,
+        IoReadable,
+        IoWritable,
         SysMem,
         SysMemBackend, //
     },
@@ -1180,15 +1181,20 @@ unsafe fn project_view<'a, T: ?Sized + KnownSize, U: ?Sized + KnownSize>(
     }
 }
 
-impl<T> IoCapable<T> for CoherentIoBackend
+impl<T> IoReadable<T> for CoherentIoBackend
 where
-    SysMemBackend: IoCapable<T>,
+    SysMemBackend: IoReadable<T>,
 {
     #[inline]
     fn io_read<'a>(view: Self::View<'a, T>) -> T {
         SysMemBackend::io_read(view.cpu_addr)
     }
+}
 
+impl<T> IoWritable<T> for CoherentIoBackend
+where
+    SysMemBackend: IoWritable<T>,
+{
     #[inline]
     fn io_write<'a>(view: Self::View<'a, T>, value: T) {
         SysMemBackend::io_write(view.cpu_addr, value)
diff --git a/rust/kernel/io.rs b/rust/kernel/io.rs
index de8ef8e2aec4..fd5dd5f6bda4 100644
--- a/rust/kernel/io.rs
+++ b/rust/kernel/io.rs
@@ -247,9 +247,9 @@ fn io_view_as_repr<'a, IO: Io<'a, Target = T>, T: AsRepr>(
 /// backends (e.g. MMIO, PCI config space, etc.).
 ///
 /// The base trait only defines the projection operations; which I/O methods are available depends
-/// on which [`IoCapable<T>`] traits are implemented for the type. For example, for MMIO regions,
-/// all widths (u8, u16, u32, and u64 on 64-bit systems) are typically supported. For PCI
-/// configuration space, u8, u16, and u32 are supported but u64 is not.
+/// on which [`IoReadable<T>`] and [`IoWritable<T>`] traits are implemented for the type. For
+/// example, for MMIO regions, all widths (u8, u16, u32, and u64 on 64-bit systems) are typically
+/// supported. For PCI configuration space, u8, u16, and u32 are supported but u64 is not.
 ///
 /// This trait is separate from the `Io` trait as multiple different I/O types may share the same
 /// operation.
@@ -276,18 +276,24 @@ unsafe fn project_view<'a, T: ?Sized + KnownSize, U: ?Sized + KnownSize>(
     ) -> Self::View<'a, U>;
 }
 
-/// Trait indicating that an I/O backend supports operations of a certain type and providing an
-/// implementation for these operations.
+/// Trait indicating that an I/O backend supports reads of a certain type and providing an
+/// implementation for these reads.
 ///
 /// Different I/O backends can implement this trait to expose only the operations they support.
 ///
-/// For example, a PCI configuration space may implement `IoCapable<u8>`, `IoCapable<u16>`,
-/// and `IoCapable<u32>`, but not `IoCapable<u64>`, while an MMIO region on a 64-bit
+/// For example, a PCI configuration space may implement `IoReadable<u8>`, `IoReadable<u16>`,
+/// and `IoReadable<u32>`, but not `IoReadable<u64>`, while an MMIO region on a 64-bit
 /// system might implement all four.
-pub trait IoCapable<T>: IoBackend {
+pub trait IoReadable<T>: IoBackend {
     /// Performs an I/O read of type `T` at `view` and returns the result.
     fn io_read<'a>(view: Self::View<'a, T>) -> T;
+}
 
+/// Trait indicating that an I/O backend supports writes of a certain type and providing an
+/// implementation for these writes.
+///
+/// Like [`IoReadable`], it is implemented for each type the backend supports.
+pub trait IoWritable<T>: IoBackend {
     /// Performs an I/O write of `value` at `view`.
     fn io_write<'a>(view: Self::View<'a, T>, value: T);
 }
@@ -548,7 +554,7 @@ fn try_cast<U>(self) -> Result<<Self::Backend as IoBackend>::View<'a, U>>
     fn read_val(self) -> Self::Target
     where
         Self::Target: AsReprMut,
-        Self::Backend: IoCapable<<Self::Target as AsRepr>::Repr>,
+        Self::Backend: IoReadable<<Self::Target as AsRepr>::Repr>,
     {
         Self::Target::from_repr(Self::Backend::io_read(io_view_as_repr(self)))
     }
@@ -570,7 +576,7 @@ fn read_val(self) -> Self::Target
     fn write_val(self, value: Self::Target)
     where
         Self::Target: AsRepr,
-        Self::Backend: IoCapable<<Self::Target as AsRepr>::Repr>,
+        Self::Backend: IoWritable<<Self::Target as AsRepr>::Repr>,
     {
         Self::Backend::io_write(io_view_as_repr(self), Self::Target::into_repr(value))
     }
@@ -695,7 +701,7 @@ fn copy_to_slice(self, data: &mut [u8])
     fn try_read8(self, offset: usize) -> Result<u8>
     where
         usize: IoLoc<Self::Target, u8>,
-        Self::Backend: IoCapable<u8>,
+        Self::Backend: IoReadable<u8>,
     {
         self.try_read(offset)
     }
@@ -705,7 +711,7 @@ fn try_read8(self, offset: usize) -> Result<u8>
     fn try_read16(self, offset: usize) -> Result<u16>
     where
         usize: IoLoc<Self::Target, u16>,
-        Self::Backend: IoCapable<u16>,
+        Self::Backend: IoReadable<u16>,
     {
         self.try_read(offset)
     }
@@ -715,7 +721,7 @@ fn try_read16(self, offset: usize) -> Result<u16>
     fn try_read32(self, offset: usize) -> Result<u32>
     where
         usize: IoLoc<Self::Target, u32>,
-        Self::Backend: IoCapable<u32>,
+        Self::Backend: IoReadable<u32>,
     {
         self.try_read(offset)
     }
@@ -725,7 +731,7 @@ fn try_read32(self, offset: usize) -> Result<u32>
     fn try_read64(self, offset: usize) -> Result<u64>
     where
         usize: IoLoc<Self::Target, u64>,
-        Self::Backend: IoCapable<u64>,
+        Self::Backend: IoReadable<u64>,
     {
         self.try_read(offset)
     }
@@ -735,7 +741,7 @@ fn try_read64(self, offset: usize) -> Result<u64>
     fn try_write8(self, value: u8, offset: usize) -> Result
     where
         usize: IoLoc<Self::Target, u8>,
-        Self::Backend: IoCapable<u8>,
+        Self::Backend: IoWritable<u8>,
     {
         self.try_write(offset, value)
     }
@@ -745,7 +751,7 @@ fn try_write8(self, value: u8, offset: usize) -> Result
     fn try_write16(self, value: u16, offset: usize) -> Result
     where
         usize: IoLoc<Self::Target, u16>,
-        Self::Backend: IoCapable<u16>,
+        Self::Backend: IoWritable<u16>,
     {
         self.try_write(offset, value)
     }
@@ -755,7 +761,7 @@ fn try_write16(self, value: u16, offset: usize) -> Result
     fn try_write32(self, value: u32, offset: usize) -> Result
     where
         usize: IoLoc<Self::Target, u32>,
-        Self::Backend: IoCapable<u32>,
+        Self::Backend: IoWritable<u32>,
     {
         self.try_write(offset, value)
     }
@@ -765,7 +771,7 @@ fn try_write32(self, value: u32, offset: usize) -> Result
     fn try_write64(self, value: u64, offset: usize) -> Result
     where
         usize: IoLoc<Self::Target, u64>,
-        Self::Backend: IoCapable<u64>,
+        Self::Backend: IoWritable<u64>,
     {
         self.try_write(offset, value)
     }
@@ -777,7 +783,7 @@ fn try_write64(self, value: u64, offset: usize) -> Result
     fn read8(self, offset: usize) -> u8
     where
         usize: IoLoc<Self::Target, u8>,
-        Self::Backend: IoCapable<u8>,
+        Self::Backend: IoReadable<u8>,
     {
         self.read(offset)
     }
@@ -789,7 +795,7 @@ fn read8(self, offset: usize) -> u8
     fn read16(self, offset: usize) -> u16
     where
         usize: IoLoc<Self::Target, u16>,
-        Self::Backend: IoCapable<u16>,
+        Self::Backend: IoReadable<u16>,
     {
         self.read(offset)
     }
@@ -801,7 +807,7 @@ fn read16(self, offset: usize) -> u16
     fn read32(self, offset: usize) -> u32
     where
         usize: IoLoc<Self::Target, u32>,
-        Self::Backend: IoCapable<u32>,
+        Self::Backend: IoReadable<u32>,
     {
         self.read(offset)
     }
@@ -813,7 +819,7 @@ fn read32(self, offset: usize) -> u32
     fn read64(self, offset: usize) -> u64
     where
         usize: IoLoc<Self::Target, u64>,
-        Self::Backend: IoCapable<u64>,
+        Self::Backend: IoReadable<u64>,
     {
         self.read(offset)
     }
@@ -825,7 +831,7 @@ fn read64(self, offset: usize) -> u64
     fn write8(self, value: u8, offset: usize)
     where
         usize: IoLoc<Self::Target, u8>,
-        Self::Backend: IoCapable<u8>,
+        Self::Backend: IoWritable<u8>,
     {
         self.write(offset, value)
     }
@@ -837,7 +843,7 @@ fn write8(self, value: u8, offset: usize)
     fn write16(self, value: u16, offset: usize)
     where
         usize: IoLoc<Self::Target, u16>,
-        Self::Backend: IoCapable<u16>,
+        Self::Backend: IoWritable<u16>,
     {
         self.write(offset, value)
     }
@@ -849,7 +855,7 @@ fn write16(self, value: u16, offset: usize)
     fn write32(self, value: u32, offset: usize)
     where
         usize: IoLoc<Self::Target, u32>,
-        Self::Backend: IoCapable<u32>,
+        Self::Backend: IoWritable<u32>,
     {
         self.write(offset, value)
     }
@@ -861,7 +867,7 @@ fn write32(self, value: u32, offset: usize)
     fn write64(self, value: u64, offset: usize)
     where
         usize: IoLoc<Self::Target, u64>,
-        Self::Backend: IoCapable<u64>,
+        Self::Backend: IoWritable<u64>,
     {
         self.write(offset, value)
     }
@@ -894,7 +900,7 @@ fn try_read<T, L>(self, location: L) -> Result<T>
     where
         T: AsReprMut,
         L: IoLoc<Self::Target, T>,
-        Self::Backend: IoCapable<<T as AsRepr>::Repr>,
+        Self::Backend: IoReadable<<T as AsRepr>::Repr>,
     {
         Ok(io_read!(self, try: location))
     }
@@ -927,7 +933,7 @@ fn try_write<T, L>(self, location: L, value: T) -> Result
     where
         T: AsRepr,
         L: IoLoc<Self::Target, T>,
-        Self::Backend: IoCapable<<T as AsRepr>::Repr>,
+        Self::Backend: IoWritable<<T as AsRepr>::Repr>,
     {
         io_write!(self, try: location, value);
         Ok(())
@@ -973,7 +979,7 @@ fn try_write_reg<T, L, V>(self, value: V) -> Result
         T: AsRepr,
         L: IoLoc<Self::Target, T>,
         V: LocatedRegister<Self::Target, Location = L, Value = T>,
-        Self::Backend: IoCapable<<T as AsRepr>::Repr>,
+        Self::Backend: IoWritable<<T as AsRepr>::Repr>,
     {
         let (location, value) = value.into_io_op();
 
@@ -1007,7 +1013,7 @@ fn try_update<T, L, F>(self, location: L, f: F) -> Result
     where
         T: AsReprMut,
         L: IoLoc<Self::Target, T>,
-        Self::Backend: IoCapable<<T as AsRepr>::Repr>,
+        Self::Backend: IoReadable<<T as AsRepr>::Repr> + IoWritable<<T as AsRepr>::Repr>,
         F: FnOnce(T) -> T,
     {
         let view = io_project!(self, try: location);
@@ -1041,7 +1047,7 @@ fn read<T, L>(self, location: L) -> T
     where
         T: AsReprMut,
         L: IoLoc<Self::Target, T>,
-        Self::Backend: IoCapable<<T as AsRepr>::Repr>,
+        Self::Backend: IoReadable<<T as AsRepr>::Repr>,
     {
         io_read!(self, build: location)
     }
@@ -1072,7 +1078,7 @@ fn write<T, L>(self, location: L, value: T)
     where
         T: AsRepr,
         L: IoLoc<Self::Target, T>,
-        Self::Backend: IoCapable<<T as AsRepr>::Repr>,
+        Self::Backend: IoWritable<<T as AsRepr>::Repr>,
     {
         io_write!(self, build: location, value);
     }
@@ -1116,7 +1122,7 @@ fn write_reg<T, L, V>(self, value: V)
         T: AsRepr,
         L: IoLoc<Self::Target, T>,
         V: LocatedRegister<Self::Target, Location = L, Value = T>,
-        Self::Backend: IoCapable<<T as AsRepr>::Repr>,
+        Self::Backend: IoWritable<<T as AsRepr>::Repr>,
     {
         let (location, value) = value.into_io_op();
 
@@ -1150,7 +1156,7 @@ fn update<T, L, F>(self, location: L, f: F)
     where
         T: AsReprMut,
         L: IoLoc<Self::Target, T>,
-        Self::Backend: IoCapable<<T as AsRepr>::Repr>,
+        Self::Backend: IoReadable<<T as AsRepr>::Repr> + IoWritable<<T as AsRepr>::Repr>,
         F: FnOnce(T) -> T,
     {
         let view = io_project!(self, build: location);
@@ -1237,17 +1243,20 @@ unsafe fn project_view<'a, T: ?Sized + KnownSize, U: ?Sized + KnownSize>(
     }
 }
 
-/// Implements [`IoCapable`] on `$backend` for `$ty` using `$read_fn` and `$write_fn`.
+/// Implements [`IoReadable`] and [`IoWritable`] on `$backend` for `$ty` using `$read_fn` and
+/// `$write_fn`.
 macro_rules! impl_mmio_io_capable {
     ($backend: ident, $ty:ty, $read_fn:ident, $write_fn:ident) => {
-        impl IoCapable<$ty> for $backend {
+        impl IoReadable<$ty> for $backend {
             #[inline]
             fn io_read(view: <$backend as IoBackend>::View<'_, $ty>) -> $ty {
                 // SAFETY: `$backend::as_ptr(view)` is a valid pointer for MMIO operations for both
                 // `MmioBackend` and `RelaxedMmioBackend`.
                 unsafe { bindings::$read_fn($backend::as_ptr(view).cast_const().cast()) }
             }
+        }
 
+        impl IoWritable<$ty> for $backend {
             #[inline]
             fn io_write(view: <$backend as IoBackend>::View<'_, $ty>, value: $ty) {
                 // SAFETY: `$backend::as_ptr(view)` is a valid pointer for MMIO operations for both
@@ -1396,11 +1405,11 @@ unsafe fn project_view<'a, T: ?Sized + KnownSize, U: ?Sized + KnownSize>(
     }
 }
 
-/// Implements [`IoCapable`] on `SysMemBackend` for `$ty` using `read_volatile` and
-/// `write_volatile`.
+/// Implements [`IoReadable`] and [`IoWritable`] on `SysMemBackend` for `$ty` using
+/// `read_volatile` and `write_volatile`.
 macro_rules! impl_sysmem_io_capable {
     ($ty:ty) => {
-        impl IoCapable<$ty> for SysMemBackend {
+        impl IoReadable<$ty> for SysMemBackend {
             #[inline]
             fn io_read(view: SysMem<'_, $ty>) -> $ty {
                 // SAFETY:
@@ -1411,7 +1420,9 @@ fn io_read(view: SysMem<'_, $ty>) -> $ty {
                 // - The macro is only used on primitives so all bit patterns are valid.
                 unsafe { view.ptr.read_volatile() }
             }
+        }
 
+        impl IoWritable<$ty> for SysMemBackend {
             #[inline]
             fn io_write(view: SysMem<'_, $ty>, value: $ty) {
                 // SAFETY:
@@ -1601,10 +1612,10 @@ unsafe fn project_view<'a, T: ?Sized + KnownSize, U: ?Sized + KnownSize>(
     }
 }
 
-impl<T> IoCapable<T> for IoSysMapBackend
+impl<T> IoReadable<T> for IoSysMapBackend
 where
-    MmioBackend: IoCapable<T>,
-    SysMemBackend: IoCapable<T>,
+    MmioBackend: IoReadable<T>,
+    SysMemBackend: IoReadable<T>,
 {
     #[inline]
     fn io_read(view: Self::View<'_, T>) -> T {
@@ -1613,7 +1624,13 @@ fn io_read(view: Self::View<'_, T>) -> T {
             IoSysMap::Sys(r) => SysMemBackend::io_read(r),
         }
     }
+}
 
+impl<T> IoWritable<T> for IoSysMapBackend
+where
+    MmioBackend: IoWritable<T>,
+    SysMemBackend: IoWritable<T>,
+{
     #[inline]
     fn io_write<'a>(view: Self::View<'a, T>, value: T) {
         match view {
diff --git a/rust/kernel/pci/io.rs b/rust/kernel/pci/io.rs
index 953e16735c6e..426e914e15c2 100644
--- a/rust/kernel/pci/io.rs
+++ b/rust/kernel/pci/io.rs
@@ -10,7 +10,8 @@
     io::{
         IoBackend,
         IoBase,
-        IoCapable,
+        IoReadable,
+        IoWritable,
         Mmio,
         MmioBackend,
         MmioRaw,
@@ -111,10 +112,11 @@ unsafe fn project_view<'a, T: ?Sized + KnownSize, U: ?Sized + KnownSize>(
     }
 }
 
-/// Implements [`IoCapable`] on [`ConfigSpace`] for `$ty` using `$read_fn` and `$write_fn`.
+/// Implements [`IoReadable`] and [`IoWritable`] on [`ConfigSpace`] for `$ty` using `$read_fn`
+/// and `$write_fn`.
 macro_rules! impl_config_space_io_capable {
     ($ty:ty, $read_fn:ident, $write_fn:ident) => {
-        impl IoCapable<$ty> for ConfigSpaceBackend {
+        impl IoReadable<$ty> for ConfigSpaceBackend {
             fn io_read(view: ConfigSpace<'_, $ty>) -> $ty {
                 // CAST: The offset is cast to `i32` because the C functions expect a 32-bit
                 // signed offset parameter. PCI configuration space size is at most 4096 bytes,
@@ -128,7 +130,9 @@ fn io_read(view: ConfigSpace<'_, $ty>) -> $ty {
                 let _ = unsafe { bindings::$read_fn(view.pdev.as_raw(), addr, &mut val) };
                 val
             }
+        }
 
+        impl IoWritable<$ty> for ConfigSpaceBackend {
             fn io_write(view: ConfigSpace<'_, $ty>, value: $ty) {
                 // CAST: The offset is cast to `i32` because the C functions expect a 32-bit
                 // signed offset parameter. PCI configuration space size is at most 4096 bytes,

-- 
2.56.0


  reply	other threads:[~2026-10-15 12:39 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-15 12:39 [PATCH 0/7] rust: io: add read-only and write-only views and registers Daniel Almeida
2026-10-15 12:39 ` Daniel Almeida [this message]
2026-10-20 12:04   ` [PATCH 1/7] rust: io: split IoCapable into IoReadable and IoWritable Gary Guo
2026-10-20 14:01     ` Vishal Moola (Fractile)
2026-10-15 12:39 ` [PATCH 2/7] rust: io: split IoCopyable into IoCopyReadable and IoCopyWritable Daniel Almeida
2026-10-15 12:39 ` [PATCH 3/7] rust: io: add read-only and write-only views Daniel Almeida
2026-10-15 12:39 ` [PATCH 4/7] rust: io: project primitive accessors directly Daniel Almeida
2026-10-15 12:39 ` [PATCH 5/7] rust: io: let I/O locations carry an access mode Daniel Almeida
2026-10-20 12:23   ` Gary Guo
2026-10-15 12:39 ` [PATCH 6/7] rust: io: register: add `#[ro]` and `#[wo]` attributes Daniel Almeida
2026-10-15 12:39 ` [PATCH 7/7] drm/tyr: mark read-only and write-only registers Daniel Almeida
2026-10-20  8:01 ` [PATCH 0/7] rust: io: add read-only and write-only views and registers 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=20261015-io-access-modes-v1-1-93611b84b5e3@collabora.com \
    --to=daniel.almeida@collabora.com \
    --cc=a.hindborg@kernel.org \
    --cc=abdiel.janulgue@gmail.com \
    --cc=acourbot@nvidia.com \
    --cc=airlied@gmail.com \
    --cc=aliceryhl@google.com \
    --cc=bhelgaas@google.com \
    --cc=bjorn3_gh@protonmail.com \
    --cc=boqun@kernel.org \
    --cc=dakr@kernel.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=driver-core@lists.linux.dev \
    --cc=gary@garyguo.net \
    --cc=kwilczynski@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=lossin@kernel.org \
    --cc=ojeda@kernel.org \
    --cc=robin.murphy@arm.com \
    --cc=rust-for-linux@vger.kernel.org \
    --cc=simona@ffwll.ch \
    --cc=tamird@kernel.org \
    --cc=tmgross@umich.edu \
    --cc=work@onurozkan.dev \
    /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

all inboxes | Powered by JetHome®