Skip to content

Commit 3efcd05

Browse files
committed
IMPORT: rust: port of api from 'rust' branch
Signed-off-by: Fabien Parent <[email protected]>
1 parent 1961e0a commit 3efcd05

File tree

3 files changed

+72
-0
lines changed

3 files changed

+72
-0
lines changed

rust/helpers.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include <linux/err.h>
2828
#include <linux/errname.h>
2929
#include <linux/mutex.h>
30+
#include <linux/of_device.h>
3031
#include <linux/refcount.h>
3132
#include <linux/sched/signal.h>
3233
#include <linux/spinlock.h>
@@ -170,6 +171,13 @@ const char *rust_helper_dev_name(const struct device *dev)
170171
}
171172
EXPORT_SYMBOL_GPL(rust_helper_dev_name);
172173

174+
const struct of_device_id *rust_helper_of_match_device(
175+
const struct of_device_id *matches, const struct device *dev)
176+
{
177+
return of_match_device(matches, dev);
178+
}
179+
EXPORT_SYMBOL_GPL(rust_helper_of_match_device);
180+
173181
/*
174182
* `bindgen` binds the C `size_t` type as the Rust `usize` type, so we can
175183
* use it in contexts where Rust expects a `usize` like slice (array) indices.

rust/kernel/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ pub mod ioctl;
4343
pub mod io_pgtable;
4444
#[cfg(CONFIG_KUNIT)]
4545
pub mod kunit;
46+
pub mod of;
4647
pub mod prelude;
4748
pub mod print;
4849
mod static_assert;

rust/kernel/of.rs

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
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::{bindings, driver, str::BStr};
8+
9+
/// An open firmware device id.
10+
#[derive(Clone, Copy)]
11+
pub enum DeviceId {
12+
/// An open firmware device id where only a compatible string is specified.
13+
Compatible(&'static BStr),
14+
}
15+
16+
/// Defines a const open firmware device id table that also carries per-entry data/context/info.
17+
///
18+
/// The name of the const is `OF_DEVICE_ID_TABLE`, which is what buses are expected to name their
19+
/// open firmware tables.
20+
///
21+
/// # Examples
22+
///
23+
/// ```
24+
/// # use kernel::define_of_id_table;
25+
/// use kernel::of;
26+
///
27+
/// define_of_id_table! {u32, [
28+
/// (of::DeviceId::Compatible(b"test-device1,test-device2"), Some(0xff)),
29+
/// (of::DeviceId::Compatible(b"test-device3"), None),
30+
/// ]};
31+
/// ```
32+
#[macro_export]
33+
macro_rules! define_of_id_table {
34+
($data_type:ty, $($t:tt)*) => {
35+
$crate::define_id_table!(OF_DEVICE_ID_TABLE, $crate::of::DeviceId, $data_type, $($t)*);
36+
};
37+
}
38+
39+
// SAFETY: `ZERO` is all zeroed-out and `to_rawid` stores `offset` in `of_device_id::data`.
40+
unsafe impl const driver::RawDeviceId for DeviceId {
41+
type RawType = bindings::of_device_id;
42+
const ZERO: Self::RawType = bindings::of_device_id {
43+
name: [0; 32],
44+
type_: [0; 32],
45+
compatible: [0; 128],
46+
data: core::ptr::null(),
47+
};
48+
49+
fn to_rawid(&self, offset: isize) -> Self::RawType {
50+
let DeviceId::Compatible(compatible) = self;
51+
let mut id = Self::ZERO;
52+
let mut i = 0;
53+
while i < compatible.len() {
54+
// If `compatible` does not fit in `id.compatible`, an "index out of bounds" build time
55+
// error will be triggered.
56+
id.compatible[i] = compatible[i] as _;
57+
i += 1;
58+
}
59+
id.compatible[i] = b'\0' as _;
60+
id.data = offset as _;
61+
id
62+
}
63+
}

0 commit comments

Comments
 (0)