xref: /linux/rust/kernel/driver.rs (revision 4f9786035f9e519db41375818e1d0b5f20da2f10)
1ea7e1828SDanilo Krummrich // SPDX-License-Identifier: GPL-2.0
2ea7e1828SDanilo Krummrich 
3ea7e1828SDanilo Krummrich //! Generic support for drivers of different buses (e.g., PCI, Platform, Amba, etc.).
4ea7e1828SDanilo Krummrich //!
5ea7e1828SDanilo Krummrich //! Each bus / subsystem is expected to implement [`RegistrationOps`], which allows drivers to
6ea7e1828SDanilo Krummrich //! register using the [`Registration`] class.
7ea7e1828SDanilo Krummrich 
8ea7e1828SDanilo Krummrich use crate::error::{Error, Result};
9*dbd5058bSBenno Lossin use crate::{device, of, str::CStr, try_pin_init, types::Opaque, ThisModule};
10ea7e1828SDanilo Krummrich use core::pin::Pin;
11*dbd5058bSBenno Lossin use pin_init::{pin_data, pinned_drop, PinInit};
12ea7e1828SDanilo Krummrich 
13ea7e1828SDanilo Krummrich /// The [`RegistrationOps`] trait serves as generic interface for subsystems (e.g., PCI, Platform,
14ea7e1828SDanilo Krummrich /// Amba, etc.) to provide the corresponding subsystem specific implementation to register /
15ea7e1828SDanilo Krummrich /// unregister a driver of the particular type (`RegType`).
16ea7e1828SDanilo Krummrich ///
17ea7e1828SDanilo Krummrich /// For instance, the PCI subsystem would set `RegType` to `bindings::pci_driver` and call
18ea7e1828SDanilo Krummrich /// `bindings::__pci_register_driver` from `RegistrationOps::register` and
19ea7e1828SDanilo Krummrich /// `bindings::pci_unregister_driver` from `RegistrationOps::unregister`.
20e1a51c2bSDanilo Krummrich ///
21e1a51c2bSDanilo Krummrich /// # Safety
22e1a51c2bSDanilo Krummrich ///
23e1a51c2bSDanilo Krummrich /// A call to [`RegistrationOps::unregister`] for a given instance of `RegType` is only valid if a
24e1a51c2bSDanilo Krummrich /// preceding call to [`RegistrationOps::register`] has been successful.
25e1a51c2bSDanilo Krummrich pub unsafe trait RegistrationOps {
26ea7e1828SDanilo Krummrich     /// The type that holds information about the registration. This is typically a struct defined
27ea7e1828SDanilo Krummrich     /// by the C portion of the kernel.
28ea7e1828SDanilo Krummrich     type RegType: Default;
29ea7e1828SDanilo Krummrich 
30ea7e1828SDanilo Krummrich     /// Registers a driver.
31ea7e1828SDanilo Krummrich     ///
32e1a51c2bSDanilo Krummrich     /// # Safety
33e1a51c2bSDanilo Krummrich     ///
34ea7e1828SDanilo Krummrich     /// On success, `reg` must remain pinned and valid until the matching call to
35ea7e1828SDanilo Krummrich     /// [`RegistrationOps::unregister`].
36e1a51c2bSDanilo Krummrich     unsafe fn register(
37ea7e1828SDanilo Krummrich         reg: &Opaque<Self::RegType>,
38ea7e1828SDanilo Krummrich         name: &'static CStr,
39ea7e1828SDanilo Krummrich         module: &'static ThisModule,
40ea7e1828SDanilo Krummrich     ) -> Result;
41ea7e1828SDanilo Krummrich 
42ea7e1828SDanilo Krummrich     /// Unregisters a driver previously registered with [`RegistrationOps::register`].
43e1a51c2bSDanilo Krummrich     ///
44e1a51c2bSDanilo Krummrich     /// # Safety
45e1a51c2bSDanilo Krummrich     ///
46e1a51c2bSDanilo Krummrich     /// Must only be called after a preceding successful call to [`RegistrationOps::register`] for
47e1a51c2bSDanilo Krummrich     /// the same `reg`.
48e1a51c2bSDanilo Krummrich     unsafe fn unregister(reg: &Opaque<Self::RegType>);
49ea7e1828SDanilo Krummrich }
50ea7e1828SDanilo Krummrich 
51ea7e1828SDanilo Krummrich /// A [`Registration`] is a generic type that represents the registration of some driver type (e.g.
52ea7e1828SDanilo Krummrich /// `bindings::pci_driver`). Therefore a [`Registration`] must be initialized with a type that
53ea7e1828SDanilo Krummrich /// implements the [`RegistrationOps`] trait, such that the generic `T::register` and
54ea7e1828SDanilo Krummrich /// `T::unregister` calls result in the subsystem specific registration calls.
55ea7e1828SDanilo Krummrich ///
56ea7e1828SDanilo Krummrich ///Once the `Registration` structure is dropped, the driver is unregistered.
57ea7e1828SDanilo Krummrich #[pin_data(PinnedDrop)]
58ea7e1828SDanilo Krummrich pub struct Registration<T: RegistrationOps> {
59ea7e1828SDanilo Krummrich     #[pin]
60ea7e1828SDanilo Krummrich     reg: Opaque<T::RegType>,
61ea7e1828SDanilo Krummrich }
62ea7e1828SDanilo Krummrich 
63ea7e1828SDanilo Krummrich // SAFETY: `Registration` has no fields or methods accessible via `&Registration`, so it is safe to
64ea7e1828SDanilo Krummrich // share references to it with multiple threads as nothing can be done.
65ea7e1828SDanilo Krummrich unsafe impl<T: RegistrationOps> Sync for Registration<T> {}
66ea7e1828SDanilo Krummrich 
67ea7e1828SDanilo Krummrich // SAFETY: Both registration and unregistration are implemented in C and safe to be performed from
68ea7e1828SDanilo Krummrich // any thread, so `Registration` is `Send`.
69ea7e1828SDanilo Krummrich unsafe impl<T: RegistrationOps> Send for Registration<T> {}
70ea7e1828SDanilo Krummrich 
71ea7e1828SDanilo Krummrich impl<T: RegistrationOps> Registration<T> {
72ea7e1828SDanilo Krummrich     /// Creates a new instance of the registration object.
73ea7e1828SDanilo Krummrich     pub fn new(name: &'static CStr, module: &'static ThisModule) -> impl PinInit<Self, Error> {
74ea7e1828SDanilo Krummrich         try_pin_init!(Self {
75ea7e1828SDanilo Krummrich             reg <- Opaque::try_ffi_init(|ptr: *mut T::RegType| {
76ea7e1828SDanilo Krummrich                 // SAFETY: `try_ffi_init` guarantees that `ptr` is valid for write.
77ea7e1828SDanilo Krummrich                 unsafe { ptr.write(T::RegType::default()) };
78ea7e1828SDanilo Krummrich 
79ea7e1828SDanilo Krummrich                 // SAFETY: `try_ffi_init` guarantees that `ptr` is valid for write, and it has
80ea7e1828SDanilo Krummrich                 // just been initialised above, so it's also valid for read.
81ea7e1828SDanilo Krummrich                 let drv = unsafe { &*(ptr as *const Opaque<T::RegType>) };
82ea7e1828SDanilo Krummrich 
83e1a51c2bSDanilo Krummrich                 // SAFETY: `drv` is guaranteed to be pinned until `T::unregister`.
84e1a51c2bSDanilo Krummrich                 unsafe { T::register(drv, name, module) }
85ea7e1828SDanilo Krummrich             }),
86ea7e1828SDanilo Krummrich         })
87ea7e1828SDanilo Krummrich     }
88ea7e1828SDanilo Krummrich }
89ea7e1828SDanilo Krummrich 
90ea7e1828SDanilo Krummrich #[pinned_drop]
91ea7e1828SDanilo Krummrich impl<T: RegistrationOps> PinnedDrop for Registration<T> {
92ea7e1828SDanilo Krummrich     fn drop(self: Pin<&mut Self>) {
93e1a51c2bSDanilo Krummrich         // SAFETY: The existence of `self` guarantees that `self.reg` has previously been
94e1a51c2bSDanilo Krummrich         // successfully registered with `T::register`
95e1a51c2bSDanilo Krummrich         unsafe { T::unregister(&self.reg) };
96ea7e1828SDanilo Krummrich     }
97ea7e1828SDanilo Krummrich }
98ea7e1828SDanilo Krummrich 
99ea7e1828SDanilo Krummrich /// Declares a kernel module that exposes a single driver.
100ea7e1828SDanilo Krummrich ///
101ea7e1828SDanilo Krummrich /// It is meant to be used as a helper by other subsystems so they can more easily expose their own
102ea7e1828SDanilo Krummrich /// macros.
103ea7e1828SDanilo Krummrich #[macro_export]
104ea7e1828SDanilo Krummrich macro_rules! module_driver {
105ea7e1828SDanilo Krummrich     (<$gen_type:ident>, $driver_ops:ty, { type: $type:ty, $($f:tt)* }) => {
106ea7e1828SDanilo Krummrich         type Ops<$gen_type> = $driver_ops;
107ea7e1828SDanilo Krummrich 
108ea7e1828SDanilo Krummrich         #[$crate::prelude::pin_data]
109ea7e1828SDanilo Krummrich         struct DriverModule {
110ea7e1828SDanilo Krummrich             #[pin]
111ea7e1828SDanilo Krummrich             _driver: $crate::driver::Registration<Ops<$type>>,
112ea7e1828SDanilo Krummrich         }
113ea7e1828SDanilo Krummrich 
114ea7e1828SDanilo Krummrich         impl $crate::InPlaceModule for DriverModule {
115ea7e1828SDanilo Krummrich             fn init(
116ea7e1828SDanilo Krummrich                 module: &'static $crate::ThisModule
117*dbd5058bSBenno Lossin             ) -> impl ::pin_init::PinInit<Self, $crate::error::Error> {
118ea7e1828SDanilo Krummrich                 $crate::try_pin_init!(Self {
119ea7e1828SDanilo Krummrich                     _driver <- $crate::driver::Registration::new(
120ea7e1828SDanilo Krummrich                         <Self as $crate::ModuleMetadata>::NAME,
121ea7e1828SDanilo Krummrich                         module,
122ea7e1828SDanilo Krummrich                     ),
123ea7e1828SDanilo Krummrich                 })
124ea7e1828SDanilo Krummrich             }
125ea7e1828SDanilo Krummrich         }
126ea7e1828SDanilo Krummrich 
127ea7e1828SDanilo Krummrich         $crate::prelude::module! {
128ea7e1828SDanilo Krummrich             type: DriverModule,
129ea7e1828SDanilo Krummrich             $($f)*
130ea7e1828SDanilo Krummrich         }
131ea7e1828SDanilo Krummrich     }
132ea7e1828SDanilo Krummrich }
1337a718a1fSDanilo Krummrich 
1347a718a1fSDanilo Krummrich /// The bus independent adapter to match a drivers and a devices.
1357a718a1fSDanilo Krummrich ///
1367a718a1fSDanilo Krummrich /// This trait should be implemented by the bus specific adapter, which represents the connection
1377a718a1fSDanilo Krummrich /// of a device and a driver.
1387a718a1fSDanilo Krummrich ///
1397a718a1fSDanilo Krummrich /// It provides bus independent functions for device / driver interactions.
1407a718a1fSDanilo Krummrich pub trait Adapter {
1417a718a1fSDanilo Krummrich     /// The type holding driver private data about each device id supported by the driver.
1427a718a1fSDanilo Krummrich     type IdInfo: 'static;
1437a718a1fSDanilo Krummrich 
1447a718a1fSDanilo Krummrich     /// The [`of::IdTable`] of the corresponding driver.
1457a718a1fSDanilo Krummrich     fn of_id_table() -> Option<of::IdTable<Self::IdInfo>>;
1467a718a1fSDanilo Krummrich 
1477a718a1fSDanilo Krummrich     /// Returns the driver's private data from the matching entry in the [`of::IdTable`], if any.
1487a718a1fSDanilo Krummrich     ///
1497a718a1fSDanilo Krummrich     /// If this returns `None`, it means there is no match with an entry in the [`of::IdTable`].
1507a718a1fSDanilo Krummrich     #[cfg(CONFIG_OF)]
1517a718a1fSDanilo Krummrich     fn of_id_info(dev: &device::Device) -> Option<&'static Self::IdInfo> {
1527a718a1fSDanilo Krummrich         let table = Self::of_id_table()?;
1537a718a1fSDanilo Krummrich 
1547a718a1fSDanilo Krummrich         // SAFETY:
1557a718a1fSDanilo Krummrich         // - `table` has static lifetime, hence it's valid for read,
1567a718a1fSDanilo Krummrich         // - `dev` is guaranteed to be valid while it's alive, and so is `pdev.as_ref().as_raw()`.
1577a718a1fSDanilo Krummrich         let raw_id = unsafe { bindings::of_match_device(table.as_ptr(), dev.as_raw()) };
1587a718a1fSDanilo Krummrich 
1597a718a1fSDanilo Krummrich         if raw_id.is_null() {
1607a718a1fSDanilo Krummrich             None
1617a718a1fSDanilo Krummrich         } else {
1627a718a1fSDanilo Krummrich             // SAFETY: `DeviceId` is a `#[repr(transparent)` wrapper of `struct of_device_id` and
1637a718a1fSDanilo Krummrich             // does not add additional invariants, so it's safe to transmute.
1647a718a1fSDanilo Krummrich             let id = unsafe { &*raw_id.cast::<of::DeviceId>() };
1657a718a1fSDanilo Krummrich 
1667a718a1fSDanilo Krummrich             Some(table.info(<of::DeviceId as crate::device_id::RawDeviceId>::index(id)))
1677a718a1fSDanilo Krummrich         }
1687a718a1fSDanilo Krummrich     }
1697a718a1fSDanilo Krummrich 
1707a718a1fSDanilo Krummrich     #[cfg(not(CONFIG_OF))]
1717a718a1fSDanilo Krummrich     #[allow(missing_docs)]
1727a718a1fSDanilo Krummrich     fn of_id_info(_dev: &device::Device) -> Option<&'static Self::IdInfo> {
1737a718a1fSDanilo Krummrich         None
1747a718a1fSDanilo Krummrich     }
1757a718a1fSDanilo Krummrich 
1767a718a1fSDanilo Krummrich     /// Returns the driver's private data from the matching entry of any of the ID tables, if any.
1777a718a1fSDanilo Krummrich     ///
1787a718a1fSDanilo Krummrich     /// If this returns `None`, it means that there is no match in any of the ID tables directly
1797a718a1fSDanilo Krummrich     /// associated with a [`device::Device`].
1807a718a1fSDanilo Krummrich     fn id_info(dev: &device::Device) -> Option<&'static Self::IdInfo> {
1817a718a1fSDanilo Krummrich         let id = Self::of_id_info(dev);
1827a718a1fSDanilo Krummrich         if id.is_some() {
1837a718a1fSDanilo Krummrich             return id;
1847a718a1fSDanilo Krummrich         }
1857a718a1fSDanilo Krummrich 
1867a718a1fSDanilo Krummrich         None
1877a718a1fSDanilo Krummrich     }
1887a718a1fSDanilo Krummrich }
189