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
drivers
cpuidle
driver.c
Go to the documentation of this file.
1
/*
2
* driver.c - driver support
3
*
4
* (C) 2006-2007 Venkatesh Pallipadi <
[email protected]
>
5
* Shaohua Li <
[email protected]
>
6
* Adam Belay <
[email protected]
>
7
*
8
* This code is licenced under the GPL.
9
*/
10
11
#include <
linux/mutex.h
>
12
#include <linux/module.h>
13
#include <
linux/cpuidle.h
>
14
15
#include "
cpuidle.h
"
16
17
static
struct
cpuidle_driver
*cpuidle_curr_driver;
18
DEFINE_SPINLOCK
(cpuidle_driver_lock);
19
int
cpuidle_driver_refcount
;
20
21
static
void
set_power_states(
struct
cpuidle_driver
*drv)
22
{
23
int
i
;
24
25
/*
26
* cpuidle driver should set the drv->power_specified bit
27
* before registering if the driver provides
28
* power_usage numbers.
29
*
30
* If power_specified is not set,
31
* we fill in power_usage with decreasing values as the
32
* cpuidle code has an implicit assumption that state Cn
33
* uses less power than C(n-1).
34
*
35
* With CONFIG_ARCH_HAS_CPU_RELAX, C0 is already assigned
36
* an power value of -1. So we use -2, -3, etc, for other
37
* c-states.
38
*/
39
for
(i =
CPUIDLE_DRIVER_STATE_START
; i < drv->
state_count
; i++)
40
drv->
states
[i].power_usage = -1 - i;
41
}
42
47
int
cpuidle_register_driver
(
struct
cpuidle_driver
*drv)
48
{
49
if
(!drv || !drv->
state_count
)
50
return
-
EINVAL
;
51
52
if
(
cpuidle_disabled
())
53
return
-
ENODEV
;
54
55
spin_lock(&
cpuidle_driver_lock
);
56
if
(cpuidle_curr_driver) {
57
spin_unlock(&
cpuidle_driver_lock
);
58
return
-
EBUSY
;
59
}
60
61
if
(!drv->
power_specified
)
62
set_power_states(drv);
63
64
cpuidle_curr_driver = drv;
65
66
spin_unlock(&
cpuidle_driver_lock
);
67
68
return
0;
69
}
70
EXPORT_SYMBOL_GPL
(
cpuidle_register_driver
);
71
75
struct
cpuidle_driver
*
cpuidle_get_driver
(
void
)
76
{
77
return
cpuidle_curr_driver;
78
}
79
EXPORT_SYMBOL_GPL
(
cpuidle_get_driver
);
80
85
void
cpuidle_unregister_driver
(
struct
cpuidle_driver
*drv)
86
{
87
if
(drv != cpuidle_curr_driver) {
88
WARN
(1,
"invalid cpuidle_unregister_driver(%s)\n"
,
89
drv->
name
);
90
return
;
91
}
92
93
spin_lock(&
cpuidle_driver_lock
);
94
95
if
(!
WARN_ON
(
cpuidle_driver_refcount
> 0))
96
cpuidle_curr_driver =
NULL
;
97
98
spin_unlock(&
cpuidle_driver_lock
);
99
}
100
EXPORT_SYMBOL_GPL
(
cpuidle_unregister_driver
);
101
102
struct
cpuidle_driver
*
cpuidle_driver_ref
(
void
)
103
{
104
struct
cpuidle_driver
*drv;
105
106
spin_lock(&
cpuidle_driver_lock
);
107
108
drv = cpuidle_curr_driver;
109
cpuidle_driver_refcount
++;
110
111
spin_unlock(&
cpuidle_driver_lock
);
112
return
drv;
113
}
114
115
void
cpuidle_driver_unref
(
void
)
116
{
117
spin_lock(&
cpuidle_driver_lock
);
118
119
if
(!
WARN_ON
(
cpuidle_driver_refcount
<= 0))
120
cpuidle_driver_refcount
--;
121
122
spin_unlock(&
cpuidle_driver_lock
);
123
}
Generated on Thu Jan 10 2013 13:12:59 for Linux Kernel by
1.8.2