Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
arch
arm
lib
delay.c
Go to the documentation of this file.
1
/*
2
* Delay loops based on the OpenRISC implementation.
3
*
4
* Copyright (C) 2012 ARM Limited
5
*
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License version 2 as
8
* published by the Free Software Foundation.
9
*
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
14
*
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
*
19
* Author: Will Deacon <
[email protected]
>
20
*/
21
22
#include <
linux/delay.h
>
23
#include <
linux/init.h
>
24
#include <linux/kernel.h>
25
#include <linux/module.h>
26
#include <linux/timex.h>
27
28
/*
29
* Default to the loop-based delay implementation.
30
*/
31
struct
arm_delay_ops
arm_delay_ops
= {
32
.
delay
=
__loop_delay
,
33
.const_udelay =
__loop_const_udelay
,
34
.udelay =
__loop_udelay
,
35
};
36
37
static
const
struct
delay_timer
*
delay_timer
;
38
static
bool
delay_calibrated;
39
40
int
read_current_timer
(
unsigned
long
*timer_val)
41
{
42
if
(!delay_timer)
43
return
-
ENXIO
;
44
45
*timer_val = delay_timer->
read_current_timer
();
46
return
0;
47
}
48
EXPORT_SYMBOL_GPL
(
read_current_timer
);
49
50
static
void
__timer_delay(
unsigned
long
cycles)
51
{
52
cycles_t
start
=
get_cycles
();
53
54
while
((
get_cycles
() - start) < cycles)
55
cpu_relax
();
56
}
57
58
static
void
__timer_const_udelay(
unsigned
long
xloops)
59
{
60
unsigned
long
long
loops = xloops;
61
loops *=
loops_per_jiffy
;
62
__timer_delay(loops >>
UDELAY_SHIFT
);
63
}
64
65
static
void
__timer_udelay(
unsigned
long
usecs
)
66
{
67
__timer_const_udelay(usecs *
UDELAY_MULT
);
68
}
69
70
void
__init
register_current_timer_delay
(
const
struct
delay_timer *
timer
)
71
{
72
if
(!delay_calibrated) {
73
pr_info
(
"Switching to timer-based delay loop\n"
);
74
delay_timer =
timer
;
75
lpj_fine
= timer->
freq
/
HZ
;
76
loops_per_jiffy
=
lpj_fine
;
77
arm_delay_ops.
delay
= __timer_delay;
78
arm_delay_ops.
const_udelay
= __timer_const_udelay;
79
arm_delay_ops.
udelay
= __timer_udelay;
80
delay_calibrated =
true
;
81
}
else
{
82
pr_info
(
"Ignoring duplicate/late registration of read_current_timer delay\n"
);
83
}
84
}
85
86
unsigned
long
__cpuinit
calibrate_delay_is_known
(
void
)
87
{
88
delay_calibrated =
true
;
89
return
lpj_fine
;
90
}
Generated on Thu Jan 10 2013 12:56:28 for Linux Kernel by
1.8.2