diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/pm_qos_params.c | 67 |
1 files changed, 40 insertions, 27 deletions
diff --git a/kernel/pm_qos_params.c b/kernel/pm_qos_params.c index db8e51d7f392..996a4dec5f96 100644 --- a/kernel/pm_qos_params.c +++ b/kernel/pm_qos_params.c | |||
| @@ -30,7 +30,6 @@ | |||
| 30 | /*#define DEBUG*/ | 30 | /*#define DEBUG*/ |
| 31 | 31 | ||
| 32 | #include <linux/pm_qos_params.h> | 32 | #include <linux/pm_qos_params.h> |
| 33 | #include <linux/plist.h> | ||
| 34 | #include <linux/sched.h> | 33 | #include <linux/sched.h> |
| 35 | #include <linux/spinlock.h> | 34 | #include <linux/spinlock.h> |
| 36 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
| @@ -49,11 +48,6 @@ | |||
| 49 | * or pm_qos_object list and pm_qos_objects need to happen with pm_qos_lock | 48 | * or pm_qos_object list and pm_qos_objects need to happen with pm_qos_lock |
| 50 | * held, taken with _irqsave. One lock to rule them all | 49 | * held, taken with _irqsave. One lock to rule them all |
| 51 | */ | 50 | */ |
| 52 | struct pm_qos_request_list { | ||
| 53 | struct plist_node list; | ||
| 54 | int pm_qos_class; | ||
| 55 | }; | ||
| 56 | |||
| 57 | enum pm_qos_type { | 51 | enum pm_qos_type { |
| 58 | PM_QOS_MAX, /* return the largest value */ | 52 | PM_QOS_MAX, /* return the largest value */ |
| 59 | PM_QOS_MIN /* return the smallest value */ | 53 | PM_QOS_MIN /* return the smallest value */ |
| @@ -210,6 +204,12 @@ int pm_qos_request(int pm_qos_class) | |||
| 210 | } | 204 | } |
| 211 | EXPORT_SYMBOL_GPL(pm_qos_request); | 205 | EXPORT_SYMBOL_GPL(pm_qos_request); |
| 212 | 206 | ||
| 207 | int pm_qos_request_active(struct pm_qos_request_list *req) | ||
| 208 | { | ||
| 209 | return req->pm_qos_class != 0; | ||
| 210 | } | ||
| 211 | EXPORT_SYMBOL_GPL(pm_qos_request_active); | ||
| 212 | |||
| 213 | /** | 213 | /** |
| 214 | * pm_qos_add_request - inserts new qos request into the list | 214 | * pm_qos_add_request - inserts new qos request into the list |
| 215 | * @pm_qos_class: identifies which list of qos request to us | 215 | * @pm_qos_class: identifies which list of qos request to us |
| @@ -221,25 +221,23 @@ EXPORT_SYMBOL_GPL(pm_qos_request); | |||
| 221 | * element as a handle for use in updating and removal. Call needs to save | 221 | * element as a handle for use in updating and removal. Call needs to save |
| 222 | * this handle for later use. | 222 | * this handle for later use. |
| 223 | */ | 223 | */ |
| 224 | struct pm_qos_request_list *pm_qos_add_request(int pm_qos_class, s32 value) | 224 | void pm_qos_add_request(struct pm_qos_request_list *dep, |
| 225 | int pm_qos_class, s32 value) | ||
| 225 | { | 226 | { |
| 226 | struct pm_qos_request_list *dep; | 227 | struct pm_qos_object *o = pm_qos_array[pm_qos_class]; |
| 227 | 228 | int new_value; | |
| 228 | dep = kzalloc(sizeof(struct pm_qos_request_list), GFP_KERNEL); | ||
| 229 | if (dep) { | ||
| 230 | struct pm_qos_object *o = pm_qos_array[pm_qos_class]; | ||
| 231 | int new_value; | ||
| 232 | |||
| 233 | if (value == PM_QOS_DEFAULT_VALUE) | ||
| 234 | new_value = o->default_value; | ||
| 235 | else | ||
| 236 | new_value = value; | ||
| 237 | plist_node_init(&dep->list, new_value); | ||
| 238 | dep->pm_qos_class = pm_qos_class; | ||
| 239 | update_target(o, &dep->list, 0, PM_QOS_DEFAULT_VALUE); | ||
| 240 | } | ||
| 241 | 229 | ||
| 242 | return dep; | 230 | if (pm_qos_request_active(dep)) { |
| 231 | WARN(1, KERN_ERR "pm_qos_add_request() called for already added request\n"); | ||
| 232 | return; | ||
| 233 | } | ||
| 234 | if (value == PM_QOS_DEFAULT_VALUE) | ||
| 235 | new_value = o->default_value; | ||
| 236 | else | ||
| 237 | new_value = value; | ||
| 238 | plist_node_init(&dep->list, new_value); | ||
| 239 | dep->pm_qos_class = pm_qos_class; | ||
| 240 | update_target(o, &dep->list, 0, PM_QOS_DEFAULT_VALUE); | ||
| 243 | } | 241 | } |
| 244 | EXPORT_SYMBOL_GPL(pm_qos_add_request); | 242 | EXPORT_SYMBOL_GPL(pm_qos_add_request); |
| 245 | 243 | ||
| @@ -262,6 +260,11 @@ void pm_qos_update_request(struct pm_qos_request_list *pm_qos_req, | |||
| 262 | if (!pm_qos_req) /*guard against callers passing in null */ | 260 | if (!pm_qos_req) /*guard against callers passing in null */ |
| 263 | return; | 261 | return; |
| 264 | 262 | ||
| 263 | if (!pm_qos_request_active(pm_qos_req)) { | ||
| 264 | WARN(1, KERN_ERR "pm_qos_update_request() called for unknown object\n"); | ||
| 265 | return; | ||
| 266 | } | ||
| 267 | |||
| 265 | o = pm_qos_array[pm_qos_req->pm_qos_class]; | 268 | o = pm_qos_array[pm_qos_req->pm_qos_class]; |
| 266 | 269 | ||
| 267 | if (new_value == PM_QOS_DEFAULT_VALUE) | 270 | if (new_value == PM_QOS_DEFAULT_VALUE) |
| @@ -290,9 +293,14 @@ void pm_qos_remove_request(struct pm_qos_request_list *pm_qos_req) | |||
| 290 | return; | 293 | return; |
| 291 | /* silent return to keep pcm code cleaner */ | 294 | /* silent return to keep pcm code cleaner */ |
| 292 | 295 | ||
| 296 | if (!pm_qos_request_active(pm_qos_req)) { | ||
| 297 | WARN(1, KERN_ERR "pm_qos_remove_request() called for unknown object\n"); | ||
| 298 | return; | ||
| 299 | } | ||
| 300 | |||
| 293 | o = pm_qos_array[pm_qos_req->pm_qos_class]; | 301 | o = pm_qos_array[pm_qos_req->pm_qos_class]; |
| 294 | update_target(o, &pm_qos_req->list, 1, PM_QOS_DEFAULT_VALUE); | 302 | update_target(o, &pm_qos_req->list, 1, PM_QOS_DEFAULT_VALUE); |
| 295 | kfree(pm_qos_req); | 303 | memset(pm_qos_req, 0, sizeof(*pm_qos_req)); |
| 296 | } | 304 | } |
| 297 | EXPORT_SYMBOL_GPL(pm_qos_remove_request); | 305 | EXPORT_SYMBOL_GPL(pm_qos_remove_request); |
| 298 | 306 | ||
| @@ -340,8 +348,12 @@ static int pm_qos_power_open(struct inode *inode, struct file *filp) | |||
| 340 | 348 | ||
| 341 | pm_qos_class = find_pm_qos_object_by_minor(iminor(inode)); | 349 | pm_qos_class = find_pm_qos_object_by_minor(iminor(inode)); |
| 342 | if (pm_qos_class >= 0) { | 350 | if (pm_qos_class >= 0) { |
| 343 | filp->private_data = (void *) pm_qos_add_request(pm_qos_class, | 351 | struct pm_qos_request_list *req = kzalloc(GFP_KERNEL, sizeof(*req)); |
| 344 | PM_QOS_DEFAULT_VALUE); | 352 | if (!req) |
| 353 | return -ENOMEM; | ||
| 354 | |||
| 355 | pm_qos_add_request(req, pm_qos_class, PM_QOS_DEFAULT_VALUE); | ||
| 356 | filp->private_data = req; | ||
| 345 | 357 | ||
| 346 | if (filp->private_data) | 358 | if (filp->private_data) |
| 347 | return 0; | 359 | return 0; |
| @@ -353,8 +365,9 @@ static int pm_qos_power_release(struct inode *inode, struct file *filp) | |||
| 353 | { | 365 | { |
| 354 | struct pm_qos_request_list *req; | 366 | struct pm_qos_request_list *req; |
| 355 | 367 | ||
| 356 | req = (struct pm_qos_request_list *)filp->private_data; | 368 | req = filp->private_data; |
| 357 | pm_qos_remove_request(req); | 369 | pm_qos_remove_request(req); |
| 370 | kfree(req); | ||
| 358 | 371 | ||
| 359 | return 0; | 372 | return 0; |
| 360 | } | 373 | } |
