| /* SPDX-License-Identifier: MIT */ | |
| /* | |
| * Copyright © 2026 Intel Corporation | |
| */ | |
| #ifndef _XE_SLEEP_H_ | |
| #define _XE_SLEEP_H_ | |
| #include <linux/delay.h> | |
| #include <linux/math64.h> | |
| /** | |
| * xe_sleep_relaxed_ms() - Sleep for an approximate time. | |
| * @delay_ms: time in msec to sleep | |
| * | |
| * For smaller timeouts, sleep with 0.5ms accuracy. | |
| */ | |
| static inline void xe_sleep_relaxed_ms(unsigned int delay_ms) | |
| { | |
| unsigned long min_us, max_us; | |
| if (!delay_ms) | |
| return; | |
| if (delay_ms > 20) { | |
| msleep(delay_ms); | |
| return; | |
| } | |
| min_us = mul_u32_u32(delay_ms, 1000); | |
| max_us = min_us + 500; | |
| usleep_range(min_us, max_us); | |
| } | |
| /** | |
| * xe_sleep_exponential_ms() - Sleep for a exponentially increased time. | |
| * @sleep_period_ms: current time in msec to sleep | |
| * @max_sleep_ms: maximum time in msec to sleep | |
| * | |
| * Sleep for the @sleep_period_ms and exponentially increase this time for the | |
| * next loop, unless reaching the @max_sleep_ms limit. | |
| * | |
| * Return: approximate time in msec the task was delayed. | |
| */ | |
| static inline unsigned int xe_sleep_exponential_ms(unsigned int *sleep_period_ms, | |
| unsigned int max_sleep_ms) | |
| { | |
| unsigned int delay_ms = *sleep_period_ms; | |
| unsigned int next_delay_ms = 2 * delay_ms; | |
| xe_sleep_relaxed_ms(delay_ms); | |
| *sleep_period_ms = min(next_delay_ms, max_sleep_ms); | |
| return delay_ms; | |
| } | |
| #endif |