* [PATCH v4 1/2] rust: clk: Add `ExclusiveClk` wrapper for `clk_rate_exclusive_get`
2026-07-11 10:16 [PATCH v4 0/2] rust: clk: Add ExclusiveClk and use it in pwm-th1520 Maurice Hieronymus
@ 2026-07-11 10:16 ` Maurice Hieronymus
2026-07-11 10:16 ` [PATCH v4 2/2] pwm: th1520: Lock clock rate with clk_rate_exclusive_get Maurice Hieronymus
2026-10-20 12:59 ` [PATCH v4 0/2] rust: clk: Add ExclusiveClk and use it in pwm-th1520 Uwe Kleine-König
2 siblings, 0 replies; 5+ messages in thread
From: Maurice Hieronymus @ 2026-07-11 10:16 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Miguel Ojeda, Boqun Feng,
Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg,
Alice Ryhl, Trevor Gross, Danilo Krummrich, Drew Fustini,
Guo Ren, Fu Wei, Michal Wilczynski, Uwe Kleine-König,
Brian Masney
Cc: Daniel Almeida, linux-clk, rust-for-linux, linux-kernel,
linux-riscv, linux-pwm, Maurice Hieronymus
Add Rust bindings for `clk_rate_exclusive_get()` and
`clk_rate_exclusive_put()`.
`Clk::rate_exclusive_get()` consumes the `Clk<Enabled>` and returns an
`ExclusiveClk`. The matching put is issued from its Drop impl.
`ExclusiveClk` derefs to `Clk<Enabled>` so existing APIs remain
available on the locked handle.
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Signed-off-by: Maurice Hieronymus <mhi@mailbox.org>
---
rust/kernel/clk.rs | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 67 insertions(+)
diff --git a/rust/kernel/clk.rs b/rust/kernel/clk.rs
index e677156ffd21..18e4c1fb0937 100644
--- a/rust/kernel/clk.rs
+++ b/rust/kernel/clk.rs
@@ -95,6 +95,7 @@ mod common_clk {
use core::{
marker::PhantomData,
mem::ManuallyDrop,
+ ops::Deref,
ptr, //
};
@@ -682,6 +683,23 @@ pub fn disable(self) -> Clk<Prepared> {
_phantom: PhantomData,
}
}
+
+ /// Acquire exclusive control over the clock's rate.
+ ///
+ /// Consumes the [`Clk<Enabled>`] and returns an [`ExclusiveClk`] that releases
+ /// the exclusivity when dropped. While held, no other consumer may change the clock's rate.
+ ///
+ /// Equivalent to the kernel's [`clk_rate_exclusive_get`] API. Must not be called from
+ /// atomic context.
+ ///
+ /// [`clk_rate_exclusive_get`]: https://docs.kernel.org/core-api/kernel-api.html#c.clk_rate_exclusive_get
+ #[inline]
+ pub fn rate_exclusive_get(self) -> Result<ExclusiveClk> {
+ // SAFETY: By the type invariants, self.as_raw() is a valid argument for
+ // clk_rate_exclusive_get.
+ to_result(unsafe { bindings::clk_rate_exclusive_get(self.as_raw()) })?;
+ Ok(ExclusiveClk(self))
+ }
}
impl<T: ClkState> Clk<T> {
@@ -767,6 +785,55 @@ fn clone(&self) -> Self {
}
}
}
+
+ /// A [`Clk<Enabled>`] with exclusive control over its rate.
+ ///
+ /// While an [`ExclusiveClk`] exists, no other consumer of the same clock may change its rate.
+ /// Obtained by calling [`Clk::rate_exclusive_get`]; the exclusivity is released automatically
+ /// when the value is dropped, after which the inner [`Clk<Enabled>`] is dropped as usual.
+ ///
+ /// # Invariants
+ ///
+ /// An [`ExclusiveClk`] instance owns a [`Clk<Enabled>`] for which `clk_rate_exclusive_get` has
+ /// been called and the matching `clk_rate_exclusive_put` has not yet been called.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use kernel::clk::{
+ /// Clk,
+ /// ExclusiveClk,
+ /// Enabled //
+ /// };
+ /// use kernel::device::{
+ /// Bound,
+ /// Device, //
+ /// };
+ /// use kernel::error::Result;
+ ///
+ /// fn lock_rate(dev: &Device<Bound>) -> Result<ExclusiveClk> {
+ /// let clk = Clk::<Enabled>::get(dev, None)?;
+ /// clk.rate_exclusive_get()
+ /// }
+ /// ```
+ pub struct ExclusiveClk(Clk<Enabled>);
+
+ impl Deref for ExclusiveClk {
+ type Target = Clk<Enabled>;
+
+ fn deref(&self) -> &Clk<Enabled> {
+ &self.0
+ }
+ }
+
+ impl Drop for ExclusiveClk {
+ fn drop(&mut self) {
+ // SAFETY: By the type invariants, self.as_raw() is a valid argument for
+ // clk_rate_exclusive_put and balances the clk_rate_exclusive_get call from
+ // Clk::rate_exclusive_get.
+ unsafe { bindings::clk_rate_exclusive_put(self.as_raw()) };
+ }
+ }
}
#[cfg(CONFIG_COMMON_CLK)]
--
2.51.2
^ permalink raw reply [flat|nested] 5+ messages in thread* [PATCH v4 2/2] pwm: th1520: Lock clock rate with clk_rate_exclusive_get
2026-07-11 10:16 [PATCH v4 0/2] rust: clk: Add ExclusiveClk and use it in pwm-th1520 Maurice Hieronymus
2026-07-11 10:16 ` [PATCH v4 1/2] rust: clk: Add `ExclusiveClk` wrapper for `clk_rate_exclusive_get` Maurice Hieronymus
@ 2026-07-11 10:16 ` Maurice Hieronymus
2026-10-20 12:59 ` [PATCH v4 0/2] rust: clk: Add ExclusiveClk and use it in pwm-th1520 Uwe Kleine-König
2 siblings, 0 replies; 5+ messages in thread
From: Maurice Hieronymus @ 2026-07-11 10:16 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Miguel Ojeda, Boqun Feng,
Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg,
Alice Ryhl, Trevor Gross, Danilo Krummrich, Drew Fustini,
Guo Ren, Fu Wei, Michal Wilczynski, Uwe Kleine-König,
Brian Masney
Cc: Daniel Almeida, linux-clk, rust-for-linux, linux-kernel,
linux-riscv, linux-pwm, Maurice Hieronymus
The driver derives period and duty cycle from the clock rate read at
probe, so a later rate change would silently miscompute waveforms.
Switch to the new ExclusiveClk wrapper to hold the rate for the lifetime
of the driver data and drop the corresponding TODO.
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Michal Wilczynski <m.wilczynski@samsung.com>
Signed-off-by: Maurice Hieronymus <mhi@mailbox.org>
---
drivers/pwm/pwm_th1520.rs | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/drivers/pwm/pwm_th1520.rs b/drivers/pwm/pwm_th1520.rs
index 343a1178c5e7..8f9d3fa39200 100644
--- a/drivers/pwm/pwm_th1520.rs
+++ b/drivers/pwm/pwm_th1520.rs
@@ -22,8 +22,16 @@
use core::ops::Deref;
use kernel::{
- clk::{Clk, Enabled},
- device::{Bound, Core, Device},
+ clk::{
+ Clk,
+ Enabled,
+ ExclusiveClk, //
+ },
+ device::{
+ Bound,
+ Core,
+ Device, //
+ },
devres,
io::{
mem::IoMem,
@@ -93,7 +101,7 @@ struct Th1520WfHw {
struct Th1520PwmDriverData {
#[pin]
iomem: devres::Devres<IoMem<TH1520_PWM_REG_SIZE>>,
- clk: Clk<Enabled>,
+ clk: ExclusiveClk,
}
impl pwm::PwmOps for Th1520PwmDriverData {
@@ -319,10 +327,8 @@ fn probe(
let request = pdev.io_request_by_index(0).ok_or(ENODEV)?;
let clk = Clk::<Enabled>::get(dev, None)?;
+ let clk = clk.rate_exclusive_get()?;
- // TODO: Get exclusive ownership of the clock to prevent rate changes.
- // The Rust equivalent of `clk_rate_exclusive_get()` is not yet available.
- // This should be updated once it is implemented.
let rate_hz = clk.rate().as_hz();
if rate_hz == 0 {
dev_err!(dev, "Clock rate is zero\n");
--
2.51.2
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [PATCH v4 0/2] rust: clk: Add ExclusiveClk and use it in pwm-th1520
2026-07-11 10:16 [PATCH v4 0/2] rust: clk: Add ExclusiveClk and use it in pwm-th1520 Maurice Hieronymus
2026-07-11 10:16 ` [PATCH v4 1/2] rust: clk: Add `ExclusiveClk` wrapper for `clk_rate_exclusive_get` Maurice Hieronymus
2026-07-11 10:16 ` [PATCH v4 2/2] pwm: th1520: Lock clock rate with clk_rate_exclusive_get Maurice Hieronymus
@ 2026-10-20 12:59 ` Uwe Kleine-König
2026-10-20 13:03 ` Daniel Almeida
2 siblings, 1 reply; 5+ messages in thread
From: Uwe Kleine-König @ 2026-10-20 12:59 UTC (permalink / raw)
To: Maurice Hieronymus
Cc: Michael Turquette, Stephen Boyd, Miguel Ojeda, Boqun Feng,
Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg,
Alice Ryhl, Trevor Gross, Danilo Krummrich, Drew Fustini,
Guo Ren, Fu Wei, Michal Wilczynski, Brian Masney, Daniel Almeida,
linux-clk, rust-for-linux, linux-kernel, linux-riscv, linux-pwm
[-- Attachment #1: Type: text/plain, Size: 1344 bytes --]
Hello,
On Sat, Jul 11, 2026 at 12:16:28PM +0200, Maurice Hieronymus wrote:
> Add a Rust binding for clk_rate_exclusive_get() / clk_rate_exclusive_put()
> and use it in pwm-th1520, which previously carried a TODO noting the
> missing binding.
>
> Signed-off-by: Maurice Hieronymus <mhi@mailbox.org>
> ---
> [...]
> ---
> Maurice Hieronymus (2):
> rust: clk: Add `ExclusiveClk` wrapper for `clk_rate_exclusive_get`
> pwm: th1520: Lock clock rate with clk_rate_exclusive_get
>
> drivers/pwm/pwm_th1520.rs | 18 ++++++++-----
> rust/kernel/clk.rs | 67 +++++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 79 insertions(+), 6 deletions(-)
> ---
> base-commit: 92010229c4b38897f1319d260162d2f96925ed17
> change-id: 20260526-rate-exclusive-get-th1520-764a949de18e
> prerequisite-change-id: 20250909-clk-type-state-c01aa7dd551d:v5
> prerequisite-patch-id: 2d3dc45c241d9062a0d2546ec649eec7970fa50a
> prerequisite-patch-id: 67ad535fe110207ebc79045ba022ebb7137b0309
> prerequisite-patch-id: 3d1d8ee5c2a4957edd0807b7a5cb65dabab345b5
> prerequisite-patch-id: e2659037b8aaf51831da099cc568ad5b3c24a4dd
I didn't track these dependencies, but the change looks fine for me. Who
is supposed to merge it? I can take it via pwm, but I guess a rust tree
is more appropriate?!
Best regards
Uwe
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v4 0/2] rust: clk: Add ExclusiveClk and use it in pwm-th1520
2026-10-20 12:59 ` [PATCH v4 0/2] rust: clk: Add ExclusiveClk and use it in pwm-th1520 Uwe Kleine-König
@ 2026-10-20 13:03 ` Daniel Almeida
0 siblings, 0 replies; 5+ messages in thread
From: Daniel Almeida @ 2026-10-20 13:03 UTC (permalink / raw)
To: Uwe Kleine-König
Cc: Maurice Hieronymus, Michael Turquette, Stephen Boyd,
Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
Danilo Krummrich, Drew Fustini, Guo Ren, Fu Wei,
Michal Wilczynski, Brian Masney, linux-clk, rust-for-linux,
linux-kernel, linux-riscv, linux-pwm
> On 20 Oct 2026, at 09:59, Uwe Kleine-König <ukleinek@kernel.org> wrote:
>
> Hello,
>
> On Sat, Jul 11, 2026 at 12:16:28PM +0200, Maurice Hieronymus wrote:
>> Add a Rust binding for clk_rate_exclusive_get() / clk_rate_exclusive_put()
>> and use it in pwm-th1520, which previously carried a TODO noting the
>> missing binding.
>>
>> Signed-off-by: Maurice Hieronymus <mhi@mailbox.org>
>> ---
>> [...]
>> ---
>> Maurice Hieronymus (2):
>> rust: clk: Add `ExclusiveClk` wrapper for `clk_rate_exclusive_get`
>> pwm: th1520: Lock clock rate with clk_rate_exclusive_get
>>
>> drivers/pwm/pwm_th1520.rs | 18 ++++++++-----
>> rust/kernel/clk.rs | 67 +++++++++++++++++++++++++++++++++++++++++++++++
>> 2 files changed, 79 insertions(+), 6 deletions(-)
>> ---
>> base-commit: 92010229c4b38897f1319d260162d2f96925ed17
>> change-id: 20260526-rate-exclusive-get-th1520-764a949de18e
>> prerequisite-change-id: 20250909-clk-type-state-c01aa7dd551d:v5
>> prerequisite-patch-id: 2d3dc45c241d9062a0d2546ec649eec7970fa50a
>> prerequisite-patch-id: 67ad535fe110207ebc79045ba022ebb7137b0309
>> prerequisite-patch-id: 3d1d8ee5c2a4957edd0807b7a5cb65dabab345b5
>> prerequisite-patch-id: e2659037b8aaf51831da099cc568ad5b3c24a4dd
>
> I didn't track these dependencies, but the change looks fine for me. Who
> is supposed to merge it? I can take it via pwm, but I guess a rust tree
> is more appropriate?!
>
> Best regards
> Uwe
Please no,
See [0] instead, which also includes a newer version of this patch.
[0]: https://lore.kernel.org/rust-for-linux/20261013-clk-type-state-v6-1-a5e9977b3509@collabora.com/
^ permalink raw reply [flat|nested] 5+ messages in thread