Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

rust: driver: implement `Adapter`

In order to not duplicate code in bus specific implementations (e.g.
platform), implement a generic `driver::Adapter` to represent the
connection of matched drivers and devices.

Bus specific `Adapter` implementations can simply implement this trait
to inherit generic functionality, such as matching OF or ACPI device IDs
and ID table entries.

Suggested-by: Rob Herring (Arm) <robh@kernel.org>
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
Tested-by: Dirk Behme <dirk.behme@de.bosch.com>
Link: https://lore.kernel.org/r/20241219170425.12036-14-dakr@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Danilo Krummrich and committed by
Greg Kroah-Hartman
7a718a1f bbe3b4d1

+58 -1
+1
rust/bindings/bindings_helper.h
··· 20 20 #include <linux/jump_label.h> 21 21 #include <linux/mdio.h> 22 22 #include <linux/miscdevice.h> 23 + #include <linux/of_device.h> 23 24 #include <linux/pci.h> 24 25 #include <linux/phy.h> 25 26 #include <linux/pid_namespace.h>
+57 -1
rust/kernel/driver.rs
··· 6 6 //! register using the [`Registration`] class. 7 7 8 8 use crate::error::{Error, Result}; 9 - use crate::{init::PinInit, str::CStr, try_pin_init, types::Opaque, ThisModule}; 9 + use crate::{device, init::PinInit, of, str::CStr, try_pin_init, types::Opaque, ThisModule}; 10 10 use core::pin::Pin; 11 11 use macros::{pin_data, pinned_drop}; 12 12 ··· 113 113 type: DriverModule, 114 114 $($f)* 115 115 } 116 + } 117 + } 118 + 119 + /// The bus independent adapter to match a drivers and a devices. 120 + /// 121 + /// This trait should be implemented by the bus specific adapter, which represents the connection 122 + /// of a device and a driver. 123 + /// 124 + /// It provides bus independent functions for device / driver interactions. 125 + pub trait Adapter { 126 + /// The type holding driver private data about each device id supported by the driver. 127 + type IdInfo: 'static; 128 + 129 + /// The [`of::IdTable`] of the corresponding driver. 130 + fn of_id_table() -> Option<of::IdTable<Self::IdInfo>>; 131 + 132 + /// Returns the driver's private data from the matching entry in the [`of::IdTable`], if any. 133 + /// 134 + /// If this returns `None`, it means there is no match with an entry in the [`of::IdTable`]. 135 + #[cfg(CONFIG_OF)] 136 + fn of_id_info(dev: &device::Device) -> Option<&'static Self::IdInfo> { 137 + let table = Self::of_id_table()?; 138 + 139 + // SAFETY: 140 + // - `table` has static lifetime, hence it's valid for read, 141 + // - `dev` is guaranteed to be valid while it's alive, and so is `pdev.as_ref().as_raw()`. 142 + let raw_id = unsafe { bindings::of_match_device(table.as_ptr(), dev.as_raw()) }; 143 + 144 + if raw_id.is_null() { 145 + None 146 + } else { 147 + // SAFETY: `DeviceId` is a `#[repr(transparent)` wrapper of `struct of_device_id` and 148 + // does not add additional invariants, so it's safe to transmute. 149 + let id = unsafe { &*raw_id.cast::<of::DeviceId>() }; 150 + 151 + Some(table.info(<of::DeviceId as crate::device_id::RawDeviceId>::index(id))) 152 + } 153 + } 154 + 155 + #[cfg(not(CONFIG_OF))] 156 + #[allow(missing_docs)] 157 + fn of_id_info(_dev: &device::Device) -> Option<&'static Self::IdInfo> { 158 + None 159 + } 160 + 161 + /// Returns the driver's private data from the matching entry of any of the ID tables, if any. 162 + /// 163 + /// If this returns `None`, it means that there is no match in any of the ID tables directly 164 + /// associated with a [`device::Device`]. 165 + fn id_info(dev: &device::Device) -> Option<&'static Self::IdInfo> { 166 + let id = Self::of_id_info(dev); 167 + if id.is_some() { 168 + return id; 169 + } 170 + 171 + None 116 172 } 117 173 }