xref: /linux/rust/kernel/serdev.rs (revision 99f59aa82341c8491a1b94c5dd9c666fe979a479)
1*99f59aa8SMarkus Probst // SPDX-License-Identifier: GPL-2.0
2*99f59aa8SMarkus Probst 
3*99f59aa8SMarkus Probst //! Abstractions for the serial device bus.
4*99f59aa8SMarkus Probst //!
5*99f59aa8SMarkus Probst //! C header: [`include/linux/serdev.h`](srctree/include/linux/serdev.h)
6*99f59aa8SMarkus Probst 
7*99f59aa8SMarkus Probst use crate::{
8*99f59aa8SMarkus Probst     acpi,
9*99f59aa8SMarkus Probst     device,
10*99f59aa8SMarkus Probst     driver,
11*99f59aa8SMarkus Probst     error::{
12*99f59aa8SMarkus Probst         from_result,
13*99f59aa8SMarkus Probst         to_result,
14*99f59aa8SMarkus Probst         VTABLE_DEFAULT_ERROR, //
15*99f59aa8SMarkus Probst     },
16*99f59aa8SMarkus Probst     new_mutex,
17*99f59aa8SMarkus Probst     of,
18*99f59aa8SMarkus Probst     prelude::*,
19*99f59aa8SMarkus Probst     sync::{
20*99f59aa8SMarkus Probst         aref::AlwaysRefCounted,
21*99f59aa8SMarkus Probst         Mutex, //
22*99f59aa8SMarkus Probst     },
23*99f59aa8SMarkus Probst     time::Jiffies,
24*99f59aa8SMarkus Probst     types::{
25*99f59aa8SMarkus Probst         Opaque,
26*99f59aa8SMarkus Probst         ScopeGuard, //
27*99f59aa8SMarkus Probst     }, //
28*99f59aa8SMarkus Probst };
29*99f59aa8SMarkus Probst 
30*99f59aa8SMarkus Probst use core::{
31*99f59aa8SMarkus Probst     cell::UnsafeCell,
32*99f59aa8SMarkus Probst     marker::PhantomData,
33*99f59aa8SMarkus Probst     mem::{offset_of, MaybeUninit},
34*99f59aa8SMarkus Probst     ptr::NonNull, //
35*99f59aa8SMarkus Probst };
36*99f59aa8SMarkus Probst 
37*99f59aa8SMarkus Probst /// Parity bit to use with a serial device.
38*99f59aa8SMarkus Probst #[repr(u32)]
39*99f59aa8SMarkus Probst pub enum Parity {
40*99f59aa8SMarkus Probst     /// No parity bit.
41*99f59aa8SMarkus Probst     None = bindings::serdev_parity_SERDEV_PARITY_NONE,
42*99f59aa8SMarkus Probst     /// Even partiy.
43*99f59aa8SMarkus Probst     Even = bindings::serdev_parity_SERDEV_PARITY_EVEN,
44*99f59aa8SMarkus Probst     /// Odd parity.
45*99f59aa8SMarkus Probst     Odd = bindings::serdev_parity_SERDEV_PARITY_ODD,
46*99f59aa8SMarkus Probst }
47*99f59aa8SMarkus Probst 
48*99f59aa8SMarkus Probst /// An adapter for the registration of serial device bus device drivers.
49*99f59aa8SMarkus Probst pub struct Adapter<T: Driver>(T);
50*99f59aa8SMarkus Probst 
51*99f59aa8SMarkus Probst // SAFETY:
52*99f59aa8SMarkus Probst // - `bindings::serdev_device_driver` is a C type declared as `repr(C)`.
53*99f59aa8SMarkus Probst // - `PrivateData<'bound, T>` is the type of the driver's device private data.
54*99f59aa8SMarkus Probst // - `struct serdev_device_driver` embeds a `struct device_driver`.
55*99f59aa8SMarkus Probst // - `DEVICE_DRIVER_OFFSET` is the correct byte offset to the embedded `struct device_driver`.
56*99f59aa8SMarkus Probst unsafe impl<T: Driver> driver::DriverLayout for Adapter<T> {
57*99f59aa8SMarkus Probst     type DriverType = bindings::serdev_device_driver;
58*99f59aa8SMarkus Probst     type DriverData<'bound> = PrivateData<'bound, T>;
59*99f59aa8SMarkus Probst     const DEVICE_DRIVER_OFFSET: usize = core::mem::offset_of!(Self::DriverType, driver);
60*99f59aa8SMarkus Probst }
61*99f59aa8SMarkus Probst 
62*99f59aa8SMarkus Probst // SAFETY: A call to `unregister` for a given instance of `DriverType` is guaranteed to be valid if
63*99f59aa8SMarkus Probst // a preceding call to `register` has been successful.
64*99f59aa8SMarkus Probst unsafe impl<T: Driver> driver::RegistrationOps for Adapter<T> {
65*99f59aa8SMarkus Probst     unsafe fn register(
66*99f59aa8SMarkus Probst         sdrv: &Opaque<Self::DriverType>,
67*99f59aa8SMarkus Probst         name: &'static CStr,
68*99f59aa8SMarkus Probst         module: &'static ThisModule,
69*99f59aa8SMarkus Probst     ) -> Result {
70*99f59aa8SMarkus Probst         let of_table = match T::OF_ID_TABLE {
71*99f59aa8SMarkus Probst             Some(table) => table.as_ptr(),
72*99f59aa8SMarkus Probst             None => core::ptr::null(),
73*99f59aa8SMarkus Probst         };
74*99f59aa8SMarkus Probst 
75*99f59aa8SMarkus Probst         let acpi_table = match T::ACPI_ID_TABLE {
76*99f59aa8SMarkus Probst             Some(table) => table.as_ptr(),
77*99f59aa8SMarkus Probst             None => core::ptr::null(),
78*99f59aa8SMarkus Probst         };
79*99f59aa8SMarkus Probst 
80*99f59aa8SMarkus Probst         // SAFETY: It's safe to set the fields of `struct serdev_device_driver` on initialization.
81*99f59aa8SMarkus Probst         unsafe {
82*99f59aa8SMarkus Probst             (*sdrv.get()).driver.name = name.as_char_ptr();
83*99f59aa8SMarkus Probst             (*sdrv.get()).probe = Some(Self::probe_callback);
84*99f59aa8SMarkus Probst             (*sdrv.get()).remove = Some(Self::remove_callback);
85*99f59aa8SMarkus Probst             (*sdrv.get()).driver.of_match_table = of_table;
86*99f59aa8SMarkus Probst             (*sdrv.get()).driver.acpi_match_table = acpi_table;
87*99f59aa8SMarkus Probst         }
88*99f59aa8SMarkus Probst 
89*99f59aa8SMarkus Probst         // SAFETY: `sdrv` is guaranteed to be a valid `DriverType`.
90*99f59aa8SMarkus Probst         to_result(unsafe { bindings::__serdev_device_driver_register(sdrv.get(), module.0) })
91*99f59aa8SMarkus Probst     }
92*99f59aa8SMarkus Probst 
93*99f59aa8SMarkus Probst     unsafe fn unregister(sdrv: &Opaque<Self::DriverType>) {
94*99f59aa8SMarkus Probst         // SAFETY: `sdrv` is guaranteed to be a valid `DriverType`.
95*99f59aa8SMarkus Probst         unsafe { bindings::serdev_device_driver_unregister(sdrv.get()) };
96*99f59aa8SMarkus Probst     }
97*99f59aa8SMarkus Probst }
98*99f59aa8SMarkus Probst 
99*99f59aa8SMarkus Probst #[doc(hidden)]
100*99f59aa8SMarkus Probst #[pin_data(PinnedDrop)]
101*99f59aa8SMarkus Probst pub struct PrivateData<'bound, T: Driver> {
102*99f59aa8SMarkus Probst     sdev: &'bound Device<device::Bound>,
103*99f59aa8SMarkus Probst     #[pin]
104*99f59aa8SMarkus Probst     driver: UnsafeCell<MaybeUninit<T::Data<'bound>>>,
105*99f59aa8SMarkus Probst     open: UnsafeCell<bool>,
106*99f59aa8SMarkus Probst     /// Whether `receive_buf_callback` is allowed to call `Driver::receive`.
107*99f59aa8SMarkus Probst     ///
108*99f59aa8SMarkus Probst     /// If locked, the receive_buf_callback will be blocked on data reception.
109*99f59aa8SMarkus Probst     /// This is the case while the driver is being probed or while [`PrivateData`] is being dropped.
110*99f59aa8SMarkus Probst     /// This is necessary, because we need to open the serdev device before the driver has been
111*99f59aa8SMarkus Probst     /// probed in order to allow it to be configured, which allows `receive_buf_callback` to be
112*99f59aa8SMarkus Probst     /// called. Thus we need to block data until probe completes and the driver data becomes
113*99f59aa8SMarkus Probst     /// initialized.
114*99f59aa8SMarkus Probst     ///
115*99f59aa8SMarkus Probst     /// If unlocked and true, the receive_buf_callback will forward the data to
116*99f59aa8SMarkus Probst     /// `Driver::receive`. This is the normal state of operation.
117*99f59aa8SMarkus Probst     ///
118*99f59aa8SMarkus Probst     /// If unlocked and false, the receive_buf_callback will throw away the data.
119*99f59aa8SMarkus Probst     /// This is only the case, if the serdev device is open and
120*99f59aa8SMarkus Probst     /// - the driver returned an error in probe
121*99f59aa8SMarkus Probst     /// or
122*99f59aa8SMarkus Probst     /// - the driver data already has been dropped, because it was unbound.
123*99f59aa8SMarkus Probst     #[pin]
124*99f59aa8SMarkus Probst     active: Mutex<bool>,
125*99f59aa8SMarkus Probst }
126*99f59aa8SMarkus Probst 
127*99f59aa8SMarkus Probst #[pinned_drop]
128*99f59aa8SMarkus Probst impl<T: Driver> PinnedDrop for PrivateData<'_, T> {
129*99f59aa8SMarkus Probst     fn drop(self: Pin<&mut Self>) {
130*99f59aa8SMarkus Probst         let mut active = self.active.lock();
131*99f59aa8SMarkus Probst         if *active {
132*99f59aa8SMarkus Probst             // SAFETY:
133*99f59aa8SMarkus Probst             // - We have exclusive access to `self.driver`.
134*99f59aa8SMarkus Probst             // - `self.driver` is guaranteed to be initialized.
135*99f59aa8SMarkus Probst             unsafe { (*self.driver.get()).assume_init_drop() };
136*99f59aa8SMarkus Probst             *active = false;
137*99f59aa8SMarkus Probst         }
138*99f59aa8SMarkus Probst         drop(active);
139*99f59aa8SMarkus Probst 
140*99f59aa8SMarkus Probst         // SAFETY: We have exclusive access to `self.open`.
141*99f59aa8SMarkus Probst         if unsafe { *self.open.get() } {
142*99f59aa8SMarkus Probst             // SAFETY: `self.sdev.as_raw()` is guaranteed to be a pointer to a valid
143*99f59aa8SMarkus Probst             // `struct serdev_device`.
144*99f59aa8SMarkus Probst             unsafe { bindings::serdev_device_close(self.sdev.as_raw()) };
145*99f59aa8SMarkus Probst         }
146*99f59aa8SMarkus Probst     }
147*99f59aa8SMarkus Probst }
148*99f59aa8SMarkus Probst 
149*99f59aa8SMarkus Probst impl<T: Driver> Adapter<T> {
150*99f59aa8SMarkus Probst     const OPS: &'static bindings::serdev_device_ops = &bindings::serdev_device_ops {
151*99f59aa8SMarkus Probst         receive_buf: if T::HAS_RECEIVE {
152*99f59aa8SMarkus Probst             Some(Self::receive_buf_callback)
153*99f59aa8SMarkus Probst         } else {
154*99f59aa8SMarkus Probst             None
155*99f59aa8SMarkus Probst         },
156*99f59aa8SMarkus Probst         write_wakeup: Some(bindings::serdev_device_write_wakeup),
157*99f59aa8SMarkus Probst     };
158*99f59aa8SMarkus Probst 
159*99f59aa8SMarkus Probst     extern "C" fn probe_callback(sdev: *mut bindings::serdev_device) -> kernel::ffi::c_int {
160*99f59aa8SMarkus Probst         // SAFETY: The serial device bus only ever calls the probe callback with a valid pointer to
161*99f59aa8SMarkus Probst         // a `struct serdev_device`.
162*99f59aa8SMarkus Probst         //
163*99f59aa8SMarkus Probst         // INVARIANT: `sdev` is valid for the duration of `probe_callback()`.
164*99f59aa8SMarkus Probst         let sdev = unsafe { &*sdev.cast::<Device<device::CoreInternal<'_>>>() };
165*99f59aa8SMarkus Probst         let info = <Self as driver::Adapter>::id_info(sdev.as_ref());
166*99f59aa8SMarkus Probst 
167*99f59aa8SMarkus Probst         from_result(|| {
168*99f59aa8SMarkus Probst             sdev.as_ref().set_drvdata(try_pin_init!(PrivateData::<T> {
169*99f59aa8SMarkus Probst                 sdev: &**sdev,
170*99f59aa8SMarkus Probst                 driver: MaybeUninit::<T::Data<'_>>::zeroed().into(),
171*99f59aa8SMarkus Probst                 open: false.into(),
172*99f59aa8SMarkus Probst                 active <- new_mutex!(false),
173*99f59aa8SMarkus Probst             }))?;
174*99f59aa8SMarkus Probst             // SAFETY: We just set drvdata to `PrivateData<'_, T>`.
175*99f59aa8SMarkus Probst             let private_data = unsafe { sdev.as_ref().drvdata_borrow::<PrivateData<'_, T>>() };
176*99f59aa8SMarkus Probst             let private_data = ScopeGuard::new_with_data(private_data, |_| {
177*99f59aa8SMarkus Probst                 // SAFETY: We just set drvdata to `PrivateData<'_, T>`.
178*99f59aa8SMarkus Probst                 drop(unsafe { sdev.as_ref().drvdata_obtain::<PrivateData<'_, T>>() });
179*99f59aa8SMarkus Probst             });
180*99f59aa8SMarkus Probst             let mut active = private_data.active.lock();
181*99f59aa8SMarkus Probst 
182*99f59aa8SMarkus Probst             // SAFETY: `sdev.as_raw()` is guaranteed to be a valid pointer to `serdev_device`.
183*99f59aa8SMarkus Probst             unsafe { bindings::serdev_device_set_client_ops(sdev.as_raw(), Self::OPS) };
184*99f59aa8SMarkus Probst 
185*99f59aa8SMarkus Probst             // SAFETY: The serial device bus only ever calls the probe callback with a valid pointer
186*99f59aa8SMarkus Probst             // to a `serdev_device`.
187*99f59aa8SMarkus Probst             to_result(unsafe { bindings::serdev_device_open(sdev.as_raw()) })?;
188*99f59aa8SMarkus Probst 
189*99f59aa8SMarkus Probst             // SAFETY: We have exclusive access to `private_data.open`.
190*99f59aa8SMarkus Probst             unsafe { *private_data.open.get() = true };
191*99f59aa8SMarkus Probst 
192*99f59aa8SMarkus Probst             let data = T::probe(sdev, info);
193*99f59aa8SMarkus Probst 
194*99f59aa8SMarkus Probst             // SAFETY: We have exclusive access to `private_data.driver`.
195*99f59aa8SMarkus Probst             let driver = unsafe { &mut *private_data.driver.get() };
196*99f59aa8SMarkus Probst             // SAFETY:
197*99f59aa8SMarkus Probst             // - `driver.as_mut_ptr()` is a valid pointer to uninitialized data.
198*99f59aa8SMarkus Probst             // - `private_data.driver` is pinned.
199*99f59aa8SMarkus Probst             let result = unsafe { data.__pinned_init(driver.as_mut_ptr()) };
200*99f59aa8SMarkus Probst 
201*99f59aa8SMarkus Probst             *active = result.is_ok();
202*99f59aa8SMarkus Probst 
203*99f59aa8SMarkus Probst             drop(active);
204*99f59aa8SMarkus Probst 
205*99f59aa8SMarkus Probst             result.map(|()| {
206*99f59aa8SMarkus Probst                 private_data.dismiss();
207*99f59aa8SMarkus Probst                 0
208*99f59aa8SMarkus Probst             })
209*99f59aa8SMarkus Probst         })
210*99f59aa8SMarkus Probst     }
211*99f59aa8SMarkus Probst 
212*99f59aa8SMarkus Probst     extern "C" fn remove_callback(sdev: *mut bindings::serdev_device) {
213*99f59aa8SMarkus Probst         // SAFETY: The serial device bus only ever calls the remove callback with a valid pointer
214*99f59aa8SMarkus Probst         // to a `struct serdev_device`.
215*99f59aa8SMarkus Probst         //
216*99f59aa8SMarkus Probst         // INVARIANT: `sdev` is valid for the duration of `remove_callback()`.
217*99f59aa8SMarkus Probst         let sdev = unsafe { &*sdev.cast::<Device<device::CoreInternal<'_>>>() };
218*99f59aa8SMarkus Probst 
219*99f59aa8SMarkus Probst         // SAFETY: `remove_callback` is only ever called after a successful call to
220*99f59aa8SMarkus Probst         // `probe_callback`, hence it's guaranteed that `Device::set_drvdata()` has been called
221*99f59aa8SMarkus Probst         // and stored a `Pin<KBox<PrivateData<'_, T>>>`.
222*99f59aa8SMarkus Probst         let private_data = unsafe { sdev.as_ref().drvdata_borrow::<PrivateData<'_, T>>() };
223*99f59aa8SMarkus Probst 
224*99f59aa8SMarkus Probst         // SAFETY: No one has exclusive access to `private_data.driver`.
225*99f59aa8SMarkus Probst         let data = unsafe { &*private_data.driver.get() };
226*99f59aa8SMarkus Probst         // SAFETY:
227*99f59aa8SMarkus Probst         // - `private_data.driver` is pinned.
228*99f59aa8SMarkus Probst         // - `remove_callback` is only ever called after a successful call to `probe_callback`,
229*99f59aa8SMarkus Probst         //   hence it's guaranteed that `private_data.driver` was initialized.
230*99f59aa8SMarkus Probst         let data_pinned = unsafe { Pin::new_unchecked(data.assume_init_ref()) };
231*99f59aa8SMarkus Probst 
232*99f59aa8SMarkus Probst         T::unbind(sdev, data_pinned);
233*99f59aa8SMarkus Probst     }
234*99f59aa8SMarkus Probst 
235*99f59aa8SMarkus Probst     extern "C" fn receive_buf_callback(
236*99f59aa8SMarkus Probst         sdev: *mut bindings::serdev_device,
237*99f59aa8SMarkus Probst         buf: *const u8,
238*99f59aa8SMarkus Probst         length: usize,
239*99f59aa8SMarkus Probst     ) -> usize {
240*99f59aa8SMarkus Probst         // SAFETY: The serial device bus only ever calls the receive buf callback with a valid
241*99f59aa8SMarkus Probst         // pointer to a `struct serdev_device`.
242*99f59aa8SMarkus Probst         //
243*99f59aa8SMarkus Probst         // INVARIANT: `sdev` is valid for the duration of `receive_buf_callback()`.
244*99f59aa8SMarkus Probst         let sdev = unsafe { &*sdev.cast::<Device<device::BoundInternal>>() };
245*99f59aa8SMarkus Probst 
246*99f59aa8SMarkus Probst         // SAFETY: `receive_buf_callback` is only ever called after a successful call to
247*99f59aa8SMarkus Probst         // `probe_callback`, hence it's guaranteed that `Device::set_drvdata()` has been called
248*99f59aa8SMarkus Probst         // and stored a `Pin<KBox<PrivateData<'_, T>>>`.
249*99f59aa8SMarkus Probst         let private_data = unsafe { sdev.as_ref().drvdata_borrow::<PrivateData<'_, T>>() };
250*99f59aa8SMarkus Probst         let active = private_data.active.lock();
251*99f59aa8SMarkus Probst 
252*99f59aa8SMarkus Probst         if !*active {
253*99f59aa8SMarkus Probst             return length;
254*99f59aa8SMarkus Probst         }
255*99f59aa8SMarkus Probst 
256*99f59aa8SMarkus Probst         // SAFETY: No one has exclusive access to `private_data.driver`.
257*99f59aa8SMarkus Probst         let data = unsafe { &*private_data.driver.get() };
258*99f59aa8SMarkus Probst         // SAFETY:
259*99f59aa8SMarkus Probst         // - `private_data.driver` is pinned.
260*99f59aa8SMarkus Probst         // - `receive_buf_callback` is only ever called after a successful call to `probe_callback`,
261*99f59aa8SMarkus Probst         //   hence it's guaranteed that `private_data.driver` was initialized.
262*99f59aa8SMarkus Probst         let data_pinned = unsafe { Pin::new_unchecked(data.assume_init_ref()) };
263*99f59aa8SMarkus Probst 
264*99f59aa8SMarkus Probst         // SAFETY: `buf` is guaranteed to be non-null and has the size of `length`.
265*99f59aa8SMarkus Probst         let buf = unsafe { core::slice::from_raw_parts(buf, length) };
266*99f59aa8SMarkus Probst 
267*99f59aa8SMarkus Probst         T::receive(sdev, data_pinned, buf)
268*99f59aa8SMarkus Probst     }
269*99f59aa8SMarkus Probst }
270*99f59aa8SMarkus Probst 
271*99f59aa8SMarkus Probst impl<T: Driver> driver::Adapter for Adapter<T> {
272*99f59aa8SMarkus Probst     type IdInfo = T::IdInfo;
273*99f59aa8SMarkus Probst 
274*99f59aa8SMarkus Probst     fn of_id_table() -> Option<of::IdTable<Self::IdInfo>> {
275*99f59aa8SMarkus Probst         T::OF_ID_TABLE
276*99f59aa8SMarkus Probst     }
277*99f59aa8SMarkus Probst 
278*99f59aa8SMarkus Probst     fn acpi_id_table() -> Option<acpi::IdTable<Self::IdInfo>> {
279*99f59aa8SMarkus Probst         T::ACPI_ID_TABLE
280*99f59aa8SMarkus Probst     }
281*99f59aa8SMarkus Probst }
282*99f59aa8SMarkus Probst 
283*99f59aa8SMarkus Probst /// Declares a kernel module that exposes a single serial device bus device driver.
284*99f59aa8SMarkus Probst ///
285*99f59aa8SMarkus Probst /// # Examples
286*99f59aa8SMarkus Probst ///
287*99f59aa8SMarkus Probst /// ```ignore
288*99f59aa8SMarkus Probst /// kernel::module_serdev_device_driver! {
289*99f59aa8SMarkus Probst ///     type: MyDriver,
290*99f59aa8SMarkus Probst ///     name: "Module name",
291*99f59aa8SMarkus Probst ///     authors: ["Author name"],
292*99f59aa8SMarkus Probst ///     description: "Description",
293*99f59aa8SMarkus Probst ///     license: "GPL v2",
294*99f59aa8SMarkus Probst /// }
295*99f59aa8SMarkus Probst /// ```
296*99f59aa8SMarkus Probst #[macro_export]
297*99f59aa8SMarkus Probst macro_rules! module_serdev_device_driver {
298*99f59aa8SMarkus Probst     ($($f:tt)*) => {
299*99f59aa8SMarkus Probst         $crate::module_driver!(<T>, $crate::serdev::Adapter<T>, { $($f)* });
300*99f59aa8SMarkus Probst     };
301*99f59aa8SMarkus Probst }
302*99f59aa8SMarkus Probst 
303*99f59aa8SMarkus Probst /// The serial device bus device driver trait.
304*99f59aa8SMarkus Probst ///
305*99f59aa8SMarkus Probst /// Drivers must implement this trait in order to get a serial device bus device driver registered.
306*99f59aa8SMarkus Probst ///
307*99f59aa8SMarkus Probst /// # Examples
308*99f59aa8SMarkus Probst ///
309*99f59aa8SMarkus Probst ///```
310*99f59aa8SMarkus Probst /// # use kernel::{
311*99f59aa8SMarkus Probst ///     acpi,
312*99f59aa8SMarkus Probst ///     bindings,
313*99f59aa8SMarkus Probst ///     device::{
314*99f59aa8SMarkus Probst ///         Bound,
315*99f59aa8SMarkus Probst ///         Core, //
316*99f59aa8SMarkus Probst ///     },
317*99f59aa8SMarkus Probst ///     of,
318*99f59aa8SMarkus Probst ///     serdev, //
319*99f59aa8SMarkus Probst /// };
320*99f59aa8SMarkus Probst ///
321*99f59aa8SMarkus Probst /// struct MyDriver;
322*99f59aa8SMarkus Probst ///
323*99f59aa8SMarkus Probst /// kernel::of_device_table!(
324*99f59aa8SMarkus Probst ///     OF_TABLE,
325*99f59aa8SMarkus Probst ///     MODULE_OF_TABLE,
326*99f59aa8SMarkus Probst ///     <MyDriver as serdev::Driver>::IdInfo,
327*99f59aa8SMarkus Probst ///     [
328*99f59aa8SMarkus Probst ///         (of::DeviceId::new(c"test,device"), ())
329*99f59aa8SMarkus Probst ///     ]
330*99f59aa8SMarkus Probst /// );
331*99f59aa8SMarkus Probst ///
332*99f59aa8SMarkus Probst /// kernel::acpi_device_table!(
333*99f59aa8SMarkus Probst ///     ACPI_TABLE,
334*99f59aa8SMarkus Probst ///     MODULE_ACPI_TABLE,
335*99f59aa8SMarkus Probst ///     <MyDriver as serdev::Driver>::IdInfo,
336*99f59aa8SMarkus Probst ///     [
337*99f59aa8SMarkus Probst ///         (acpi::DeviceId::new(c"LNUXBEEF"), ())
338*99f59aa8SMarkus Probst ///     ]
339*99f59aa8SMarkus Probst /// );
340*99f59aa8SMarkus Probst ///
341*99f59aa8SMarkus Probst /// #[vtable]
342*99f59aa8SMarkus Probst /// impl serdev::Driver for MyDriver {
343*99f59aa8SMarkus Probst ///     type IdInfo = ();
344*99f59aa8SMarkus Probst ///     type Data<'bound> = Self;
345*99f59aa8SMarkus Probst ///     const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = Some(&OF_TABLE);
346*99f59aa8SMarkus Probst ///     const ACPI_ID_TABLE: Option<acpi::IdTable<Self::IdInfo>> = Some(&ACPI_TABLE);
347*99f59aa8SMarkus Probst ///
348*99f59aa8SMarkus Probst ///     fn probe<'bound>(
349*99f59aa8SMarkus Probst ///         sdev: &'bound serdev::Device<Core<'_>>,
350*99f59aa8SMarkus Probst ///         _id_info: Option<&'bound Self::IdInfo>,
351*99f59aa8SMarkus Probst ///     ) -> impl PinInit<Self::Data<'bound>, Error> + 'bound {
352*99f59aa8SMarkus Probst ///         sdev.set_baudrate(115200);
353*99f59aa8SMarkus Probst ///         sdev.write_all(b"Hello\n", 0)?;
354*99f59aa8SMarkus Probst ///         Ok(MyDriver)
355*99f59aa8SMarkus Probst ///     }
356*99f59aa8SMarkus Probst /// }
357*99f59aa8SMarkus Probst ///```
358*99f59aa8SMarkus Probst #[vtable]
359*99f59aa8SMarkus Probst pub trait Driver {
360*99f59aa8SMarkus Probst     /// The type holding driver private data about each device id supported by the driver.
361*99f59aa8SMarkus Probst     // TODO: Use associated_type_defaults once stabilized:
362*99f59aa8SMarkus Probst     //
363*99f59aa8SMarkus Probst     // ```
364*99f59aa8SMarkus Probst     // type IdInfo: 'static = ();
365*99f59aa8SMarkus Probst     // ```
366*99f59aa8SMarkus Probst     type IdInfo: 'static;
367*99f59aa8SMarkus Probst 
368*99f59aa8SMarkus Probst     /// The type of the driver's bus device private data.
369*99f59aa8SMarkus Probst     type Data<'bound>: Send + Sync + 'bound;
370*99f59aa8SMarkus Probst 
371*99f59aa8SMarkus Probst     /// The table of OF device ids supported by the driver.
372*99f59aa8SMarkus Probst     const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = None;
373*99f59aa8SMarkus Probst 
374*99f59aa8SMarkus Probst     /// The table of ACPI device ids supported by the driver.
375*99f59aa8SMarkus Probst     const ACPI_ID_TABLE: Option<acpi::IdTable<Self::IdInfo>> = None;
376*99f59aa8SMarkus Probst 
377*99f59aa8SMarkus Probst     /// Serial device bus device driver probe.
378*99f59aa8SMarkus Probst     ///
379*99f59aa8SMarkus Probst     /// Called when a new serial device bus device is added or discovered.
380*99f59aa8SMarkus Probst     /// Implementers should attempt to initialize the device here.
381*99f59aa8SMarkus Probst     fn probe<'bound>(
382*99f59aa8SMarkus Probst         sdev: &'bound Device<device::Core<'_>>,
383*99f59aa8SMarkus Probst         id_info: Option<&'bound Self::IdInfo>,
384*99f59aa8SMarkus Probst     ) -> impl PinInit<Self::Data<'bound>, Error> + 'bound;
385*99f59aa8SMarkus Probst 
386*99f59aa8SMarkus Probst     /// Serial device bus device driver unbind.
387*99f59aa8SMarkus Probst     ///
388*99f59aa8SMarkus Probst     /// Called when a [`Device`] is unbound from its bound [`Driver`]. Implementing this callback
389*99f59aa8SMarkus Probst     /// is optional.
390*99f59aa8SMarkus Probst     ///
391*99f59aa8SMarkus Probst     /// This callback serves as a place for drivers to perform teardown operations that require a
392*99f59aa8SMarkus Probst     /// `&Device<Core>` or `&Device<Bound>` reference. For instance.
393*99f59aa8SMarkus Probst     ///
394*99f59aa8SMarkus Probst     /// Otherwise, release operations for driver resources should be performed in `Drop`.
395*99f59aa8SMarkus Probst     fn unbind<'bound>(sdev: &'bound Device<device::Core<'_>>, this: Pin<&Self::Data<'bound>>) {
396*99f59aa8SMarkus Probst         let _ = (sdev, this);
397*99f59aa8SMarkus Probst     }
398*99f59aa8SMarkus Probst 
399*99f59aa8SMarkus Probst     /// Serial device bus device data receive callback.
400*99f59aa8SMarkus Probst     ///
401*99f59aa8SMarkus Probst     /// Called when data got received from device.
402*99f59aa8SMarkus Probst     ///
403*99f59aa8SMarkus Probst     /// Returns the number of bytes accepted.
404*99f59aa8SMarkus Probst     fn receive<'bound>(
405*99f59aa8SMarkus Probst         sdev: &'bound Device<device::Bound>,
406*99f59aa8SMarkus Probst         this: Pin<&Self::Data<'bound>>,
407*99f59aa8SMarkus Probst         data: &[u8],
408*99f59aa8SMarkus Probst     ) -> usize {
409*99f59aa8SMarkus Probst         let _ = (sdev, this, data);
410*99f59aa8SMarkus Probst         build_error!(VTABLE_DEFAULT_ERROR)
411*99f59aa8SMarkus Probst     }
412*99f59aa8SMarkus Probst }
413*99f59aa8SMarkus Probst 
414*99f59aa8SMarkus Probst /// The serial device bus device representation.
415*99f59aa8SMarkus Probst ///
416*99f59aa8SMarkus Probst /// This structure represents the Rust abstraction for a C `struct serdev_device`. The
417*99f59aa8SMarkus Probst /// implementation abstracts the usage of an already existing C `struct serdev_device` within Rust
418*99f59aa8SMarkus Probst /// code that we get passed from the C side.
419*99f59aa8SMarkus Probst ///
420*99f59aa8SMarkus Probst /// # Invariants
421*99f59aa8SMarkus Probst ///
422*99f59aa8SMarkus Probst /// A [`Device`] instance represents a valid `struct serdev_device` created by the C portion of
423*99f59aa8SMarkus Probst /// the kernel.
424*99f59aa8SMarkus Probst #[repr(transparent)]
425*99f59aa8SMarkus Probst pub struct Device<Ctx: device::DeviceContext = device::Normal>(
426*99f59aa8SMarkus Probst     Opaque<bindings::serdev_device>,
427*99f59aa8SMarkus Probst     PhantomData<Ctx>,
428*99f59aa8SMarkus Probst );
429*99f59aa8SMarkus Probst 
430*99f59aa8SMarkus Probst impl<Ctx: device::DeviceContext> Device<Ctx> {
431*99f59aa8SMarkus Probst     #[inline]
432*99f59aa8SMarkus Probst     fn as_raw(&self) -> *mut bindings::serdev_device {
433*99f59aa8SMarkus Probst         self.0.get()
434*99f59aa8SMarkus Probst     }
435*99f59aa8SMarkus Probst }
436*99f59aa8SMarkus Probst 
437*99f59aa8SMarkus Probst impl Device<device::Bound> {
438*99f59aa8SMarkus Probst     /// Set the baudrate in bits per second.
439*99f59aa8SMarkus Probst     ///
440*99f59aa8SMarkus Probst     /// Common baudrates are 115200, 9600, 19200, 57600, 4800.
441*99f59aa8SMarkus Probst     ///
442*99f59aa8SMarkus Probst     /// Use [`Device::write_flush`] before calling this if you have written data prior to this call.
443*99f59aa8SMarkus Probst     #[inline]
444*99f59aa8SMarkus Probst     pub fn set_baudrate(&self, speed: u32) -> Result<(), u32> {
445*99f59aa8SMarkus Probst         // SAFETY: `self.as_raw()` is guaranteed to be a pointer to a valid `serdev_device`.
446*99f59aa8SMarkus Probst         let ret = unsafe { bindings::serdev_device_set_baudrate(self.as_raw(), speed) };
447*99f59aa8SMarkus Probst         if ret == speed {
448*99f59aa8SMarkus Probst             Ok(())
449*99f59aa8SMarkus Probst         } else {
450*99f59aa8SMarkus Probst             Err(ret)
451*99f59aa8SMarkus Probst         }
452*99f59aa8SMarkus Probst     }
453*99f59aa8SMarkus Probst 
454*99f59aa8SMarkus Probst     /// Set if flow control should be enabled.
455*99f59aa8SMarkus Probst     ///
456*99f59aa8SMarkus Probst     /// Use [`Device::write_flush`] before calling this if you have written data prior to this call.
457*99f59aa8SMarkus Probst     #[inline]
458*99f59aa8SMarkus Probst     pub fn set_flow_control(&self, enable: bool) {
459*99f59aa8SMarkus Probst         // SAFETY: `self.as_raw()` is guaranteed to be a pointer to a valid `serdev_device`.
460*99f59aa8SMarkus Probst         unsafe { bindings::serdev_device_set_flow_control(self.as_raw(), enable) };
461*99f59aa8SMarkus Probst     }
462*99f59aa8SMarkus Probst 
463*99f59aa8SMarkus Probst     /// Set parity to use.
464*99f59aa8SMarkus Probst     ///
465*99f59aa8SMarkus Probst     /// Use [`Device::write_flush`] before calling this if you have written data prior to this call.
466*99f59aa8SMarkus Probst     #[inline]
467*99f59aa8SMarkus Probst     pub fn set_parity(&self, parity: Parity) -> Result {
468*99f59aa8SMarkus Probst         // SAFETY: `self.as_raw()` is guaranteed to be a pointer to a valid `serdev_device`.
469*99f59aa8SMarkus Probst         to_result(unsafe { bindings::serdev_device_set_parity(self.as_raw(), parity as u32) })
470*99f59aa8SMarkus Probst     }
471*99f59aa8SMarkus Probst 
472*99f59aa8SMarkus Probst     /// Write data to the serial device until the controller has accepted all the data or has
473*99f59aa8SMarkus Probst     /// been interrupted by a timeout or signal.
474*99f59aa8SMarkus Probst     ///
475*99f59aa8SMarkus Probst     /// Note that any accepted data has only been buffered by the controller. Use
476*99f59aa8SMarkus Probst     /// [`Device::wait_until_sent`] to make sure the controller write buffer has actually been
477*99f59aa8SMarkus Probst     /// emptied.
478*99f59aa8SMarkus Probst     ///
479*99f59aa8SMarkus Probst     /// Use a timeout of 0 to wait indefinitely.
480*99f59aa8SMarkus Probst     ///
481*99f59aa8SMarkus Probst     /// Returns the number of bytes written (less than `data.len()` if interrupted).
482*99f59aa8SMarkus Probst     /// [`kernel::error::code::ETIMEDOUT`] or [`kernel::error::code::ERESTARTSYS`] if interrupted
483*99f59aa8SMarkus Probst     /// before any bytes were written. [`kernel::error::code::EINVAL`] if `data.len() > i32::MAX`.
484*99f59aa8SMarkus Probst     #[inline]
485*99f59aa8SMarkus Probst     pub fn write_all(&self, data: &[u8], timeout: Jiffies) -> Result<usize> {
486*99f59aa8SMarkus Probst         if data.len() > i32::MAX as usize {
487*99f59aa8SMarkus Probst             return Err(EINVAL);
488*99f59aa8SMarkus Probst         }
489*99f59aa8SMarkus Probst 
490*99f59aa8SMarkus Probst         // SAFETY:
491*99f59aa8SMarkus Probst         // - `self.as_raw()` is guaranteed to be a pointer to a valid `serdev_device`.
492*99f59aa8SMarkus Probst         // - `data.as_ptr()` is guaranteed to be a valid array pointer with the size of
493*99f59aa8SMarkus Probst         //   `data.len()`.
494*99f59aa8SMarkus Probst         let ret = unsafe {
495*99f59aa8SMarkus Probst             bindings::serdev_device_write(
496*99f59aa8SMarkus Probst                 self.as_raw(),
497*99f59aa8SMarkus Probst                 data.as_ptr(),
498*99f59aa8SMarkus Probst                 data.len(),
499*99f59aa8SMarkus Probst                 isize::try_from(timeout).unwrap_or_default(),
500*99f59aa8SMarkus Probst             )
501*99f59aa8SMarkus Probst         };
502*99f59aa8SMarkus Probst         // CAST: negative return values are guaranteed to be between `-MAX_ERRNO` and `-1`,
503*99f59aa8SMarkus Probst         // which always fit into a `i32`.
504*99f59aa8SMarkus Probst         to_result(ret as i32).map(|()| ret.unsigned_abs())
505*99f59aa8SMarkus Probst     }
506*99f59aa8SMarkus Probst 
507*99f59aa8SMarkus Probst     /// Write data to the serial device.
508*99f59aa8SMarkus Probst     ///
509*99f59aa8SMarkus Probst     /// If you want to write until the controller has accepted all the data, use
510*99f59aa8SMarkus Probst     /// [`Device::write_all`].
511*99f59aa8SMarkus Probst     ///
512*99f59aa8SMarkus Probst     /// Note that any accepted data has only been buffered by the controller. Use
513*99f59aa8SMarkus Probst     /// [`Device::wait_until_sent`] to make sure the controller write buffer has actually been
514*99f59aa8SMarkus Probst     /// emptied.
515*99f59aa8SMarkus Probst     ///
516*99f59aa8SMarkus Probst     /// Returns the number of bytes written (less than `data.len()` if not enough room in the
517*99f59aa8SMarkus Probst     /// write buffer).
518*99f59aa8SMarkus Probst     #[inline]
519*99f59aa8SMarkus Probst     pub fn write(&self, data: &[u8]) -> Result<u32> {
520*99f59aa8SMarkus Probst         if data.len() > i32::MAX as usize {
521*99f59aa8SMarkus Probst             return Err(EINVAL);
522*99f59aa8SMarkus Probst         }
523*99f59aa8SMarkus Probst 
524*99f59aa8SMarkus Probst         // SAFETY:
525*99f59aa8SMarkus Probst         // - `self.as_raw()` is guaranteed to be a pointer to a valid `serdev_device`.
526*99f59aa8SMarkus Probst         // - `data.as_ptr()` is guaranteed to be a valid array pointer with the size of
527*99f59aa8SMarkus Probst         //   `data.len()`.
528*99f59aa8SMarkus Probst         let ret =
529*99f59aa8SMarkus Probst             unsafe { bindings::serdev_device_write_buf(self.as_raw(), data.as_ptr(), data.len()) };
530*99f59aa8SMarkus Probst 
531*99f59aa8SMarkus Probst         to_result(ret as i32).map(|()| ret.unsigned_abs())
532*99f59aa8SMarkus Probst     }
533*99f59aa8SMarkus Probst 
534*99f59aa8SMarkus Probst     /// Send data to the serial device immediately.
535*99f59aa8SMarkus Probst     ///
536*99f59aa8SMarkus Probst     /// Note that this doesn't guarantee that the data has been transmitted.
537*99f59aa8SMarkus Probst     /// Use [`Device::wait_until_sent`] for this purpose.
538*99f59aa8SMarkus Probst     #[inline]
539*99f59aa8SMarkus Probst     pub fn write_flush(&self) {
540*99f59aa8SMarkus Probst         // SAFETY: `self.as_raw()` is guaranteed to be a pointer to a valid `serdev_device`.
541*99f59aa8SMarkus Probst         unsafe { bindings::serdev_device_write_flush(self.as_raw()) };
542*99f59aa8SMarkus Probst     }
543*99f59aa8SMarkus Probst 
544*99f59aa8SMarkus Probst     /// Wait for the data to be sent.
545*99f59aa8SMarkus Probst     ///
546*99f59aa8SMarkus Probst     /// After this function, the write buffer of the controller should be empty or the timeout
547*99f59aa8SMarkus Probst     /// elapsed.
548*99f59aa8SMarkus Probst     ///
549*99f59aa8SMarkus Probst     /// Use a timeout of 0 to wait indefinitely.
550*99f59aa8SMarkus Probst     #[inline]
551*99f59aa8SMarkus Probst     pub fn wait_until_sent(&self, timeout: Jiffies) {
552*99f59aa8SMarkus Probst         // SAFETY: `self.as_raw()` is guaranteed to be a pointer to a valid `serdev_device`.
553*99f59aa8SMarkus Probst         unsafe {
554*99f59aa8SMarkus Probst             bindings::serdev_device_wait_until_sent(
555*99f59aa8SMarkus Probst                 self.as_raw(),
556*99f59aa8SMarkus Probst                 isize::try_from(timeout).unwrap_or_default(),
557*99f59aa8SMarkus Probst             )
558*99f59aa8SMarkus Probst         };
559*99f59aa8SMarkus Probst     }
560*99f59aa8SMarkus Probst }
561*99f59aa8SMarkus Probst 
562*99f59aa8SMarkus Probst // SAFETY: `serdev::Device` is a transparent wrapper of `struct serdev_device`.
563*99f59aa8SMarkus Probst // The offset is guaranteed to point to a valid device field inside `serdev::Device`.
564*99f59aa8SMarkus Probst unsafe impl<Ctx: device::DeviceContext> device::AsBusDevice<Ctx> for Device<Ctx> {
565*99f59aa8SMarkus Probst     const OFFSET: usize = offset_of!(bindings::serdev_device, dev);
566*99f59aa8SMarkus Probst }
567*99f59aa8SMarkus Probst 
568*99f59aa8SMarkus Probst // SAFETY: `Device` is a transparent wrapper of a type that doesn't depend on `Device`'s generic
569*99f59aa8SMarkus Probst // argument.
570*99f59aa8SMarkus Probst kernel::impl_device_context_deref!(unsafe { Device });
571*99f59aa8SMarkus Probst kernel::impl_device_context_into_aref!(Device);
572*99f59aa8SMarkus Probst 
573*99f59aa8SMarkus Probst // SAFETY: Instances of `Device` are always reference-counted.
574*99f59aa8SMarkus Probst unsafe impl AlwaysRefCounted for Device {
575*99f59aa8SMarkus Probst     fn inc_ref(&self) {
576*99f59aa8SMarkus Probst         self.as_ref().inc_ref();
577*99f59aa8SMarkus Probst     }
578*99f59aa8SMarkus Probst 
579*99f59aa8SMarkus Probst     unsafe fn dec_ref(obj: NonNull<Self>) {
580*99f59aa8SMarkus Probst         // SAFETY: The safety requirements guarantee that the refcount is non-zero.
581*99f59aa8SMarkus Probst         unsafe { bindings::serdev_device_put(obj.cast().as_ptr()) }
582*99f59aa8SMarkus Probst     }
583*99f59aa8SMarkus Probst }
584*99f59aa8SMarkus Probst 
585*99f59aa8SMarkus Probst impl<Ctx: device::DeviceContext> AsRef<device::Device<Ctx>> for Device<Ctx> {
586*99f59aa8SMarkus Probst     fn as_ref(&self) -> &device::Device<Ctx> {
587*99f59aa8SMarkus Probst         // SAFETY: By the type invariant of `Self`, `self.as_raw()` is a pointer to a valid
588*99f59aa8SMarkus Probst         // `struct serdev_device`.
589*99f59aa8SMarkus Probst         let dev = unsafe { &raw mut (*self.as_raw()).dev };
590*99f59aa8SMarkus Probst 
591*99f59aa8SMarkus Probst         // SAFETY: `dev` points to a valid `struct device`.
592*99f59aa8SMarkus Probst         unsafe { device::Device::from_raw(dev) }
593*99f59aa8SMarkus Probst     }
594*99f59aa8SMarkus Probst }
595*99f59aa8SMarkus Probst 
596*99f59aa8SMarkus Probst // SAFETY: A `Device` is always reference-counted and can be released from any thread.
597*99f59aa8SMarkus Probst unsafe impl Send for Device {}
598*99f59aa8SMarkus Probst 
599*99f59aa8SMarkus Probst // SAFETY: `Device` can be shared among threads because all methods of `Device`
600*99f59aa8SMarkus Probst // (i.e. `Device<Normal>) are thread safe.
601*99f59aa8SMarkus Probst unsafe impl Sync for Device {}
602*99f59aa8SMarkus Probst 
603*99f59aa8SMarkus Probst // SAFETY: Same as `Device<Normal>` -- the underlying `struct serdev_device` is the same;
604*99f59aa8SMarkus Probst // `Bound` is a zero-sized type-state marker that does not affect thread safety.
605*99f59aa8SMarkus Probst unsafe impl Sync for Device<device::Bound> {}
606