projects/linux·blob uaccess-cleanups · refs

88 lines · 2.1 KiB

1// SPDX-License-Identifier: GPL-2.0
2
3//! Rust Serial device bus device driver sample.
4
5use kernel::{
6 acpi,
7 device::{
8 Bound,
9 Core, //
10 },
11 of,
12 prelude::*,
13 serdev,
14 sync::aref::ARef, //
15};
16
17struct SampleDriver {
18 sdev: ARef<serdev::Device>,
19}
20
21kernel::of_device_table!(
22 OF_TABLE,
23 <SampleDriver as serdev::Driver>::IdInfo,
24 [(of::DeviceId::new(c"test,rust_driver_serdev"), ())]
25);
26
27kernel::acpi_device_table!(
28 ACPI_TABLE,
29 <SampleDriver as serdev::Driver>::IdInfo,
30 [(acpi::DeviceId::new(c"LNUXBEEF"), ())]
31);
32
33#[vtable]
34impl serdev::Driver for SampleDriver {
35 type IdInfo = ();
36 type Data<'bound> = Self;
37 const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = Some(&OF_TABLE);
38 const ACPI_ID_TABLE: Option<acpi::IdTable<Self::IdInfo>> = Some(&ACPI_TABLE);
39
40 fn probe<'bound>(
41 sdev: &'bound serdev::Device<Core<'_>>,
42 _info: Option<&'bound Self::IdInfo>,
43 ) -> impl PinInit<Self, Error> + 'bound {
44 let dev = sdev.as_ref();
45
46 dev_dbg!(dev, "Probe Rust Serial device bus device driver sample.\n");
47
48 if sdev
49 .set_baudrate(
50 dev.fwnode()
51 .and_then(|fwnode| fwnode.property_read(c"baudrate").optional())
52 .unwrap_or(115200),
53 )
54 .is_err()
55 {
56 return Err(EINVAL);
57 }
58 sdev.set_flow_control(false);
59 sdev.set_parity(serdev::Parity::None)?;
60
61 Ok(Self { sdev: sdev.into() })
62 }
63
64 fn receive<'bound>(
65 sdev: &'bound serdev::Device<Bound>,
66 _this: Pin<&Self>,
67 data: &[u8],
68 ) -> usize {
69 sdev.write(data).unwrap_or_default() as usize
70 }
71}
72
73impl Drop for SampleDriver {
74 fn drop(&mut self) {
75 dev_dbg!(
76 self.sdev.as_ref(),
77 "Remove Rust Serial device bus device driver sample.\n"
78 );
79 }
80}
81
82kernel::module_serdev_device_driver! {
83 type: SampleDriver,
84 name: "rust_driver_serdev",
85 authors: ["Markus Probst"],
86 description: "Rust Serial device bus device driver",
87 license: "GPL v2",
88}