Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/samples/rust/rust_debugfs.rs
49086 views
1
// SPDX-License-Identifier: GPL-2.0
2
3
// Copyright (C) 2025 Google LLC.
4
5
//! Sample DebugFS exporting platform driver
6
//!
7
//! To successfully probe this driver with ACPI, use an ssdt that looks like
8
//!
9
//! ```dsl
10
//! DefinitionBlock ("", "SSDT", 2, "TEST", "VIRTACPI", 0x00000001)
11
//! {
12
//! Scope (\_SB)
13
//! {
14
//! Device (T432)
15
//! {
16
//! Name (_HID, "LNUXBEEF") // ACPI hardware ID to match
17
//! Name (_UID, 1)
18
//! Name (_STA, 0x0F) // Device present, enabled
19
//! Name (_DSD, Package () { // Sample attribute
20
//! ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
21
//! Package() {
22
//! Package(2) {"compatible", "sample-debugfs"}
23
//! }
24
//! })
25
//! Name (_CRS, ResourceTemplate ()
26
//! {
27
//! Memory32Fixed (ReadWrite, 0xFED00000, 0x1000)
28
//! })
29
//! }
30
//! }
31
//! }
32
//! ```
33
34
use core::str::FromStr;
35
use kernel::c_str;
36
use kernel::debugfs::{Dir, File};
37
use kernel::new_mutex;
38
use kernel::prelude::*;
39
use kernel::sizes::*;
40
use kernel::sync::atomic::{Atomic, Relaxed};
41
use kernel::sync::Mutex;
42
use kernel::{acpi, device::Core, of, platform, str::CString, types::ARef};
43
44
kernel::module_platform_driver! {
45
type: RustDebugFs,
46
name: "rust_debugfs",
47
authors: ["Matthew Maurer"],
48
description: "Rust DebugFS usage sample",
49
license: "GPL",
50
}
51
52
#[pin_data]
53
struct RustDebugFs {
54
pdev: ARef<platform::Device>,
55
// As we only hold these for drop effect (to remove the directory/files) we have a leading
56
// underscore to indicate to the compiler that we don't expect to use this field directly.
57
_debugfs: Dir,
58
#[pin]
59
_compatible: File<CString>,
60
#[pin]
61
counter: File<Atomic<usize>>,
62
#[pin]
63
inner: File<Mutex<Inner>>,
64
#[pin]
65
array_blob: File<Mutex<[u8; 4]>>,
66
#[pin]
67
vector_blob: File<Mutex<KVec<u8>>>,
68
}
69
70
#[derive(Debug)]
71
struct Inner {
72
x: u32,
73
y: u32,
74
}
75
76
impl FromStr for Inner {
77
type Err = Error;
78
fn from_str(s: &str) -> Result<Self> {
79
let mut parts = s.split_whitespace();
80
let x = parts
81
.next()
82
.ok_or(EINVAL)?
83
.parse::<u32>()
84
.map_err(|_| EINVAL)?;
85
let y = parts
86
.next()
87
.ok_or(EINVAL)?
88
.parse::<u32>()
89
.map_err(|_| EINVAL)?;
90
if parts.next().is_some() {
91
return Err(EINVAL);
92
}
93
Ok(Inner { x, y })
94
}
95
}
96
97
kernel::acpi_device_table!(
98
ACPI_TABLE,
99
MODULE_ACPI_TABLE,
100
<RustDebugFs as platform::Driver>::IdInfo,
101
[(acpi::DeviceId::new(c_str!("LNUXBEEF")), ())]
102
);
103
104
impl platform::Driver for RustDebugFs {
105
type IdInfo = ();
106
const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = None;
107
const ACPI_ID_TABLE: Option<acpi::IdTable<Self::IdInfo>> = Some(&ACPI_TABLE);
108
109
fn probe(
110
pdev: &platform::Device<Core>,
111
_info: Option<&Self::IdInfo>,
112
) -> impl PinInit<Self, Error> {
113
RustDebugFs::new(pdev).pin_chain(|this| {
114
this.counter.store(91, Relaxed);
115
{
116
let mut guard = this.inner.lock();
117
guard.x = guard.y;
118
guard.y = 42;
119
}
120
121
Ok(())
122
})
123
}
124
}
125
126
impl RustDebugFs {
127
fn build_counter(dir: &Dir) -> impl PinInit<File<Atomic<usize>>> + '_ {
128
dir.read_write_file(c_str!("counter"), Atomic::<usize>::new(0))
129
}
130
131
fn build_inner(dir: &Dir) -> impl PinInit<File<Mutex<Inner>>> + '_ {
132
dir.read_write_file(c_str!("pair"), new_mutex!(Inner { x: 3, y: 10 }))
133
}
134
135
fn new(pdev: &platform::Device<Core>) -> impl PinInit<Self, Error> + '_ {
136
let debugfs = Dir::new(c_str!("sample_debugfs"));
137
let dev = pdev.as_ref();
138
139
try_pin_init! {
140
Self {
141
_compatible <- debugfs.read_only_file(
142
c_str!("compatible"),
143
dev.fwnode()
144
.ok_or(ENOENT)?
145
.property_read::<CString>(c_str!("compatible"))
146
.required_by(dev)?,
147
),
148
counter <- Self::build_counter(&debugfs),
149
inner <- Self::build_inner(&debugfs),
150
array_blob <- debugfs.read_write_binary_file(
151
c_str!("array_blob"),
152
new_mutex!([0x62, 0x6c, 0x6f, 0x62]),
153
),
154
vector_blob <- debugfs.read_write_binary_file(
155
c_str!("vector_blob"),
156
new_mutex!(kernel::kvec!(0x42; SZ_4K)?),
157
),
158
_debugfs: debugfs,
159
pdev: pdev.into(),
160
}
161
}
162
}
163
}
164
165