Root/
1 | /* |
2 | * governor.c - governor support |
3 | * |
4 | * (C) 2006-2007 Venkatesh Pallipadi <venkatesh.pallipadi@intel.com> |
5 | * Shaohua Li <shaohua.li@intel.com> |
6 | * Adam Belay <abelay@novell.com> |
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 | LIST_HEAD(cpuidle_governors); |
18 | struct cpuidle_governor *cpuidle_curr_governor; |
19 | |
20 | /** |
21 | * __cpuidle_find_governor - finds a governor of the specified name |
22 | * @str: the name |
23 | * |
24 | * Must be called with cpuidle_lock acquired. |
25 | */ |
26 | static struct cpuidle_governor * __cpuidle_find_governor(const char *str) |
27 | { |
28 | struct cpuidle_governor *gov; |
29 | |
30 | list_for_each_entry(gov, &cpuidle_governors, governor_list) |
31 | if (!strnicmp(str, gov->name, CPUIDLE_NAME_LEN)) |
32 | return gov; |
33 | |
34 | return NULL; |
35 | } |
36 | |
37 | /** |
38 | * cpuidle_switch_governor - changes the governor |
39 | * @gov: the new target governor |
40 | * |
41 | * NOTE: "gov" can be NULL to specify disabled |
42 | * Must be called with cpuidle_lock acquired. |
43 | */ |
44 | int cpuidle_switch_governor(struct cpuidle_governor *gov) |
45 | { |
46 | struct cpuidle_device *dev; |
47 | |
48 | if (gov == cpuidle_curr_governor) |
49 | return 0; |
50 | |
51 | cpuidle_uninstall_idle_handler(); |
52 | |
53 | if (cpuidle_curr_governor) { |
54 | list_for_each_entry(dev, &cpuidle_detected_devices, device_list) |
55 | cpuidle_disable_device(dev); |
56 | module_put(cpuidle_curr_governor->owner); |
57 | } |
58 | |
59 | cpuidle_curr_governor = gov; |
60 | |
61 | if (gov) { |
62 | if (!try_module_get(cpuidle_curr_governor->owner)) |
63 | return -EINVAL; |
64 | list_for_each_entry(dev, &cpuidle_detected_devices, device_list) |
65 | cpuidle_enable_device(dev); |
66 | cpuidle_install_idle_handler(); |
67 | printk(KERN_INFO "cpuidle: using governor %s\n", gov->name); |
68 | } |
69 | |
70 | return 0; |
71 | } |
72 | |
73 | /** |
74 | * cpuidle_register_governor - registers a governor |
75 | * @gov: the governor |
76 | */ |
77 | int cpuidle_register_governor(struct cpuidle_governor *gov) |
78 | { |
79 | int ret = -EEXIST; |
80 | |
81 | if (!gov || !gov->select) |
82 | return -EINVAL; |
83 | |
84 | if (cpuidle_disabled()) |
85 | return -ENODEV; |
86 | |
87 | mutex_lock(&cpuidle_lock); |
88 | if (__cpuidle_find_governor(gov->name) == NULL) { |
89 | ret = 0; |
90 | list_add_tail(&gov->governor_list, &cpuidle_governors); |
91 | if (!cpuidle_curr_governor || |
92 | cpuidle_curr_governor->rating < gov->rating) |
93 | cpuidle_switch_governor(gov); |
94 | } |
95 | mutex_unlock(&cpuidle_lock); |
96 | |
97 | return ret; |
98 | } |
99 | |
100 | /** |
101 | * cpuidle_replace_governor - find a replacement governor |
102 | * @exclude_rating: the rating that will be skipped while looking for |
103 | * new governor. |
104 | */ |
105 | static struct cpuidle_governor *cpuidle_replace_governor(int exclude_rating) |
106 | { |
107 | struct cpuidle_governor *gov; |
108 | struct cpuidle_governor *ret_gov = NULL; |
109 | unsigned int max_rating = 0; |
110 | |
111 | list_for_each_entry(gov, &cpuidle_governors, governor_list) { |
112 | if (gov->rating == exclude_rating) |
113 | continue; |
114 | if (gov->rating > max_rating) { |
115 | max_rating = gov->rating; |
116 | ret_gov = gov; |
117 | } |
118 | } |
119 | |
120 | return ret_gov; |
121 | } |
122 | |
123 | /** |
124 | * cpuidle_unregister_governor - unregisters a governor |
125 | * @gov: the governor |
126 | */ |
127 | void cpuidle_unregister_governor(struct cpuidle_governor *gov) |
128 | { |
129 | if (!gov) |
130 | return; |
131 | |
132 | mutex_lock(&cpuidle_lock); |
133 | if (gov == cpuidle_curr_governor) { |
134 | struct cpuidle_governor *new_gov; |
135 | new_gov = cpuidle_replace_governor(gov->rating); |
136 | cpuidle_switch_governor(new_gov); |
137 | } |
138 | list_del(&gov->governor_list); |
139 | mutex_unlock(&cpuidle_lock); |
140 | } |
141 | |
142 |
Branches:
ben-wpan
ben-wpan-stefan
javiroman/ks7010
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9