Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 #ifndef _LINUX_DELAY_H
0003 #define _LINUX_DELAY_H
0004 
0005 /*
0006  * Copyright (C) 1993 Linus Torvalds
0007  *
0008  * Delay routines, using a pre-computed "loops_per_jiffy" value.
0009  *
0010  * Please note that ndelay(), udelay() and mdelay() may return early for
0011  * several reasons:
0012  *  1. computed loops_per_jiffy too low (due to the time taken to
0013  *     execute the timer interrupt.)
0014  *  2. cache behaviour affecting the time it takes to execute the
0015  *     loop function.
0016  *  3. CPU clock rate changes.
0017  *
0018  * Please see this thread:
0019  *   https://lists.openwall.net/linux-kernel/2011/01/09/56
0020  */
0021 
0022 #include <linux/math.h>
0023 #include <linux/sched.h>
0024 
0025 extern unsigned long loops_per_jiffy;
0026 
0027 #include <asm/delay.h>
0028 
0029 /*
0030  * Using udelay() for intervals greater than a few milliseconds can
0031  * risk overflow for high loops_per_jiffy (high bogomips) machines. The
0032  * mdelay() provides a wrapper to prevent this.  For delays greater
0033  * than MAX_UDELAY_MS milliseconds, the wrapper is used.  Architecture
0034  * specific values can be defined in asm-???/delay.h as an override.
0035  * The 2nd mdelay() definition ensures GCC will optimize away the 
0036  * while loop for the common cases where n <= MAX_UDELAY_MS  --  Paul G.
0037  */
0038 
0039 #ifndef MAX_UDELAY_MS
0040 #define MAX_UDELAY_MS   5
0041 #endif
0042 
0043 #ifndef mdelay
0044 #define mdelay(n) (\
0045     (__builtin_constant_p(n) && (n)<=MAX_UDELAY_MS) ? udelay((n)*1000) : \
0046     ({unsigned long __ms=(n); while (__ms--) udelay(1000);}))
0047 #endif
0048 
0049 #ifndef ndelay
0050 static inline void ndelay(unsigned long x)
0051 {
0052     udelay(DIV_ROUND_UP(x, 1000));
0053 }
0054 #define ndelay(x) ndelay(x)
0055 #endif
0056 
0057 extern unsigned long lpj_fine;
0058 void calibrate_delay(void);
0059 void __attribute__((weak)) calibration_delay_done(void);
0060 void msleep(unsigned int msecs);
0061 unsigned long msleep_interruptible(unsigned int msecs);
0062 void usleep_range_state(unsigned long min, unsigned long max,
0063             unsigned int state);
0064 
0065 static inline void usleep_range(unsigned long min, unsigned long max)
0066 {
0067     usleep_range_state(min, max, TASK_UNINTERRUPTIBLE);
0068 }
0069 
0070 static inline void usleep_idle_range(unsigned long min, unsigned long max)
0071 {
0072     usleep_range_state(min, max, TASK_IDLE);
0073 }
0074 
0075 static inline void ssleep(unsigned int seconds)
0076 {
0077     msleep(seconds * 1000);
0078 }
0079 
0080 /* see Documentation/timers/timers-howto.rst for the thresholds */
0081 static inline void fsleep(unsigned long usecs)
0082 {
0083     if (usecs <= 10)
0084         udelay(usecs);
0085     else if (usecs <= 20000)
0086         usleep_range(usecs, 2 * usecs);
0087     else
0088         msleep(DIV_ROUND_UP(usecs, 1000));
0089 }
0090 
0091 #endif /* defined(_LINUX_DELAY_H) */