From: Alexandre Courbot Date: Thu, 19 Jun 2025 13:23:55 +0000 (+0900) Subject: gpu: nova-core: add helper function to wait on condition X-Git-Tag: v6.17-rc1~110^2~1^2~26 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a03c9bd953c2482aec8013c9c857b4d53031b54d;p=thirdparty%2Flinux.git gpu: nova-core: add helper function to wait on condition 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. Link: https://lore.kernel.org/lkml/20250220070611.214262-8-fujita.tomonori@gmail.com/ [1] Signed-off-by: Alexandre Courbot Link: https://lore.kernel.org/r/20250619-nova-frts-v6-11-ecf41ef99252@nvidia.com Signed-off-by: Danilo Krummrich --- diff --git a/drivers/gpu/nova-core/util.rs b/drivers/gpu/nova-core/util.rs index 332a64cfc6a9d..c50bfa5ab7fe3 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::Instant; + pub(crate) const fn to_lowercase_bytes(s: &str) -> [u8; N] { let src = s.as_bytes(); let mut dst = [0; N]; @@ -19,3 +24,27 @@ 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.tomonori@gmail.com/) +#[expect(dead_code)] +pub(crate) fn wait_on Option>(timeout: Duration, cond: F) -> Result { + let start_time = Instant::now(); + + loop { + if let Some(ret) = cond() { + return Ok(ret); + } + + if start_time.elapsed().as_nanos() > timeout.as_nanos() as i64 { + return Err(ETIMEDOUT); + } + } +}