From: "Danilo Krummrich" <dakr@kernel.org>
To: "Daniel Almeida" <daniel.almeida@collabora.com>
Cc: "Michael Turquette" <mturquette@baylibre.com>,
"Stephen Boyd" <sboyd@kernel.org>,
"Miguel Ojeda" <ojeda@kernel.org>,
"Alex Gaynor" <alex.gaynor@gmail.com>,
"Boqun Feng" <boqun.feng@gmail.com>,
"Gary Guo" <gary@garyguo.net>,
"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
"Benno Lossin" <lossin@kernel.org>,
"Andreas Hindborg" <a.hindborg@kernel.org>,
"Alice Ryhl" <aliceryhl@google.com>,
"Trevor Gross" <tmgross@umich.edu>,
"Rafael J. Wysocki" <rafael@kernel.org>,
"Viresh Kumar" <viresh.kumar@linaro.org>,
"Alexandre Courbot" <acourbot@nvidia.com>,
linux-clk@vger.kernel.org, rust-for-linux@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org
Subject: Re: [PATCH] rust: clk: use the type-state pattern
Date: Wed, 30 Jul 2025 14:24:20 +0200 [thread overview]
Message-ID: <DBPDYDSV2URD.G6L0VGU3IYAC@kernel.org> (raw)
In-Reply-To: <086CDFC4-A9EE-40C7-89BB-D3B8CBFA01EA@collabora.com>
On Wed Jul 30, 2025 at 2:13 PM CEST, Daniel Almeida wrote:
>> On 30 Jul 2025, at 05:03, Danilo Krummrich <dakr@kernel.org> wrote:
>> On Tue Jul 29, 2025 at 11:38 PM CEST, Daniel Almeida wrote:
>>> /// fn configure_clk(dev: &Device) -> Result {
>>> - /// let clk = Clk::get(dev, Some(c_str!("apb_clk")))?;
>>> + /// // The fastest way is to use a version of `Clk::get` for the desired
>>> + /// // state, i.e.:
>>> + /// let clk: Clk<Enabled> = Clk::<Enabled>::get(dev, Some(c_str!("apb_clk")))?;
>>
>> Given that this is a driver API, why do we allow obtaining and configuring
>> clocks of any device, i.e. also unbound devices?
>>
>> I think Clk::<T>::get() should take a &Device<Bound> instead.
>
> Ah, this was a question I had, but that I forgot to mention here.
>
> The same can probably be said of the regulator series? i.e.:
>
> impl Regulator<Disabled> {
> /// Obtains a [`Regulator`] instance from the system.
> pub fn get(dev: &Device, name: &CStr) -> Result<Self> {
> Regulator::get_internal(dev, name)
> }
Yes, that's a device resource as well. We should only give it out to drivers
when they're actually bound to the device.
>>
>>> - /// clk.prepare_enable()?;
>>> + /// // Any other state is also possible, e.g.:
>>> + /// let clk: Clk<Prepared> = Clk::<Prepared>::get(dev, Some(c_str!("apb_clk")))?;
>>> + ///
>>> + /// // Later:
>>> + /// let clk: Clk<Enabled> = clk.enable().map_err(|error| {
>>> + /// error.error
>>> + /// })?;
>>> + ///
>>> + /// // Note that error.clk is the original `clk` if the operation
>>> + /// // failed. It is provided as a convenience so that the operation may be
>>> + /// // retried in case of errors.
>>> ///
>>> /// let expected_rate = Hertz::from_ghz(1);
>>> ///
>>> @@ -120,104 +200,172 @@ mod common_clk {
>>> /// clk.set_rate(expected_rate)?;
>>> /// }
>>> ///
>>> - /// clk.disable_unprepare();
>>> + /// // Nothing is needed here. The drop implementation will undo any
>>> + /// // operations as appropriate.
>>> + /// Ok(())
>>> + /// }
>>> + ///
>>> + /// fn shutdown(dev: &Device, clk: Clk<Enabled>) -> Result {
>>
>> You don't need the dev argument here.
>>
>>> + /// // The states can be traversed "in the reverse order" as well:
>>> + /// let clk: Clk<Prepared> = clk.disable().map_err(|error| {
>>> + /// error.error
>>> + /// })?;
>>> + ///
>>> + /// let clk: Clk<Unprepared> = clk.unprepare();
>>
>> I know you want to showcase the type state, yet I don't know if we should
>> explicitly declare the type if not necessary. People will likely just copy
>> things. Maybe a comment is better to emphasize it?
>
> Ok
>
>>
>>> + ///
>>> /// Ok(())
>>> /// }
>>> /// ```
>>> ///
>>> /// [`struct clk`]: https://docs.kernel.org/driver-api/clk.html
>>> #[repr(transparent)]
>>> - pub struct Clk(*mut bindings::clk);
>>> + pub struct Clk<T: ClkState> {
>>> + inner: *mut bindings::clk,
>>> + _phantom: core::marker::PhantomData<T>,
>>> + }
>>
>> <snip>
>>
>>> + impl<T: ClkState> Drop for Clk<T> {
>>> + fn drop(&mut self) {
>>> + if T::DISABLE_ON_DROP {
>>> + // SAFETY: By the type invariants, self.as_raw() is a valid argument for
>>> + // [`clk_disable`].
>>> + unsafe { bindings::clk_disable(self.as_raw()) };
>>> + }
>>> +
>>> + if T::UNPREPARE_ON_DROP {
>>> + // SAFETY: By the type invariants, self.as_raw() is a valid argument for
>>> + // [`clk_unprepare`].
>>> + unsafe { bindings::clk_unprepare(self.as_raw()) };
>>> + }
>>
>> Nice! I like this cleanup. However, don't you still need to call clk_put() to
>> drop the reference count?
>
> Right, clk_put() was totally forgotten.
>
>>
>> Also, given that this is a device resource, don't we want to take it away from
>> drivers once the corresponding device has been unbound, i.e. use Devres?
>
> Do you mean to have the get() functions return Devres<Clk>?
>
> Also, is this applicable for Regulator as well?
Yes, drivers shouldn't be able to mess with device specific resources once they
are unbound from the device.
next prev parent reply other threads:[~2025-07-30 12:24 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-07-29 21:38 [PATCH] rust: clk: use the type-state pattern Daniel Almeida
2025-07-30 6:23 ` Viresh Kumar
2025-07-30 12:27 ` Daniel Almeida
2025-07-30 14:48 ` Viresh Kumar
2025-07-30 7:29 ` Daniel Sedlak
2025-07-30 8:20 ` Benno Lossin
2025-07-30 12:59 ` Daniel Almeida
2025-07-30 13:27 ` Daniel Sedlak
2025-07-30 13:30 ` Daniel Almeida
2025-07-30 13:39 ` Alice Ryhl
2025-07-30 13:45 ` Daniel Almeida
2025-07-30 8:29 ` Danilo Krummrich
2025-07-30 12:25 ` Daniel Almeida
2025-07-30 8:03 ` Danilo Krummrich
2025-07-30 12:13 ` Daniel Almeida
2025-07-30 12:24 ` Danilo Krummrich [this message]
2025-07-30 13:52 ` Daniel Almeida
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=DBPDYDSV2URD.G6L0VGU3IYAC@kernel.org \
--to=dakr@kernel.org \
--cc=a.hindborg@kernel.org \
--cc=acourbot@nvidia.com \
--cc=alex.gaynor@gmail.com \
--cc=aliceryhl@google.com \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun.feng@gmail.com \
--cc=daniel.almeida@collabora.com \
--cc=gary@garyguo.net \
--cc=linux-clk@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@vger.kernel.org \
--cc=lossin@kernel.org \
--cc=mturquette@baylibre.com \
--cc=ojeda@kernel.org \
--cc=rafael@kernel.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=sboyd@kernel.org \
--cc=tmgross@umich.edu \
--cc=viresh.kumar@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.