From: Danilo Krummrich Date: Mon, 26 Jan 2026 12:23:52 +0000 (+0100) Subject: Merge tag 'v6.19-rc7' into driver-core-next X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=eb3dad518e4da48ab6c6df16aa8895b8b0bd6ecf;p=thirdparty%2Fkernel%2Flinux.git Merge tag 'v6.19-rc7' into driver-core-next We need the driver-core fixes in here as well to build on top of. Signed-off-by: Danilo Krummrich --- eb3dad518e4da48ab6c6df16aa8895b8b0bd6ecf diff --cc rust/kernel/driver.rs index 315f1efe15589,bee3ae21a27b2..36de8098754d0 --- a/rust/kernel/driver.rs +++ b/rust/kernel/driver.rs @@@ -94,20 -94,40 +94,44 @@@ //! [`device_id`]: kernel::device_id //! [`module_driver`]: kernel::module_driver -use crate::error::{Error, Result}; -use crate::{acpi, device, of, str::CStr, try_pin_init, types::Opaque, ThisModule}; -use core::pin::Pin; -use pin_init::{pin_data, pinned_drop, PinInit}; +use crate::{ + acpi, + device, + of, + prelude::*, + types::Opaque, + ThisModule, // +}; + /// Trait describing the layout of a specific device driver. + /// + /// This trait describes the layout of a specific driver structure, such as `struct pci_driver` or + /// `struct platform_driver`. + /// + /// # Safety + /// + /// Implementors must guarantee that: + /// - `DriverType` is `repr(C)`, + /// - `DriverData` is the type of the driver's device private data. + /// - `DriverType` embeds a valid `struct device_driver` at byte offset `DEVICE_DRIVER_OFFSET`. + pub unsafe trait DriverLayout { + /// The specific driver type embedding a `struct device_driver`. + type DriverType: Default; + + /// The type of the driver's device private data. + type DriverData; + + /// Byte offset of the embedded `struct device_driver` within `DriverType`. + /// + /// This must correspond exactly to the location of the embedded `struct device_driver` field. + const DEVICE_DRIVER_OFFSET: usize; + } + /// The [`RegistrationOps`] trait serves as generic interface for subsystems (e.g., PCI, Platform, /// Amba, etc.) to provide the corresponding subsystem specific implementation to register / - /// unregister a driver of the particular type (`RegType`). + /// unregister a driver of the particular type (`DriverType`). /// - /// For instance, the PCI subsystem would set `RegType` to `bindings::pci_driver` and call + /// For instance, the PCI subsystem would set `DriverType` to `bindings::pci_driver` and call /// `bindings::__pci_register_driver` from `RegistrationOps::register` and /// `bindings::pci_unregister_driver` from `RegistrationOps::unregister`. /// diff --cc rust/kernel/io.rs index fcd1b156a14a4,b64b11f75a353..056a3ec71647b --- a/rust/kernel/io.rs +++ b/rust/kernel/io.rs @@@ -201,17 -142,15 +201,18 @@@ macro_rules! define_read /// Bound checks are performed on compile time, hence if the offset is not known at compile /// time, the build will fail. $(#[$attr])* - #[inline] + // Always inline to optimize out error path of `io_addr_assert`. + #[inline(always)] - pub fn $name(&self, offset: usize) -> $type_name { + $vis fn $name(&self, offset: usize) -> $type_name { let addr = self.io_addr_assert::<$type_name>(offset); - // SAFETY: By the type invariant `addr` is a valid address for MMIO operations. - unsafe { bindings::$c_fn(addr as *const c_void) } + // SAFETY: By the type invariant `addr` is a valid address for IO operations. + $call_macro!(infallible, $c_fn, self, $type_name, addr) } + }; + (fallible, $(#[$attr:meta])* $vis:vis $try_name:ident, $call_macro:ident($c_fn:ident) -> + $type_name:ty) => { /// Read IO data from a given offset. /// /// Bound checks are performed on runtime, it fails if the offset (plus the type size) is @@@ -235,16 -172,15 +236,17 @@@ macro_rules! define_write /// Bound checks are performed on compile time, hence if the offset is not known at compile /// time, the build will fail. $(#[$attr])* - #[inline] + // Always inline to optimize out error path of `io_addr_assert`. + #[inline(always)] - pub fn $name(&self, value: $type_name, offset: usize) { + $vis fn $name(&self, value: $type_name, offset: usize) { let addr = self.io_addr_assert::<$type_name>(offset); - // SAFETY: By the type invariant `addr` is a valid address for MMIO operations. - unsafe { bindings::$c_fn(value, addr as *mut c_void) } + $call_macro!(infallible, $c_fn, self, $type_name, addr, value); } + }; + (fallible, $(#[$attr:meta])* $vis:vis $try_name:ident, $call_macro:ident($c_fn:ident) <- + $type_name:ty) => { /// Write IO data from a given offset. /// /// Bound checks are performed on runtime, it fails if the offset (plus the type size) is @@@ -321,11 -241,10 +323,12 @@@ pub trait Io self.addr().checked_add(offset).ok_or(EINVAL) } + /// Returns the absolute I/O address for a given `offset`, + /// performing compile-time bound checks. - #[inline] + // Always inline to optimize out error path of `build_assert`. + #[inline(always)] fn io_addr_assert(&self, offset: usize) -> usize { - build_assert!(Self::offset_valid::(offset, SIZE)); + build_assert!(offset_valid::(offset, Self::MIN_SIZE)); self.addr() + offset }