forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
rust: add initial common clock framework bindings
This patch adds initial abstractions including: - `Clk` wrapper around `struct clk *`. - Binding of clk_get() method implemented as a method of `device::RawDevice` trait. - `EnableClk` that is an invariant of the `Clk` type that manages usage of the disable_unprepare() function. - Routines get_rate() and prepare_enable() implemented as methods of `Clk` type. Signed-off-by: Maciej Falkowski <m.falkowski@samsung.com>
- Loading branch information
Maciej Falkowski
committed
Jan 12, 2022
1 parent
cd969b5
commit 632ef86
Showing
5 changed files
with
113 additions
and
1 deletion.
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
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,75 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
|
||
//! Common clock framework. | ||
//! | ||
//! C header: [`include/linux/clk.h`](../../../../include/linux/clk.h) | ||
use crate::{bindings, error::Result, to_result}; | ||
use core::mem::ManuallyDrop; | ||
|
||
/// Represents `struct clk *`. | ||
/// | ||
/// # Invariants | ||
/// | ||
/// The pointer is valid. | ||
pub struct Clk(*mut bindings::clk); | ||
|
||
impl Clk { | ||
/// Creates new clock structure from a raw pointer. | ||
/// | ||
/// # Safety | ||
/// | ||
/// The pointer must be valid. | ||
pub unsafe fn new(clk: *mut bindings::clk) -> Self { | ||
Self(clk) | ||
} | ||
|
||
/// Returns value of the rate field of `struct clk`. | ||
pub fn get_rate(&self) -> usize { | ||
// SAFETY: the pointer is valid by the type invariant. | ||
unsafe { bindings::clk_get_rate(self.0) as usize } | ||
} | ||
|
||
/// Prepares and enables the underlying hardware clock. | ||
/// | ||
/// This function should not be called in atomic context. | ||
pub fn prepare_enable(self) -> Result<EnabledClk> { | ||
// SAFETY: the pointer is valid by the type invariant. | ||
to_result(|| unsafe { bindings::clk_prepare_enable(self.0) })?; | ||
Ok(EnabledClk(self)) | ||
} | ||
} | ||
|
||
impl Drop for Clk { | ||
fn drop(&mut self) { | ||
// SAFETY: the pointer is valid by the type invariant. | ||
unsafe { bindings::clk_put(self.0) }; | ||
} | ||
} | ||
|
||
/// A clock variant that is prepared and enabled. | ||
pub struct EnabledClk(Clk); | ||
|
||
impl EnabledClk { | ||
/// Returns value of the rate field of `struct clk`. | ||
pub fn get_rate(&self) -> usize { | ||
self.0.get_rate() | ||
} | ||
|
||
/// Disables and later unprepares the underlying hardware clock prematurely. | ||
/// | ||
/// This function should not be called in atomic context. | ||
pub fn disable_unprepare(self) -> Clk { | ||
let mut clk = ManuallyDrop::new(self); | ||
// SAFETY: the pointer is valid by the type invariant. | ||
unsafe { bindings::clk_disable_unprepare(clk.0 .0) }; | ||
core::mem::replace(&mut clk.0, Clk(core::ptr::null_mut())) | ||
} | ||
} | ||
|
||
impl Drop for EnabledClk { | ||
fn drop(&mut self) { | ||
// SAFETY: the pointer is valid by the type invariant. | ||
unsafe { bindings::clk_disable_unprepare(self.0 .0) }; | ||
} | ||
} |
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