Skip to content

Commit bbe3b4d

Browse files
Danilo Krummrichgregkh
authored andcommitted
rust: of: add of::DeviceId abstraction
`of::DeviceId` is an abstraction around `struct of_device_id`. This is used by subsequent patches, in particular the platform bus abstractions, to create OF device ID tables. Reviewed-by: Rob Herring (Arm) <[email protected]> Signed-off-by: Danilo Krummrich <[email protected]> Tested-by: Dirk Behme <[email protected]> Tested-by: Fabien Parent <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 685376d commit bbe3b4d

File tree

3 files changed

+62
-0
lines changed

3 files changed

+62
-0
lines changed

MAINTAINERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17505,6 +17505,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git
1750517505
F: Documentation/ABI/testing/sysfs-firmware-ofw
1750617506
F: drivers/of/
1750717507
F: include/linux/of*.h
17508+
F: rust/kernel/of.rs
1750817509
F: scripts/dtc/
1750917510
F: tools/testing/selftests/dt/
1751017511
K: of_overlay_notifier_

rust/kernel/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ pub mod list;
5656
pub mod miscdevice;
5757
#[cfg(CONFIG_NET)]
5858
pub mod net;
59+
pub mod of;
5960
pub mod page;
6061
pub mod pid_namespace;
6162
pub mod prelude;

rust/kernel/of.rs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
3+
//! Device Tree / Open Firmware abstractions.
4+
5+
use crate::{bindings, device_id::RawDeviceId, prelude::*};
6+
7+
/// IdTable type for OF drivers.
8+
pub type IdTable<T> = &'static dyn kernel::device_id::IdTable<DeviceId, T>;
9+
10+
/// An open firmware device id.
11+
#[repr(transparent)]
12+
#[derive(Clone, Copy)]
13+
pub struct DeviceId(bindings::of_device_id);
14+
15+
// SAFETY:
16+
// * `DeviceId` is a `#[repr(transparent)` wrapper of `struct of_device_id` and does not add
17+
// additional invariants, so it's safe to transmute to `RawType`.
18+
// * `DRIVER_DATA_OFFSET` is the offset to the `data` field.
19+
unsafe impl RawDeviceId for DeviceId {
20+
type RawType = bindings::of_device_id;
21+
22+
const DRIVER_DATA_OFFSET: usize = core::mem::offset_of!(bindings::of_device_id, data);
23+
24+
fn index(&self) -> usize {
25+
self.0.data as _
26+
}
27+
}
28+
29+
impl DeviceId {
30+
/// Create a new device id from an OF 'compatible' string.
31+
pub const fn new(compatible: &'static CStr) -> Self {
32+
let src = compatible.as_bytes_with_nul();
33+
// Replace with `bindings::of_device_id::default()` once stabilized for `const`.
34+
// SAFETY: FFI type is valid to be zero-initialized.
35+
let mut of: bindings::of_device_id = unsafe { core::mem::zeroed() };
36+
37+
// TODO: Use `clone_from_slice` once the corresponding types do match.
38+
let mut i = 0;
39+
while i < src.len() {
40+
of.compatible[i] = src[i] as _;
41+
i += 1;
42+
}
43+
44+
Self(of)
45+
}
46+
}
47+
48+
/// Create an OF `IdTable` with an "alias" for modpost.
49+
#[macro_export]
50+
macro_rules! of_device_table {
51+
($table_name:ident, $module_table_name:ident, $id_info_type: ty, $table_data: expr) => {
52+
const $table_name: $crate::device_id::IdArray<
53+
$crate::of::DeviceId,
54+
$id_info_type,
55+
{ $table_data.len() },
56+
> = $crate::device_id::IdArray::new($table_data);
57+
58+
$crate::module_device_table!("of", $module_table_name, $table_name);
59+
};
60+
}

0 commit comments

Comments
 (0)