[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <fc26c393-5c4b-48a8-a7ac-12558f79b140@sedlak.dev>
Date: Wed, 30 Jul 2025 09:29:25 +0200
From: Daniel Sedlak <daniel@...lak.dev>
To: Daniel Almeida <daniel.almeida@...labora.com>,
Michael Turquette <mturquette@...libre.com>, Stephen Boyd
<sboyd@...nel.org>, Miguel Ojeda <ojeda@...nel.org>,
Alex Gaynor <alex.gaynor@...il.com>, Boqun Feng <boqun.feng@...il.com>,
Gary Guo <gary@...yguo.net>, Björn Roy Baron
<bjorn3_gh@...tonmail.com>, Benno Lossin <lossin@...nel.org>,
Andreas Hindborg <a.hindborg@...nel.org>, Alice Ryhl <aliceryhl@...gle.com>,
Trevor Gross <tmgross@...ch.edu>, Danilo Krummrich <dakr@...nel.org>,
"Rafael J. Wysocki" <rafael@...nel.org>,
Viresh Kumar <viresh.kumar@...aro.org>
Cc: Alexandre Courbot <acourbot@...dia.com>, linux-clk@...r.kernel.org,
rust-for-linux@...r.kernel.org, linux-kernel@...r.kernel.org,
linux-pm@...r.kernel.org
Subject: Re: [PATCH] rust: clk: use the type-state pattern
Hi Daniel,
On 7/29/25 11:38 PM, Daniel Almeida wrote:
> + mod private {
> + pub trait Sealed {}
> +
> + impl Sealed for super::Unprepared {}
> + impl Sealed for super::Prepared {}
> + impl Sealed for super::Enabled {}
> + }
I just noticed we have plenty of Sealed traits scattered across rust/
folder. Do you think we would benefit from unifying it to a single
location to prevent duplication?
> +
> + /// A trait representing the different states that a [`Clk`] can be in.
> + pub trait ClkState: private::Sealed {
> + /// Whether the clock should be disabled when dropped.
> + const DISABLE_ON_DROP: bool;
> +
> + /// Whether the clock should be unprepared when dropped.
> + const UNPREPARE_ON_DROP: bool;
> + }
> +
> + /// A state where the [`Clk`] is not prepared and not enabled.
> + pub struct Unprepared;
> +
> + /// A state where the [`Clk`] is prepared but not enabled.
> + pub struct Prepared;
> +
> + /// A state where the [`Clk`] is both prepared and enabled.
> + pub struct Enabled;
I would put a private member into the structs so the user of this API
cannot construct it themself without using your abstractions.
pub struct Unprepared(());
pub struct Prepared(());
pub struct Enabled(());
> +
> + impl ClkState for Unprepared {
> + const DISABLE_ON_DROP: bool = false;
> + const UNPREPARE_ON_DROP: bool = false;
> + }
> +
> + impl ClkState for Prepared {
> + const DISABLE_ON_DROP: bool = false;
> + const UNPREPARE_ON_DROP: bool = true;
> + }
> +
> + impl ClkState for Enabled {
> + const DISABLE_ON_DROP: bool = true;
> + const UNPREPARE_ON_DROP: bool = true;
> + }
> +
> + /// An error that can occur when trying to convert a [`Clk`] between states.
> + pub struct Error<State: ClkState> {
Nit: IMO we mostly use the `where` variant instead of the colon.
pub struct Error<State>
where State: ClkState
But does it make sense to put the bounds on the structs? Shouldn't be
enough but but the bounds on the impl block?
> + /// The error that occurred.
> + pub error: kernel::error::Error,
> +
> + /// The [`Clk`] that caused the error, so that the operation may be
> + /// retried.
> + pub clk: Clk<State>,
> + }
>
Thanks!
Daniel
Powered by blists - more mailing lists