blob: a35b6f1ae79f96cc36b8b813d23e267db234ca29 [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/*
2 * Originally from linux/arch/arm/lib/delay.S
3 *
4 * Copyright (C) 1995, 1996 Russell King
Duy Truonge833aca2013-02-12 13:35:08 -08005 * Copyright (c) 2010, The Linux Foundation. All rights reserved.
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07006 * Copyright (C) 1993 Linus Torvalds
7 * Copyright (C) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
8 * Copyright (C) 2005-2006 Atmel Corporation
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14#include <linux/module.h>
15#include <linux/delay.h>
16#include <linux/timex.h>
17
18/*
19 * Oh, if only we had a cycle counter...
20 */
21void delay_loop(unsigned long loops)
22{
23 asm volatile(
24 "1: subs %0, %0, #1 \n"
25 " bhi 1b \n"
26 : /* No output */
27 : "r" (loops)
28 );
29}
30
31#ifdef ARCH_HAS_READ_CURRENT_TIMER
32/*
33 * Assuming read_current_timer() is monotonically increasing
34 * across calls.
35 */
36void read_current_timer_delay_loop(unsigned long loops)
37{
38 unsigned long bclock, now;
39
40 read_current_timer(&bclock);
41 do {
42 read_current_timer(&now);
43 } while ((now - bclock) < loops);
44}
45#endif
46
47static void (*delay_fn)(unsigned long) = delay_loop;
48
49void set_delay_fn(void (*fn)(unsigned long))
50{
51 delay_fn = fn;
52}
53
54/*
55 * loops = usecs * HZ * loops_per_jiffy / 1000000
56 */
57void __delay(unsigned long loops)
58{
59 delay_fn(loops);
60}
61EXPORT_SYMBOL(__delay);
62
63/*
64 * 0 <= xloops <= 0x7fffff06
65 * loops_per_jiffy <= 0x01ffffff (max. 3355 bogomips)
66 */
67void __const_udelay(unsigned long xloops)
68{
69 unsigned long lpj;
70 unsigned long loops;
71
72 xloops >>= 14; /* max = 0x01ffffff */
73 lpj = loops_per_jiffy >> 10; /* max = 0x0001ffff */
74 loops = lpj * xloops; /* max = 0x00007fff */
75 loops >>= 6; /* max = 2^32-1 */
76
77 if (loops)
78 __delay(loops);
79}
80EXPORT_SYMBOL(__const_udelay);
81
82/*
83 * usecs <= 2000
84 * HZ <= 1000
85 */
86void __udelay(unsigned long usecs)
87{
Jeff Ohlstein910f7242011-07-18 17:03:27 -070088 __const_udelay(usecs * ((2199023UL*HZ)>>11));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070089}
90EXPORT_SYMBOL(__udelay);