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>,
linux-clk@vger.kernel.org, rust-for-linux@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org
Subject: Re: [PATCH v2 2/2] rust: clk: use the type-state pattern
Date: Sun, 21 Sep 2025 18:18:52 +0200 [thread overview]
Message-ID: <DCYM4TPGMFF5.3J6H7VPADC0W0@kernel.org> (raw)
In-Reply-To: <20250910-clk-type-state-v2-2-1b97c11bb631@collabora.com>
On Wed Sep 10, 2025 at 7:28 PM CEST, Daniel Almeida wrote:
> + /// Obtains and enables a [`devres`]-managed [`Clk`] for a device.
> + ///
> + /// [`devres`]: crate::devres::Devres
> + pub fn devm_enable(dev: &Device, name: Option<&CStr>) -> Result {
> + let name = name.map_or(ptr::null(), |n| n.as_ptr());
> +
> + // SAFETY: It is safe to call [`devm_clk_get_enabled`] with a valid
> + // device pointer.
It's not, since this calls into devres it is only safe with a pointer to a bound
device, i.e. you need to require &Device<Bound>.
You also need to justify the CStr pointer in terms of being NULL and its
lifetime.
> + from_err_ptr(unsafe { bindings::devm_clk_get_enabled(dev.as_raw(), name) })?;
> + Ok(())
> + }
> +
> + /// Obtains and enables a [`devres`]-managed [`Clk`] for a device.
> + ///
> + /// This does not print any error messages if the clock is not found.
> + ///
> + /// [`devres`]: crate::devres::Devres
> + pub fn devm_enable_optional(dev: &Device, name: Option<&CStr>) -> Result {
> + let name = name.map_or(ptr::null(), |n| n.as_ptr());
> +
> + // SAFETY: It is safe to call [`devm_clk_get_optional_enabled`] with a
> + // valid device pointer.
> + from_err_ptr(unsafe { bindings::devm_clk_get_optional_enabled(dev.as_raw(), name) })?;
> + Ok(())
> + }
> +
> + /// Same as [`devm_enable_optional`], but also sets the rate.
> + pub fn devm_enable_optional_with_rate(
> + dev: &Device,
> + name: Option<&CStr>,
> + rate: Hertz,
> + ) -> Result {
> + let name = name.map_or(ptr::null(), |n| n.as_ptr());
> +
> + // SAFETY: It is safe to call
> + // [`devm_clk_get_optional_enabled_with_rate`] with a valid device
> + // pointer.
> + from_err_ptr(unsafe {
> + bindings::devm_clk_get_optional_enabled_with_rate(dev.as_raw(), name, rate.as_hz())
> + })?;
> + Ok(())
> + }
I think those should be added in a separate patch.
> + impl Clk<Unprepared> {
> /// Gets [`Clk`] corresponding to a [`Device`] and a connection id.
> ///
> /// Equivalent to the kernel's [`clk_get`] API.
> ///
> /// [`clk_get`]: https://docs.kernel.org/core-api/kernel-api.html#c.clk_get
> - pub fn get(dev: &Device, name: Option<&CStr>) -> Result<Self> {
> + #[inline]
> + pub fn get(dev: &Device, name: Option<&CStr>) -> Result<Clk<Unprepared>> {
Not related to your change, but I'm not sure we should allow drivers to mess
with clocks when they can't prove that they're still bound to the corresponding
device.
It's not introducing any safety issues or unsoundness, but it's not the correct
thing to do semantically.
> let con_id = name.map_or(ptr::null(), |n| n.as_ptr());
>
> // SAFETY: It is safe to call [`clk_get`] for a valid device pointer.
> - //
> + let inner = from_err_ptr(unsafe { bindings::clk_get(dev.as_raw(), con_id) })?;
> +
> // INVARIANT: The reference-count is decremented when [`Clk`] goes out of scope.
> - Ok(Self(from_err_ptr(unsafe {
> - bindings::clk_get(dev.as_raw(), con_id)
> - })?))
> + Ok(Self {
> + inner,
> + _phantom: PhantomData,
> + })
> }
>
> - /// Obtain the raw [`struct clk`] pointer.
> + /// Behaves the same as [`Self::get`], except when there is no clock
> + /// producer. In this case, instead of returning [`ENOENT`], it returns
> + /// a dummy [`Clk`].
> #[inline]
> - pub fn as_raw(&self) -> *mut bindings::clk {
> - self.0
> + pub fn get_optional(dev: &Device, name: Option<&CStr>) -> Result<Clk<Unprepared>> {
> + let con_id = name.map_or(ptr::null(), |n| n.as_ptr());
> +
> + // SAFETY: It is safe to call [`clk_get`] for a valid device pointer.
What about con_id?
> + let inner = from_err_ptr(unsafe { bindings::clk_get_optional(dev.as_raw(), con_id) })?;
> +
> + // INVARIANT: The reference-count is decremented when [`Clk`] goes out of scope.
I know you're consistent with other places, but this seems a odd. This doesn't
correspond to: "A [`Clk`] instance holds either a pointer to a valid [`struct
clk`] created by the C portion of the kernel or a NULL pointer."
> + Ok(Self {
> + inner,
> + _phantom: PhantomData,
> + })
> }
<snip>
> + // SAFETY: By the type invariants, self.as_raw() is a valid argument for
Missing backticks (also in a few other places).
> + // [`clk_put`].
> + unsafe { bindings::clk_put(self.as_raw()) };
> }
> }
prev parent reply other threads:[~2025-09-21 16:18 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-09-10 17:28 [PATCH v2 0/2] Clk improvements for 6.18 Daniel Almeida
2025-09-10 17:28 ` [PATCH v2 1/2] rust: clk: implement Send and Sync Daniel Almeida
2025-09-10 17:49 ` Boqun Feng
2025-09-10 18:47 ` Daniel Almeida
2025-09-10 19:17 ` Boqun Feng
2025-09-20 5:06 ` Stephen Boyd
2025-09-20 10:33 ` Daniel Almeida
2025-09-21 15:48 ` Stephen Boyd
2025-09-20 17:12 ` Alice Ryhl
2025-09-20 18:43 ` Daniel Almeida
2025-09-10 17:28 ` [PATCH v2 2/2] rust: clk: use the type-state pattern Daniel Almeida
2025-09-20 10:35 ` Daniel Almeida
2025-09-21 16:18 ` Danilo Krummrich [this message]
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=DCYM4TPGMFF5.3J6H7VPADC0W0@kernel.org \
--to=dakr@kernel.org \
--cc=a.hindborg@kernel.org \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox