diff options
author | Rafael J. Wysocki <rjw@sisk.pl> | 2012-07-03 13:07:21 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rjw@sisk.pl> | 2012-07-03 13:07:21 -0400 |
commit | e3b8cdd8e4ea51e46d3ff54d7e3568afc24654ec (patch) | |
tree | 0acfb0801d94d7222a752c40fb611dff00280803 /drivers/cpuidle | |
parent | 80de3d7f416f1accd03f2e519ead32d6fde4fcf4 (diff) | |
parent | 6e797a078824b30afbfae6cc4b1c2b21c51761ef (diff) |
Merge branch 'pm-cpuidle' into pm-domains
* pm-cpuidle:
PM / cpuidle: Add driver reference counter
cpuidle: move field disable from per-driver to per-cpu
Diffstat (limited to 'drivers/cpuidle')
-rw-r--r-- | drivers/cpuidle/cpuidle.c | 1 | ||||
-rw-r--r-- | drivers/cpuidle/driver.c | 29 | ||||
-rw-r--r-- | drivers/cpuidle/governors/menu.c | 5 | ||||
-rw-r--r-- | drivers/cpuidle/sysfs.c | 21 |
4 files changed, 43 insertions, 13 deletions
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index d90519cec880..04e4b7674a47 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c | |||
@@ -265,7 +265,6 @@ static void poll_idle_init(struct cpuidle_driver *drv) | |||
265 | state->power_usage = -1; | 265 | state->power_usage = -1; |
266 | state->flags = 0; | 266 | state->flags = 0; |
267 | state->enter = poll_idle; | 267 | state->enter = poll_idle; |
268 | state->disable = 0; | ||
269 | } | 268 | } |
270 | #else | 269 | #else |
271 | static void poll_idle_init(struct cpuidle_driver *drv) {} | 270 | static void poll_idle_init(struct cpuidle_driver *drv) {} |
diff --git a/drivers/cpuidle/driver.c b/drivers/cpuidle/driver.c index 40cd3f3024df..58bf3b1ac9c4 100644 --- a/drivers/cpuidle/driver.c +++ b/drivers/cpuidle/driver.c | |||
@@ -16,6 +16,7 @@ | |||
16 | 16 | ||
17 | static struct cpuidle_driver *cpuidle_curr_driver; | 17 | static struct cpuidle_driver *cpuidle_curr_driver; |
18 | DEFINE_SPINLOCK(cpuidle_driver_lock); | 18 | DEFINE_SPINLOCK(cpuidle_driver_lock); |
19 | int cpuidle_driver_refcount; | ||
19 | 20 | ||
20 | static void __cpuidle_register_driver(struct cpuidle_driver *drv) | 21 | static void __cpuidle_register_driver(struct cpuidle_driver *drv) |
21 | { | 22 | { |
@@ -89,8 +90,34 @@ void cpuidle_unregister_driver(struct cpuidle_driver *drv) | |||
89 | } | 90 | } |
90 | 91 | ||
91 | spin_lock(&cpuidle_driver_lock); | 92 | spin_lock(&cpuidle_driver_lock); |
92 | cpuidle_curr_driver = NULL; | 93 | |
94 | if (!WARN_ON(cpuidle_driver_refcount > 0)) | ||
95 | cpuidle_curr_driver = NULL; | ||
96 | |||
93 | spin_unlock(&cpuidle_driver_lock); | 97 | spin_unlock(&cpuidle_driver_lock); |
94 | } | 98 | } |
95 | 99 | ||
96 | EXPORT_SYMBOL_GPL(cpuidle_unregister_driver); | 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 | } | ||
diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c index 06335756ea14..8391d93f57d5 100644 --- a/drivers/cpuidle/governors/menu.c +++ b/drivers/cpuidle/governors/menu.c | |||
@@ -281,7 +281,7 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev) | |||
281 | * unless the timer is happening really really soon. | 281 | * unless the timer is happening really really soon. |
282 | */ | 282 | */ |
283 | if (data->expected_us > 5 && | 283 | if (data->expected_us > 5 && |
284 | drv->states[CPUIDLE_DRIVER_STATE_START].disable == 0) | 284 | dev->states_usage[CPUIDLE_DRIVER_STATE_START].disable == 0) |
285 | data->last_state_idx = CPUIDLE_DRIVER_STATE_START; | 285 | data->last_state_idx = CPUIDLE_DRIVER_STATE_START; |
286 | 286 | ||
287 | /* | 287 | /* |
@@ -290,8 +290,9 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev) | |||
290 | */ | 290 | */ |
291 | for (i = CPUIDLE_DRIVER_STATE_START; i < drv->state_count; i++) { | 291 | for (i = CPUIDLE_DRIVER_STATE_START; i < drv->state_count; i++) { |
292 | struct cpuidle_state *s = &drv->states[i]; | 292 | struct cpuidle_state *s = &drv->states[i]; |
293 | struct cpuidle_state_usage *su = &dev->states_usage[i]; | ||
293 | 294 | ||
294 | if (s->disable) | 295 | if (su->disable) |
295 | continue; | 296 | continue; |
296 | if (s->target_residency > data->predicted_us) | 297 | if (s->target_residency > data->predicted_us) |
297 | continue; | 298 | continue; |
diff --git a/drivers/cpuidle/sysfs.c b/drivers/cpuidle/sysfs.c index 88032b4dc6d2..5f809e337b89 100644 --- a/drivers/cpuidle/sysfs.c +++ b/drivers/cpuidle/sysfs.c | |||
@@ -217,7 +217,8 @@ struct cpuidle_state_attr { | |||
217 | struct attribute attr; | 217 | struct attribute attr; |
218 | ssize_t (*show)(struct cpuidle_state *, \ | 218 | ssize_t (*show)(struct cpuidle_state *, \ |
219 | struct cpuidle_state_usage *, char *); | 219 | struct cpuidle_state_usage *, char *); |
220 | ssize_t (*store)(struct cpuidle_state *, const char *, size_t); | 220 | ssize_t (*store)(struct cpuidle_state *, \ |
221 | struct cpuidle_state_usage *, const char *, size_t); | ||
221 | }; | 222 | }; |
222 | 223 | ||
223 | #define define_one_state_ro(_name, show) \ | 224 | #define define_one_state_ro(_name, show) \ |
@@ -233,21 +234,22 @@ static ssize_t show_state_##_name(struct cpuidle_state *state, \ | |||
233 | return sprintf(buf, "%u\n", state->_name);\ | 234 | return sprintf(buf, "%u\n", state->_name);\ |
234 | } | 235 | } |
235 | 236 | ||
236 | #define define_store_state_function(_name) \ | 237 | #define define_store_state_ull_function(_name) \ |
237 | static ssize_t store_state_##_name(struct cpuidle_state *state, \ | 238 | static ssize_t store_state_##_name(struct cpuidle_state *state, \ |
239 | struct cpuidle_state_usage *state_usage, \ | ||
238 | const char *buf, size_t size) \ | 240 | const char *buf, size_t size) \ |
239 | { \ | 241 | { \ |
240 | long value; \ | 242 | unsigned long long value; \ |
241 | int err; \ | 243 | int err; \ |
242 | if (!capable(CAP_SYS_ADMIN)) \ | 244 | if (!capable(CAP_SYS_ADMIN)) \ |
243 | return -EPERM; \ | 245 | return -EPERM; \ |
244 | err = kstrtol(buf, 0, &value); \ | 246 | err = kstrtoull(buf, 0, &value); \ |
245 | if (err) \ | 247 | if (err) \ |
246 | return err; \ | 248 | return err; \ |
247 | if (value) \ | 249 | if (value) \ |
248 | state->disable = 1; \ | 250 | state_usage->_name = 1; \ |
249 | else \ | 251 | else \ |
250 | state->disable = 0; \ | 252 | state_usage->_name = 0; \ |
251 | return size; \ | 253 | return size; \ |
252 | } | 254 | } |
253 | 255 | ||
@@ -273,8 +275,8 @@ define_show_state_ull_function(usage) | |||
273 | define_show_state_ull_function(time) | 275 | define_show_state_ull_function(time) |
274 | define_show_state_str_function(name) | 276 | define_show_state_str_function(name) |
275 | define_show_state_str_function(desc) | 277 | define_show_state_str_function(desc) |
276 | define_show_state_function(disable) | 278 | define_show_state_ull_function(disable) |
277 | define_store_state_function(disable) | 279 | define_store_state_ull_function(disable) |
278 | 280 | ||
279 | define_one_state_ro(name, show_state_name); | 281 | define_one_state_ro(name, show_state_name); |
280 | define_one_state_ro(desc, show_state_desc); | 282 | define_one_state_ro(desc, show_state_desc); |
@@ -318,10 +320,11 @@ static ssize_t cpuidle_state_store(struct kobject *kobj, | |||
318 | { | 320 | { |
319 | int ret = -EIO; | 321 | int ret = -EIO; |
320 | struct cpuidle_state *state = kobj_to_state(kobj); | 322 | struct cpuidle_state *state = kobj_to_state(kobj); |
323 | struct cpuidle_state_usage *state_usage = kobj_to_state_usage(kobj); | ||
321 | struct cpuidle_state_attr *cattr = attr_to_stateattr(attr); | 324 | struct cpuidle_state_attr *cattr = attr_to_stateattr(attr); |
322 | 325 | ||
323 | if (cattr->store) | 326 | if (cattr->store) |
324 | ret = cattr->store(state, buf, size); | 327 | ret = cattr->store(state, state_usage, buf, size); |
325 | 328 | ||
326 | return ret; | 329 | return ret; |
327 | } | 330 | } |