Skip to content

Commit 97668ff

Browse files
authored
Merge pull request raspberrypi#618 from wedsonaf/platform
rust: convert `platform` to use `driver`
2 parents efbcb28 + 2caae00 commit 97668ff

File tree

11 files changed

+356
-334
lines changed

11 files changed

+356
-334
lines changed

drivers/char/hw_random/bcm2835_rng_rust.rs

Lines changed: 27 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@
66
#![feature(allocator_api, global_asm)]
77

88
use kernel::{
9-
c_str, file::File, file_operations::FileOperations, io_buffer::IoBufferWriter, miscdev,
10-
of::ConstOfMatchTable, platform, platform::PlatformDriver, prelude::*,
9+
c_str, device, file::File, file_operations::FileOperations, io_buffer::IoBufferWriter, miscdev,
10+
module_platform_driver, of, platform, prelude::*, sync::Ref,
1111
};
1212

13-
module! {
14-
type: RngModule,
13+
module_platform_driver! {
14+
type: RngDriver,
1515
name: b"bcm2835_rng_rust",
1616
author: b"Rust for Linux Contributors",
1717
description: b"BCM2835 Random Number Generator (RNG) driver",
@@ -38,35 +38,29 @@ impl FileOperations for RngDevice {
3838
}
3939
}
4040

41-
struct RngDriver;
42-
43-
impl PlatformDriver for RngDriver {
44-
type DrvData = Pin<Box<miscdev::Registration<RngDevice>>>;
45-
46-
fn probe(device_id: i32) -> Result<Self::DrvData> {
47-
pr_info!("probing discovered hwrng with id {}\n", device_id);
48-
let drv_data = miscdev::Registration::new_pinned(c_str!("rust_hwrng"), None, ())?;
49-
Ok(drv_data)
50-
}
41+
type DeviceData = device::Data<miscdev::Registration<RngDevice>, (), ()>;
5142

52-
fn remove(device_id: i32, _drv_data: Self::DrvData) -> Result {
53-
pr_info!("removing hwrng with id {}\n", device_id);
54-
Ok(())
55-
}
56-
}
57-
58-
struct RngModule {
59-
_pdev: Pin<Box<platform::Registration>>,
60-
}
61-
62-
impl KernelModule for RngModule {
63-
fn init(name: &'static CStr, module: &'static ThisModule) -> Result<Self> {
64-
const OF_MATCH_TBL: ConstOfMatchTable<1> =
65-
ConstOfMatchTable::new_const([c_str!("brcm,bcm2835-rng")]);
66-
67-
let pdev =
68-
platform::Registration::new_pinned::<RngDriver>(name, Some(&OF_MATCH_TBL), module)?;
69-
70-
Ok(RngModule { _pdev: pdev })
43+
struct RngDriver;
44+
impl platform::Driver for RngDriver {
45+
type Data = Ref<DeviceData>;
46+
47+
kernel::define_of_id_table! {(), [
48+
(of::DeviceId::Compatible(b"brcm,bcm2835-rng"), None),
49+
]}
50+
51+
fn probe(dev: &mut platform::Device, _id_info: Option<&Self::IdInfo>) -> Result<Self::Data> {
52+
pr_info!("probing discovered hwrng with id {}\n", dev.id());
53+
let data = kernel::new_device_data!(
54+
miscdev::Registration::new(),
55+
(),
56+
(),
57+
"BCM2835::Registrations"
58+
)?;
59+
60+
data.registrations()
61+
.ok_or(Error::ENXIO)?
62+
.as_pinned_mut()
63+
.register(c_str!("rust_hwrng"), None, ())?;
64+
Ok(data.into())
7165
}
7266
}

drivers/gpio/gpio_pl061_rust.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
#![feature(global_asm, allocator_api)]
99

1010
use kernel::{
11-
amba, bit, bits_iter, declare_amba_id_table, device, gpio,
11+
amba, bit, bits_iter, define_amba_id_table, device, gpio,
1212
io_mem::IoMem,
1313
irq::{self, ExtraResult, IrqData, LockedIrqData},
1414
power,
@@ -261,11 +261,11 @@ impl amba::Driver for PL061Device {
261261
type Data = Ref<DeviceData>;
262262
type PowerOps = Self;
263263

264-
declare_amba_id_table! [
265-
{ id: 0x00041061, mask: 0x000fffff, data: () },
266-
];
264+
define_amba_id_table! {(), [
265+
({id: 0x00041061, mask: 0x000fffff}, None),
266+
]}
267267

268-
fn probe(dev: &mut amba::Device, _id: &amba::DeviceId) -> Result<Ref<DeviceData>> {
268+
fn probe(dev: &mut amba::Device, _data: Option<&Self::IdInfo>) -> Result<Ref<DeviceData>> {
269269
let res = dev.take_resource().ok_or(Error::ENXIO)?;
270270
let irq = dev.irq(0).ok_or(Error::ENXIO)?;
271271

rust/helpers.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <linux/irqchip/chained_irq.h>
1818
#include <linux/irqdomain.h>
1919
#include <linux/amba/bus.h>
20+
#include <linux/of_device.h>
2021

2122
__noreturn void rust_helper_BUG(void)
2223
{
@@ -477,6 +478,13 @@ void rust_helper_put_cred(const struct cred *cred) {
477478
}
478479
EXPORT_SYMBOL_GPL(rust_helper_put_cred);
479480

481+
const struct of_device_id *rust_helper_of_match_device(
482+
const struct of_device_id *matches, const struct device *dev)
483+
{
484+
return of_match_device(matches, dev);
485+
}
486+
EXPORT_SYMBOL_GPL(rust_helper_of_match_device);
487+
480488
/* We use bindgen's --size_t-is-usize option to bind the C size_t type
481489
* as the Rust usize type, so we can use it in contexts where Rust
482490
* expects a usize like slice (array) indices. usize is defined to be

rust/kernel/amba.rs

Lines changed: 54 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,43 @@
11
// SPDX-License-Identifier: GPL-2.0
22

3-
//! Amba devices drivers.
3+
//! Amba devices and drivers.
44
//!
55
//! C header: [`include/linux/amba/bus.h`](../../../../include/linux/amba/bus.h)
66
77
use crate::{
88
bindings, c_types, device, driver, error::from_kernel_result, io_mem::Resource, power,
9-
str::CStr, to_result, types::PointerWrapper, Error, Result, ThisModule,
9+
str::CStr, to_result, types::PointerWrapper, Result, ThisModule,
1010
};
1111

1212
/// A registration of an amba driver.
1313
pub type Registration<T> = driver::Registration<Adapter<T>>;
1414

1515
/// Id of an Amba device.
16-
pub struct DeviceId<T = ()> {
16+
#[derive(Clone, Copy)]
17+
pub struct DeviceId {
1718
/// Device id.
1819
pub id: u32,
1920

2021
/// Mask that identifies which bits are valid in the device id.
2122
pub mask: u32,
23+
}
24+
25+
// SAFETY: `ZERO` is all zeroed-out and `to_rawid` stores `offset` in `amba_id::data`.
26+
unsafe impl const driver::RawDeviceId for DeviceId {
27+
type RawType = bindings::amba_id;
28+
const ZERO: Self::RawType = bindings::amba_id {
29+
id: 0,
30+
mask: 0,
31+
data: core::ptr::null_mut(),
32+
};
2233

23-
/// Context data to be associated with the device id. This is carried over to [`Driver::probe`]
24-
/// so that drivers can encode any information they may need then.
25-
pub data: T,
34+
fn to_rawid(&self, offset: isize) -> Self::RawType {
35+
bindings::amba_id {
36+
id: self.id,
37+
mask: self.mask,
38+
data: offset as _,
39+
}
40+
}
2641
}
2742

2843
/// An amba driver.
@@ -39,11 +54,11 @@ pub trait Driver {
3954
/// The type holding information about each device id supported by the driver.
4055
type IdInfo: 'static = ();
4156

42-
/// The table of device ids supported by the drivers.
43-
const ID_TABLE: &'static [DeviceId<Self::IdInfo>];
57+
/// The table of device ids supported by the driver.
58+
const ID_TABLE: Option<driver::IdTable<'static, DeviceId, Self::IdInfo>> = None;
4459

4560
/// Probes for the device with the given id.
46-
fn probe(dev: &mut Device, id: &DeviceId<Self::IdInfo>) -> Result<Self::Data>;
61+
fn probe(dev: &mut Device, id_info: Option<&Self::IdInfo>) -> Result<Self::Data>;
4762

4863
/// Cleans any resources up that are associated with the device.
4964
///
@@ -56,24 +71,22 @@ pub struct Adapter<T: Driver>(T);
5671

5772
impl<T: Driver> driver::DriverOps for Adapter<T> {
5873
type RegType = bindings::amba_driver;
59-
type RawIdType = bindings::amba_id;
60-
type IdType = DeviceId<T::IdInfo>;
61-
const ID_TABLE: &'static [Self::IdType] = T::ID_TABLE;
6274

6375
unsafe fn register(
6476
reg: *mut bindings::amba_driver,
6577
name: &'static CStr,
6678
module: &'static ThisModule,
67-
id_table: *const bindings::amba_id,
6879
) -> Result {
6980
// SAFETY: By the safety requirements of this function (defined in the trait defintion),
7081
// `reg` is non-null and valid.
7182
let amba = unsafe { &mut *reg };
7283
amba.drv.name = name.as_char_ptr();
7384
amba.drv.owner = module.0;
74-
amba.id_table = id_table;
7585
amba.probe = Some(probe_callback::<T>);
7686
amba.remove = Some(remove_callback::<T>);
87+
if let Some(t) = T::ID_TABLE {
88+
amba.id_table = t.as_ref();
89+
}
7790
if cfg!(CONFIG_PM) {
7891
// SAFETY: `probe_callback` sets the driver data after calling `T::Data::into_pointer`,
7992
// and we guarantee that `T::Data` is the same as `T::PowerOps::Data` by a constraint
@@ -90,14 +103,6 @@ impl<T: Driver> driver::DriverOps for Adapter<T> {
90103
// `reg` was passed (and updated) by a previous successful call to `amba_driver_register`.
91104
unsafe { bindings::amba_driver_unregister(reg) };
92105
}
93-
94-
fn to_raw_id(index: usize, id: &Self::IdType) -> Self::RawIdType {
95-
bindings::amba_id {
96-
id: id.id,
97-
mask: id.mask,
98-
data: index as _,
99-
}
100-
}
101106
}
102107

103108
unsafe extern "C" fn probe_callback<T: Driver>(
@@ -109,11 +114,18 @@ unsafe extern "C" fn probe_callback<T: Driver>(
109114
// duration of this call, so it is guaranteed to remain alive for the lifetime of `dev`.
110115
let mut dev = unsafe { Device::from_ptr(adev) };
111116
// SAFETY: `aid` is valid by the requirements the contract with the C code.
112-
let index = unsafe { (*aid).data } as usize;
113-
if index >= T::ID_TABLE.len() {
114-
return Err(Error::ENXIO);
115-
}
116-
let data = T::probe(&mut dev, &T::ID_TABLE[index])?;
117+
let offset = unsafe { (*aid).data };
118+
let info = if offset.is_null() {
119+
None
120+
} else {
121+
// SAFETY: The offset comes from a previous call to `offset_from` in `IdArray::new`,
122+
// which guarantees that the resulting pointer is within the table.
123+
let ptr = unsafe { aid.cast::<u8>().offset(offset as _).cast::<Option<T::IdInfo>>() };
124+
// SAFETY: The id table has a static lifetime, so `ptr` is guaranteed to be valid for
125+
// read.
126+
unsafe { (&*ptr).as_ref() }
127+
};
128+
let data = T::probe(&mut dev, info)?;
117129
let ptr = T::Data::into_pointer(data);
118130
// SAFETY: `adev` is valid for write by the contract with the C code.
119131
unsafe { bindings::amba_set_drvdata(adev, ptr as _) };
@@ -193,17 +205,17 @@ unsafe impl device::RawDevice for Device {
193205
///
194206
/// ```ignore
195207
/// # use kernel::prelude::*;
196-
/// # use kernel::{amba, declare_amba_id_table, module_amba_driver};
208+
/// # use kernel::{amba, define_amba_id_table, module_amba_driver};
197209
/// #
198210
/// struct MyDriver;
199211
/// impl amba::Driver for MyDriver {
200212
/// // [...]
201-
/// # fn probe(_dev: &mut amba::Device, _id: &amba::DeviceId<Self::IdInfo>) -> Result {
213+
/// # fn probe(_dev: &mut amba::Device, _id: Option<&Self::IdInfo>) -> Result {
202214
/// # Ok(())
203215
/// # }
204-
/// # declare_amba_id_table! [
205-
/// # { id: 0x00041061, mask: 0x000fffff, data: () },
206-
/// # ];
216+
/// # define_amba_id_table! {(), [
217+
/// # ({ id: 0x00041061, mask: 0x000fffff }, None),
218+
/// # ]}
207219
/// }
208220
///
209221
/// module_amba_driver! {
@@ -220,34 +232,28 @@ macro_rules! module_amba_driver {
220232
};
221233
}
222234

223-
/// Declares the id table for amba devices.
235+
/// Defines the id table for amba devices.
224236
///
225237
/// # Examples
226238
///
227239
/// ```
228240
/// # use kernel::prelude::*;
229-
/// # use kernel::{amba, declare_amba_id_table};
241+
/// # use kernel::{amba, define_amba_id_table};
230242
/// #
231243
/// # struct Sample;
232244
/// # impl kernel::amba::Driver for Sample {
233-
/// # fn probe(_dev: &mut amba::Device, _id: &amba::DeviceId<Self::IdInfo>) -> Result {
245+
/// # fn probe(_dev: &mut amba::Device, _id: Option<&Self::IdInfo>) -> Result {
234246
/// # Ok(())
235247
/// # }
236-
/// declare_amba_id_table! [
237-
/// { id: 0x00041061, mask: 0x000fffff, data: () },
238-
/// ];
248+
/// define_amba_id_table! {(), [
249+
/// ({ id: 0x00041061, mask: 0x000fffff }, None),
250+
/// ]}
239251
/// # }
240252
/// ```
241253
#[macro_export]
242-
macro_rules! declare_amba_id_table {
243-
($({$($entry:tt)*},)*) => {
244-
const ID_TABLE: &'static [$crate::amba::DeviceId<Self::IdInfo>] = &[
245-
$( $crate::amba::DeviceId { $($entry)* },)*
246-
];
254+
macro_rules! define_amba_id_table {
255+
($data_type:ty, $($t:tt)*) => {
256+
type IdInfo = $data_type;
257+
$crate::define_id_table!(ID_TABLE, $crate::amba::DeviceId, $data_type, $($t)*);
247258
};
248-
249-
// Cover case without a trailing comma.
250-
($(($($entry:tt)*)),*) => {
251-
$crate::declare_amba_id_table!{ $({$($entry)*},)*}
252-
}
253259
}

0 commit comments

Comments
 (0)