[PATCH V2 2/2] rust: Add basic bindings for clk APIs

From: Viresh Kumar
Date: Fri Feb 21 2025 - 01:35:42 EST


Add initial bindings for the clk APIs. These provide the minimal
functionality needed for common use cases, making them straightforward
to introduce in the first iteration.

These will be used by Rust based cpufreq / OPP layers to begin with.

Signed-off-by: Viresh Kumar <viresh.kumar@xxxxxxxxxx>
---
MAINTAINERS | 1 +
rust/kernel/clk.rs | 104 +++++++++++++++++++++++++++++++++++++++++++++
rust/kernel/lib.rs | 1 +
3 files changed, 106 insertions(+)
create mode 100644 rust/kernel/clk.rs

diff --git a/MAINTAINERS b/MAINTAINERS
index 726110d3c988..96e2574f41c0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5779,6 +5779,7 @@ F: include/linux/clk-pr*
F: include/linux/clk/
F: include/linux/of_clk.h
F: rust/helpers/clk.c
+F: rust/kernel/clk.rs
X: drivers/clk/clkdev.c

COMMON INTERNET FILE SYSTEM CLIENT (CIFS and SMB3)
diff --git a/rust/kernel/clk.rs b/rust/kernel/clk.rs
new file mode 100644
index 000000000000..c212cd3167e1
--- /dev/null
+++ b/rust/kernel/clk.rs
@@ -0,0 +1,104 @@
+// SPDX-License-Identifier: GPL-2.0
+
+//! Clock abstractions.
+//!
+//! C header: [`include/linux/clk.h`](srctree/include/linux/clk.h)
+
+use crate::{
+ bindings,
+ device::Device,
+ error::{from_err_ptr, to_result, Result},
+ prelude::*,
+};
+
+use core::ptr;
+
+/// A simple implementation of `struct clk` from the C code.
+#[repr(transparent)]
+pub struct Clk(*mut bindings::clk);
+
+impl Clk {
+ /// Creates `Clk` instance for a device and a connection id.
+ pub fn new(dev: &Device, name: Option<&CStr>) -> Result<Self> {
+ let con_id = if let Some(name) = name {
+ name.as_ptr() as *const _
+ } else {
+ ptr::null()
+ };
+
+ // SAFETY: It is safe to call `clk_get()`, on a device pointer earlier received from the C
+ // code.
+ Ok(Self(from_err_ptr(unsafe {
+ bindings::clk_get(dev.as_raw(), con_id)
+ })?))
+ }
+
+ /// Obtain the raw `struct clk *`.
+ pub fn as_raw(&self) -> *mut bindings::clk {
+ self.0
+ }
+
+ /// Clock enable.
+ pub fn enable(&self) -> Result<()> {
+ // SAFETY: By the type invariants, we know that `self` owns a reference, so it is safe to
+ // use it now.
+ to_result(unsafe { bindings::clk_enable(self.0) })
+ }
+
+ /// Clock disable.
+ pub fn disable(&self) {
+ // SAFETY: By the type invariants, we know that `self` owns a reference, so it is safe to
+ // use it now.
+ unsafe { bindings::clk_disable(self.0) };
+ }
+
+ /// Clock prepare.
+ pub fn prepare(&self) -> Result<()> {
+ // SAFETY: By the type invariants, we know that `self` owns a reference, so it is safe to
+ // use it now.
+ to_result(unsafe { bindings::clk_prepare(self.0) })
+ }
+
+ /// Clock unprepare.
+ pub fn unprepare(&self) {
+ // SAFETY: By the type invariants, we know that `self` owns a reference, so it is safe to
+ // use it now.
+ unsafe { bindings::clk_unprepare(self.0) };
+ }
+
+ /// Clock prepare enable.
+ pub fn prepare_enable(&self) -> Result<()> {
+ // SAFETY: By the type invariants, we know that `self` owns a reference, so it is safe to
+ // use it now.
+ to_result(unsafe { bindings::clk_prepare_enable(self.0) })
+ }
+
+ /// Clock disable unprepare.
+ pub fn disable_unprepare(&self) {
+ // SAFETY: By the type invariants, we know that `self` owns a reference, so it is safe to
+ // use it now.
+ unsafe { bindings::clk_disable_unprepare(self.0) };
+ }
+
+ /// Clock get rate.
+ pub fn rate(&self) -> usize {
+ // SAFETY: By the type invariants, we know that `self` owns a reference, so it is safe to
+ // use it now.
+ unsafe { bindings::clk_get_rate(self.0) }
+ }
+
+ /// Clock set rate.
+ pub fn set_rate(&self, rate: usize) -> Result<()> {
+ // SAFETY: By the type invariants, we know that `self` owns a reference, so it is safe to
+ // use it now.
+ to_result(unsafe { bindings::clk_set_rate(self.0, rate) })
+ }
+}
+
+impl Drop for Clk {
+ fn drop(&mut self) {
+ // SAFETY: By the type invariants, we know that `self` owns a reference, so it is safe to
+ // relinquish it now.
+ unsafe { bindings::clk_put(self.0) };
+ }
+}
diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs
index 496ed32b0911..324b86f127a0 100644
--- a/rust/kernel/lib.rs
+++ b/rust/kernel/lib.rs
@@ -40,6 +40,7 @@
pub mod block;
#[doc(hidden)]
pub mod build_assert;
+pub mod clk;
pub mod cred;
pub mod device;
pub mod device_id;
--
2.31.1.272.g89b43f80a514