On Wed, May 07, 2025 at 10:52:39PM +0900, Alexandre Courbot wrote: > While programming the hardware, we frequently need to busy-wait until > a condition (like a given bit of a register to switch value) happens. > > Add a basic `wait_on` helper function to wait on such conditions > expressed as a closure, with a timeout argument. > > This is temporary as we will switch to `read_poll_timeout` [1] once it > is available. > > [1] > https://lore.kernel.org/lkml/20250220070611.214262-8-fujita.tomon...@gmail.com/ > > Signed-off-by: Alexandre Courbot <acour...@nvidia.com> > --- > drivers/gpu/nova-core/util.rs | 30 ++++++++++++++++++++++++++++++ > 1 file changed, 30 insertions(+) > > diff --git a/drivers/gpu/nova-core/util.rs b/drivers/gpu/nova-core/util.rs > index > 332a64cfc6a9d7d787fbdc228887c0be53a97160..afb525228431a2645afe7bb34988e9537757b1d7 > 100644 > --- a/drivers/gpu/nova-core/util.rs > +++ b/drivers/gpu/nova-core/util.rs > @@ -1,5 +1,10 @@ > // SPDX-License-Identifier: GPL-2.0 > > +use core::time::Duration; > + > +use kernel::prelude::*; > +use kernel::time::Ktime; > + > pub(crate) const fn to_lowercase_bytes<const N: usize>(s: &str) -> [u8; N] { > let src = s.as_bytes(); > let mut dst = [0; N]; > @@ -19,3 +24,28 @@ pub(crate) const fn const_bytes_to_str(bytes: &[u8]) -> > &str { > Err(_) => kernel::build_error!("Bytes are not valid UTF-8."), > } > } > + > +/// Wait until `cond` is true or `timeout` elapsed. > +/// > +/// When `cond` evaluates to `Some`, its return value is returned. > +/// > +/// `Err(ETIMEDOUT)` is returned if `timeout` has been reached without > `cond` evaluating to > +/// `Some`. > +/// > +/// TODO: replace with `read_poll_timeout` once it is available. > +/// > (https://lore.kernel.org/lkml/20250220070611.214262-8-fujita.tomon...@gmail.com/) > +#[expect(dead_code)] > +pub(crate) fn wait_on<R, F: Fn() -> Option<R>>(timeout: Duration, cond: F) > -> Result<R> { > + let start_time = Ktime::ktime_get(); > + > + loop { > + if let Some(ret) = cond() { > + return Ok(ret); > + } > + > + let cur_time = Ktime::ktime_get(); > + if (cur_time - start_time).to_ns() > timeout.as_nanos() as i64 { > + return Err(ETIMEDOUT); > + } > + } > +}
NIT: Can't you use this for wait_gfw_boot_completion() too?