aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um')
-rw-r--r--arch/um/include/asm/delay.h10
-rw-r--r--arch/um/sys-i386/delay.c59
-rw-r--r--arch/um/sys-x86_64/delay.c54
3 files changed, 91 insertions, 32 deletions
diff --git a/arch/um/include/asm/delay.h b/arch/um/include/asm/delay.h
index c71e32b6741e..8a5576d8eda5 100644
--- a/arch/um/include/asm/delay.h
+++ b/arch/um/include/asm/delay.h
@@ -1,20 +1,18 @@
1#ifndef __UM_DELAY_H 1#ifndef __UM_DELAY_H
2#define __UM_DELAY_H 2#define __UM_DELAY_H
3 3
4#define MILLION 1000000
5
6/* Undefined on purpose */ 4/* Undefined on purpose */
7extern void __bad_udelay(void); 5extern void __bad_udelay(void);
6extern void __bad_ndelay(void);
8 7
9extern void __udelay(unsigned long usecs); 8extern void __udelay(unsigned long usecs);
9extern void __ndelay(unsigned long usecs);
10extern void __delay(unsigned long loops); 10extern void __delay(unsigned long loops);
11 11
12#define udelay(n) ((__builtin_constant_p(n) && (n) > 20000) ? \ 12#define udelay(n) ((__builtin_constant_p(n) && (n) > 20000) ? \
13 __bad_udelay() : __udelay(n)) 13 __bad_udelay() : __udelay(n))
14 14
15/* It appears that ndelay is not used at all for UML, and has never been 15#define ndelay(n) ((__builtin_constant_p(n) && (n) > 20000) ? \
16 * implemented. */ 16 __bad_ndelay() : __ndelay(n))
17extern void __unimplemented_ndelay(void);
18#define ndelay(n) __unimplemented_ndelay()
19 17
20#endif 18#endif
diff --git a/arch/um/sys-i386/delay.c b/arch/um/sys-i386/delay.c
index d623e074f41d..f3fe1a688f7e 100644
--- a/arch/um/sys-i386/delay.c
+++ b/arch/um/sys-i386/delay.c
@@ -1,29 +1,60 @@
1/*
2 * Copyright (C) 2011 Richard Weinberger <richrd@nod.at>
3 * Mostly copied from arch/x86/lib/delay.c
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 */
9
1#include <linux/module.h> 10#include <linux/module.h>
2#include <linux/kernel.h> 11#include <linux/kernel.h>
3#include <linux/delay.h> 12#include <linux/delay.h>
4#include <asm/param.h> 13#include <asm/param.h>
5 14
6void __delay(unsigned long time) 15void __delay(unsigned long loops)
7{ 16{
8 /* Stolen from the i386 __loop_delay */ 17 asm volatile(
9 int d0; 18 "test %0,%0\n"
10 __asm__ __volatile__( 19 "jz 3f\n"
11 "\tjmp 1f\n" 20 "jmp 1f\n"
21
12 ".align 16\n" 22 ".align 16\n"
13 "1:\tjmp 2f\n" 23 "1: jmp 2f\n"
24
14 ".align 16\n" 25 ".align 16\n"
15 "2:\tdecl %0\n\tjns 2b" 26 "2: dec %0\n"
16 :"=&a" (d0) 27 " jnz 2b\n"
17 :"0" (time)); 28 "3: dec %0\n"
29
30 : /* we don't need output */
31 : "a" (loops)
32 );
18} 33}
34EXPORT_SYMBOL(__delay);
19 35
20void __udelay(unsigned long usecs) 36inline void __const_udelay(unsigned long xloops)
21{ 37{
22 int i, n; 38 int d0;
23 39
24 n = (loops_per_jiffy * HZ * usecs) / MILLION; 40 xloops *= 4;
25 for(i=0;i<n;i++) 41 asm("mull %%edx"
26 cpu_relax(); 42 : "=d" (xloops), "=&a" (d0)
43 : "1" (xloops), "0"
44 (loops_per_jiffy * (HZ/4)));
45
46 __delay(++xloops);
27} 47}
48EXPORT_SYMBOL(__const_udelay);
28 49
50void __udelay(unsigned long usecs)
51{
52 __const_udelay(usecs * 0x000010c7); /* 2**32 / 1000000 (rounded up) */
53}
29EXPORT_SYMBOL(__udelay); 54EXPORT_SYMBOL(__udelay);
55
56void __ndelay(unsigned long nsecs)
57{
58 __const_udelay(nsecs * 0x00005); /* 2**32 / 1000000000 (rounded up) */
59}
60EXPORT_SYMBOL(__ndelay);
diff --git a/arch/um/sys-x86_64/delay.c b/arch/um/sys-x86_64/delay.c
index dee5be66da82..f3fe1a688f7e 100644
--- a/arch/um/sys-x86_64/delay.c
+++ b/arch/um/sys-x86_64/delay.c
@@ -1,30 +1,60 @@
1/* 1/*
2 * Copyright 2003 PathScale, Inc. 2 * Copyright (C) 2011 Richard Weinberger <richrd@nod.at>
3 * Copied from arch/x86_64 3 * Mostly copied from arch/x86/lib/delay.c
4 * 4 *
5 * Licensed under the GPL 5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
6 */ 8 */
7 9
8#include <linux/module.h> 10#include <linux/module.h>
11#include <linux/kernel.h>
9#include <linux/delay.h> 12#include <linux/delay.h>
10#include <asm/processor.h>
11#include <asm/param.h> 13#include <asm/param.h>
12 14
13void __delay(unsigned long loops) 15void __delay(unsigned long loops)
14{ 16{
15 unsigned long i; 17 asm volatile(
18 "test %0,%0\n"
19 "jz 3f\n"
20 "jmp 1f\n"
16 21
17 for(i = 0; i < loops; i++) 22 ".align 16\n"
18 cpu_relax(); 23 "1: jmp 2f\n"
24
25 ".align 16\n"
26 "2: dec %0\n"
27 " jnz 2b\n"
28 "3: dec %0\n"
29
30 : /* we don't need output */
31 : "a" (loops)
32 );
19} 33}
34EXPORT_SYMBOL(__delay);
20 35
21void __udelay(unsigned long usecs) 36inline void __const_udelay(unsigned long xloops)
22{ 37{
23 unsigned long i, n; 38 int d0;
24 39
25 n = (loops_per_jiffy * HZ * usecs) / MILLION; 40 xloops *= 4;
26 for(i=0;i<n;i++) 41 asm("mull %%edx"
27 cpu_relax(); 42 : "=d" (xloops), "=&a" (d0)
43 : "1" (xloops), "0"
44 (loops_per_jiffy * (HZ/4)));
45
46 __delay(++xloops);
28} 47}
48EXPORT_SYMBOL(__const_udelay);
29 49
50void __udelay(unsigned long usecs)
51{
52 __const_udelay(usecs * 0x000010c7); /* 2**32 / 1000000 (rounded up) */
53}
30EXPORT_SYMBOL(__udelay); 54EXPORT_SYMBOL(__udelay);
55
56void __ndelay(unsigned long nsecs)
57{
58 __const_udelay(nsecs * 0x00005); /* 2**32 / 1000000000 (rounded up) */
59}
60EXPORT_SYMBOL(__ndelay);