Skip to content

Commit cf0351f

Browse files
Sven Van AsbroeckFabo
authored andcommitted
rust: add basic OF abstraction
Co-developed-by: Wedson Almeida Filho <[email protected]> Signed-off-by: Wedson Almeida Filho <[email protected]> Signed-off-by: Sven Van Asbroeck <[email protected]> Signed-off-by: Fabien Parent <[email protected]>
1 parent 2282cba commit cf0351f

File tree

2 files changed

+58
-0
lines changed

2 files changed

+58
-0
lines changed

rust/kernel/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ pub mod kunit;
5151
pub mod list;
5252
#[cfg(CONFIG_NET)]
5353
pub mod net;
54+
pub mod of;
5455
pub mod page;
5556
pub mod prelude;
5657
pub mod print;

rust/kernel/of.rs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
3+
//! Devicetree and Open Firmware abstractions.
4+
//!
5+
//! C header: [`include/linux/of_*.h`](../../../../include/linux/of_*.h)
6+
7+
use crate::{
8+
bindings, device_id,
9+
str::{BStr, CStr},
10+
};
11+
12+
/// An open firmware device id.
13+
#[repr(transparent)]
14+
#[derive(Clone, Copy)]
15+
pub struct DeviceId(bindings::of_device_id);
16+
17+
impl DeviceId {
18+
/// Create a OF `DeviceId` from a compatible string.
19+
pub const fn with_compatible(compatible: &CStr) -> Self {
20+
let device_id = core::mem::MaybeUninit::<bindings::of_device_id>::zeroed();
21+
let mut device_id = unsafe { device_id.assume_init() };
22+
23+
let compatible = BStr::from_bytes(compatible.as_bytes_with_nul());
24+
assert!(compatible.len() <= device_id.compatible.len());
25+
26+
let mut i = 0;
27+
while i < compatible.len() {
28+
device_id.compatible[i] = compatible.deref_const()[i] as _;
29+
i += 1;
30+
}
31+
32+
Self(device_id)
33+
}
34+
}
35+
36+
// SAFETY: `ZERO` is all zeroed-out and `to_rawid` stores `offset` in `of_device_id::data`.
37+
unsafe impl device_id::RawDeviceId for DeviceId {
38+
type RawType = bindings::of_device_id;
39+
const DRIVER_DATA_OFFSET: usize = core::mem::offset_of!(bindings::of_device_id, data);
40+
}
41+
42+
/// Alias for `device_id::IdTable` containing OF's `DeviceId`
43+
pub type IdTable<T> = &'static dyn device_id::IdTable<DeviceId, T>;
44+
45+
/// Create an OF `IdTable` with its alias for modpost.
46+
#[macro_export]
47+
macro_rules! of_device_table {
48+
($module_table_name:ident, $table_name:ident, $id_info_type: ty, $table_data: expr) => {
49+
const $table_name: $crate::device_id::IdArray<
50+
$crate::of::DeviceId,
51+
$id_info_type,
52+
{ $table_data.len() },
53+
> = $crate::device_id::IdArray::new($table_data);
54+
55+
$crate::module_device_table!("of", $module_table_name, $table_name);
56+
};
57+
}

0 commit comments

Comments
 (0)