-
-
Notifications
You must be signed in to change notification settings - Fork 45
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
rust/kernel: Add faux device bindings
This introduces a module for working with faux devices in rust, along with adding sample code to show how the API is used. Unlike other types of devices, we don't provide any hooks for device probe/removal - since these are optional for the faux API and are unnecessary in rust. Signed-off-by: Lyude Paul <[email protected]> Cc: Maíra Canal <[email protected]> Cc: Danilo Krummrich <[email protected]> Cc: Miguel Ojeda <[email protected]> Acked-by: Danilo Krummrich <[email protected]> Link: https://lore.kernel.org/r/2025021026-exert-accent-b4c6@gregkh Signed-off-by: Greg Kroah-Hartman <[email protected]>
- Loading branch information
Showing
7 changed files
with
111 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7116,8 +7116,10 @@ F: rust/kernel/device.rs | |
F: rust/kernel/device_id.rs | ||
F: rust/kernel/devres.rs | ||
F: rust/kernel/driver.rs | ||
F: rust/kernel/faux.rs | ||
F: rust/kernel/platform.rs | ||
F: samples/rust/rust_driver_platform.rs | ||
F: samples/rust/rust_driver_faux.rs | ||
|
||
DRIVERS FOR OMAP ADAPTIVE VOLTAGE SCALING (AVS) | ||
M: Nishanth Menon <[email protected]> | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
// SPDX-License-Identifier: GPL-2.0-only | ||
|
||
//! Abstractions for the faux bus. | ||
//! | ||
//! This module provides bindings for working with faux devices in kernel modules. | ||
//! | ||
//! C header: [`include/linux/device/faux.h`] | ||
use crate::{bindings, device, error::code::*, prelude::*}; | ||
use core::ptr::{addr_of_mut, null, null_mut, NonNull}; | ||
|
||
/// The registration of a faux device. | ||
/// | ||
/// This type represents the registration of a [`struct faux_device`]. When an instance of this type | ||
/// is dropped, its respective faux device will be unregistered from the system. | ||
/// | ||
/// # Invariants | ||
/// | ||
/// `self.0` always holds a valid pointer to an initialized and registered [`struct faux_device`]. | ||
/// | ||
/// [`struct faux_device`]: srctree/include/linux/device/faux.h | ||
#[repr(transparent)] | ||
pub struct Registration(NonNull<bindings::faux_device>); | ||
|
||
impl Registration { | ||
/// Create and register a new faux device with the given name. | ||
pub fn new(name: &CStr) -> Result<Self> { | ||
// SAFETY: | ||
// - `name` is copied by this function into its own storage | ||
// - `faux_ops` is safe to leave NULL according to the C API | ||
let dev = unsafe { bindings::faux_device_create(name.as_char_ptr(), null_mut(), null()) }; | ||
|
||
// The above function will return either a valid device, or NULL on failure | ||
// INVARIANT: The device will remain registered until faux_device_destroy() is called, which | ||
// happens in our Drop implementation. | ||
Ok(Self(NonNull::new(dev).ok_or(ENODEV)?)) | ||
} | ||
|
||
fn as_raw(&self) -> *mut bindings::faux_device { | ||
self.0.as_ptr() | ||
} | ||
} | ||
|
||
impl AsRef<device::Device> for Registration { | ||
fn as_ref(&self) -> &device::Device { | ||
// SAFETY: The underlying `device` in `faux_device` is guaranteed by the C API to be | ||
// a valid initialized `device`. | ||
unsafe { device::Device::as_ref(addr_of_mut!((*self.as_raw()).dev)) } | ||
} | ||
} | ||
|
||
impl Drop for Registration { | ||
fn drop(&mut self) { | ||
// SAFETY: `self.0` is a valid registered faux_device via our type invariants. | ||
unsafe { bindings::faux_device_destroy(self.as_raw()) } | ||
} | ||
} | ||
|
||
// SAFETY: The faux device API is thread-safe as guaranteed by the device core, as long as | ||
// faux_device_destroy() is guaranteed to only be called once - which is guaranteed by our type not | ||
// having Copy/Clone. | ||
unsafe impl Send for Registration {} | ||
|
||
// SAFETY: The faux device API is thread-safe as guaranteed by the device core, as long as | ||
// faux_device_destroy() is guaranteed to only be called once - which is guaranteed by our type not | ||
// having Copy/Clone. | ||
unsafe impl Sync for Registration {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
// SPDX-License-Identifier: GPL-2.0-only | ||
|
||
//! Rust faux device sample. | ||
use kernel::{c_str, faux, prelude::*, Module}; | ||
|
||
module! { | ||
type: SampleModule, | ||
name: "rust_faux_driver", | ||
author: "Lyude Paul", | ||
description: "Rust faux device sample", | ||
license: "GPL", | ||
} | ||
|
||
struct SampleModule { | ||
_reg: faux::Registration, | ||
} | ||
|
||
impl Module for SampleModule { | ||
fn init(_module: &'static ThisModule) -> Result<Self> { | ||
pr_info!("Initialising Rust Faux Device Sample\n"); | ||
|
||
let reg = faux::Registration::new(c_str!("rust-faux-sample-device"))?; | ||
|
||
dev_info!(reg.as_ref(), "Hello from faux device!\n"); | ||
|
||
Ok(Self { _reg: reg }) | ||
} | ||
} |