xref: /openbmc/linux/arch/s390/lib/delay.c (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds  *    Precise Delay Loops for S390
41da177e4SLinus Torvalds  *
5d3d238c7SHeiko Carstens  *    Copyright IBM Corp. 1999, 2008
6d3d238c7SHeiko Carstens  *    Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>,
71da177e4SLinus Torvalds  */
81da177e4SLinus Torvalds 
93da77cf3SHeiko Carstens #include <linux/processor.h>
101da177e4SLinus Torvalds #include <linux/delay.h>
11b3966378SHeiko Carstens #include <asm/div64.h>
123da77cf3SHeiko Carstens #include <asm/timex.h>
131da177e4SLinus Torvalds 
__delay(unsigned long loops)141da177e4SLinus Torvalds void __delay(unsigned long loops)
151da177e4SLinus Torvalds {
161da177e4SLinus Torvalds 	/*
17*9aa10e79SHeiko Carstens 	 * Loop 'loops' times. Callers must not assume a specific
18*9aa10e79SHeiko Carstens 	 * amount of time passes before this function returns.
191da177e4SLinus Torvalds 	 */
2094c12cc7SMartin Schwidefsky 	asm volatile("0: brct %0,0b" : : "d" ((loops/2) + 1));
211da177e4SLinus Torvalds }
22854508c0SGuenter Roeck EXPORT_SYMBOL(__delay);
231da177e4SLinus Torvalds 
delay_loop(unsigned long delta)24e0d62dcbSHeiko Carstens static void delay_loop(unsigned long delta)
251da177e4SLinus Torvalds {
26dd6cfe55SHeiko Carstens 	unsigned long end;
271da177e4SLinus Torvalds 
28dd6cfe55SHeiko Carstens 	end = get_tod_clock_monotonic() + delta;
29dd6cfe55SHeiko Carstens 	while (!tod_after(get_tod_clock_monotonic(), end))
30dd6cfe55SHeiko Carstens 		cpu_relax();
31d3d238c7SHeiko Carstens }
32d54853efSMartin Schwidefsky 
__udelay(unsigned long usecs)33dd6cfe55SHeiko Carstens void __udelay(unsigned long usecs)
34d3d238c7SHeiko Carstens {
35e0d62dcbSHeiko Carstens 	delay_loop(usecs << 12);
361da177e4SLinus Torvalds }
371485c5c8SHeiko Carstens EXPORT_SYMBOL(__udelay);
385a0d0e65SHeiko Carstens 
__ndelay(unsigned long nsecs)39dd6cfe55SHeiko Carstens void __ndelay(unsigned long nsecs)
40b3966378SHeiko Carstens {
41b3966378SHeiko Carstens 	nsecs <<= 9;
42b3966378SHeiko Carstens 	do_div(nsecs, 125);
43e0d62dcbSHeiko Carstens 	delay_loop(nsecs);
44b3966378SHeiko Carstens }
45b3966378SHeiko Carstens EXPORT_SYMBOL(__ndelay);
46