On Tue, 3 Feb 2026 11:39:02 +0100 Boris Brezillon <[email protected]> wrote:
> On Mon, 19 Jan 2026 12:35:21 +0000 > Alice Ryhl <[email protected]> wrote: > > > On Mon, Jan 19, 2026 at 11:45:57AM +0100, Maxime Ripard wrote: > > > On Thu, Jan 08, 2026 at 11:14:37AM -0300, Daniel Almeida wrote: > > > > > For example, it's quite typical to have (at least) one clock for the > > > > > bus > > > > > interface that drives the register, and one that drives the main > > > > > component logic. The former needs to be enabled only when you're > > > > > accessing the registers (and can be abstracted with > > > > > regmap_mmio_attach_clk for example), and the latter needs to be > > > > > enabled > > > > > only when the device actually starts operating. > > > > > > > > > > You have a similar thing for the prepare vs enable thing. The > > > > > difference > > > > > between the two is that enable can be called into atomic context but > > > > > prepare can't. > > > > > > > > > > So for drivers that would care about this, you would create your > > > > > device > > > > > with an unprepared clock, and then at various times during the driver > > > > > lifetime, you would mutate that state. > > > > The case where you're doing it only while accessing registers is > > interesting, because that means the Enable bit may be owned by a local > > variable. We may imagine an: > > > > let enabled = self.prepared_clk.enable_scoped(); > > ... use registers > > drop(enabled); > > > > Now ... this doesn't quite work with the current API - the current > > Enabled stated owns both a prepare and enable count, but the above keeps > > the prepare count in `self` and the enabled count in a local variable. > > But it could be done with a fourth state, or by a closure method: > > > > self.prepared_clk.with_enabled(|| { > > ... use registers > > }); > > > > All of this would work with an immutable variable of type Clk<Prepared>. > > Hm, maybe it'd make sense to implement Clone so we can have a temporary > clk variable that has its own prepare/enable refs and releases them > as it goes out of scope. This implies wrapping *mut bindings::clk in an > Arc<> because bindings::clk is not ARef, but should be relatively easy > to do. Posting the quick experiment I did with this approach, in case > you're interested [1] This time with a proper RawClk(*mut bindings::clk) wrapper, so we can clk_put() called in RawClk::drop() instead of in Clk::drop(). [1]https://gitlab.freedesktop.org/bbrezillon/linux/-/commit/6fa6cb72f14373b276c61d038bc2b16f49c78f74
