1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */ 2aafe4dbeSArnd Bergmann #ifndef __ASM_GENERIC_DELAY_H 3aafe4dbeSArnd Bergmann #define __ASM_GENERIC_DELAY_H 4aafe4dbeSArnd Bergmann 530ab2b03SJonas Bonn /* Undefined functions to get compile-time errors */ 630ab2b03SJonas Bonn extern void __bad_udelay(void); 730ab2b03SJonas Bonn extern void __bad_ndelay(void); 830ab2b03SJonas Bonn 9aafe4dbeSArnd Bergmann extern void __udelay(unsigned long usecs); 1030ab2b03SJonas Bonn extern void __ndelay(unsigned long nsecs); 1130ab2b03SJonas Bonn extern void __const_udelay(unsigned long xloops); 12aafe4dbeSArnd Bergmann extern void __delay(unsigned long loops); 13aafe4dbeSArnd Bergmann 14a87e553fSAndrew Morton /* 15*f36eb171SAnna-Maria Behnsen * Implementation details: 16*f36eb171SAnna-Maria Behnsen * 17*f36eb171SAnna-Maria Behnsen * * The weird n/20000 thing suppresses a "comparison is always false due to 18a87e553fSAndrew Morton * limited range of data type" warning with non-const 8-bit arguments. 19*f36eb171SAnna-Maria Behnsen * * 0x10c7 is 2**32 / 1000000 (rounded up) -> udelay 20*f36eb171SAnna-Maria Behnsen * * 0x5 is 2**32 / 1000000000 (rounded up) -> ndelay 21a87e553fSAndrew Morton */ 22a87e553fSAndrew Morton 23*f36eb171SAnna-Maria Behnsen /** 24*f36eb171SAnna-Maria Behnsen * udelay - Inserting a delay based on microseconds with busy waiting 25*f36eb171SAnna-Maria Behnsen * @usec: requested delay in microseconds 26*f36eb171SAnna-Maria Behnsen * 27*f36eb171SAnna-Maria Behnsen * When delaying in an atomic context ndelay(), udelay() and mdelay() are the 28*f36eb171SAnna-Maria Behnsen * only valid variants of delaying/sleeping to go with. 29*f36eb171SAnna-Maria Behnsen * 30*f36eb171SAnna-Maria Behnsen * When inserting delays in non atomic context which are shorter than the time 31*f36eb171SAnna-Maria Behnsen * which is required to queue e.g. an hrtimer and to enter then the scheduler, 32*f36eb171SAnna-Maria Behnsen * it is also valuable to use udelay(). But it is not simple to specify a 33*f36eb171SAnna-Maria Behnsen * generic threshold for this which will fit for all systems. An approximation 34*f36eb171SAnna-Maria Behnsen * is a threshold for all delays up to 10 microseconds. 35*f36eb171SAnna-Maria Behnsen * 36*f36eb171SAnna-Maria Behnsen * When having a delay which is larger than the architecture specific 37*f36eb171SAnna-Maria Behnsen * %MAX_UDELAY_MS value, please make sure mdelay() is used. Otherwise a overflow 38*f36eb171SAnna-Maria Behnsen * risk is given. 39*f36eb171SAnna-Maria Behnsen * 40*f36eb171SAnna-Maria Behnsen * Please note that ndelay(), udelay() and mdelay() may return early for several 41*f36eb171SAnna-Maria Behnsen * reasons (https://lists.openwall.net/linux-kernel/2011/01/09/56): 42*f36eb171SAnna-Maria Behnsen * 43*f36eb171SAnna-Maria Behnsen * #. computed loops_per_jiffy too low (due to the time taken to execute the 44*f36eb171SAnna-Maria Behnsen * timer interrupt.) 45*f36eb171SAnna-Maria Behnsen * #. cache behaviour affecting the time it takes to execute the loop function. 46*f36eb171SAnna-Maria Behnsen * #. CPU clock rate changes. 47*f36eb171SAnna-Maria Behnsen */ 48a87e553fSAndrew Morton #define udelay(n) \ 49a87e553fSAndrew Morton ({ \ 50a87e553fSAndrew Morton if (__builtin_constant_p(n)) { \ 51a87e553fSAndrew Morton if ((n) / 20000 >= 1) \ 52a87e553fSAndrew Morton __bad_udelay(); \ 53a87e553fSAndrew Morton else \ 54a87e553fSAndrew Morton __const_udelay((n) * 0x10c7ul); \ 55a87e553fSAndrew Morton } else { \ 56a87e553fSAndrew Morton __udelay(n); \ 57a87e553fSAndrew Morton } \ 58a87e553fSAndrew Morton }) 5930ab2b03SJonas Bonn 60*f36eb171SAnna-Maria Behnsen /** 61*f36eb171SAnna-Maria Behnsen * ndelay - Inserting a delay based on nanoseconds with busy waiting 62*f36eb171SAnna-Maria Behnsen * @nsec: requested delay in nanoseconds 63*f36eb171SAnna-Maria Behnsen * 64*f36eb171SAnna-Maria Behnsen * See udelay() for basic information about ndelay() and it's variants. 65*f36eb171SAnna-Maria Behnsen */ 66a87e553fSAndrew Morton #define ndelay(n) \ 67a87e553fSAndrew Morton ({ \ 68a87e553fSAndrew Morton if (__builtin_constant_p(n)) { \ 69a87e553fSAndrew Morton if ((n) / 20000 >= 1) \ 70a87e553fSAndrew Morton __bad_ndelay(); \ 71a87e553fSAndrew Morton else \ 72a87e553fSAndrew Morton __const_udelay((n) * 5ul); \ 73a87e553fSAndrew Morton } else { \ 74a87e553fSAndrew Morton __ndelay(n); \ 75a87e553fSAndrew Morton } \ 76a87e553fSAndrew Morton }) 77aafe4dbeSArnd Bergmann 78aafe4dbeSArnd Bergmann #endif /* __ASM_GENERIC_DELAY_H */ 79