diff options
Diffstat (limited to 'kernel/pm_qos_params.c')
-rw-r--r-- | kernel/pm_qos_params.c | 48 |
1 files changed, 23 insertions, 25 deletions
diff --git a/kernel/pm_qos_params.c b/kernel/pm_qos_params.c index 0afe32be4c85..dfdec524d1b7 100644 --- a/kernel/pm_qos_params.c +++ b/kernel/pm_qos_params.c | |||
@@ -24,11 +24,12 @@ | |||
24 | * requirement that the application has is cleaned up when closes the file | 24 | * requirement that the application has is cleaned up when closes the file |
25 | * pointer or exits the pm_qos_object will get an opportunity to clean up. | 25 | * pointer or exits the pm_qos_object will get an opportunity to clean up. |
26 | * | 26 | * |
27 | * mark gross mgross@linux.intel.com | 27 | * Mark Gross <mgross@linux.intel.com> |
28 | */ | 28 | */ |
29 | 29 | ||
30 | #include <linux/pm_qos_params.h> | 30 | #include <linux/pm_qos_params.h> |
31 | #include <linux/sched.h> | 31 | #include <linux/sched.h> |
32 | #include <linux/smp_lock.h> | ||
32 | #include <linux/spinlock.h> | 33 | #include <linux/spinlock.h> |
33 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
34 | #include <linux/time.h> | 35 | #include <linux/time.h> |
@@ -42,7 +43,7 @@ | |||
42 | #include <linux/uaccess.h> | 43 | #include <linux/uaccess.h> |
43 | 44 | ||
44 | /* | 45 | /* |
45 | * locking rule: all changes to target_value or requirements or notifiers lists | 46 | * locking rule: all changes to requirements or notifiers lists |
46 | * or pm_qos_object list and pm_qos_objects need to happen with pm_qos_lock | 47 | * or pm_qos_object list and pm_qos_objects need to happen with pm_qos_lock |
47 | * held, taken with _irqsave. One lock to rule them all | 48 | * held, taken with _irqsave. One lock to rule them all |
48 | */ | 49 | */ |
@@ -65,7 +66,7 @@ struct pm_qos_object { | |||
65 | struct miscdevice pm_qos_power_miscdev; | 66 | struct miscdevice pm_qos_power_miscdev; |
66 | char *name; | 67 | char *name; |
67 | s32 default_value; | 68 | s32 default_value; |
68 | s32 target_value; | 69 | atomic_t target_value; |
69 | s32 (*comparitor)(s32, s32); | 70 | s32 (*comparitor)(s32, s32); |
70 | }; | 71 | }; |
71 | 72 | ||
@@ -76,7 +77,7 @@ static struct pm_qos_object cpu_dma_pm_qos = { | |||
76 | .notifiers = &cpu_dma_lat_notifier, | 77 | .notifiers = &cpu_dma_lat_notifier, |
77 | .name = "cpu_dma_latency", | 78 | .name = "cpu_dma_latency", |
78 | .default_value = 2000 * USEC_PER_SEC, | 79 | .default_value = 2000 * USEC_PER_SEC, |
79 | .target_value = 2000 * USEC_PER_SEC, | 80 | .target_value = ATOMIC_INIT(2000 * USEC_PER_SEC), |
80 | .comparitor = min_compare | 81 | .comparitor = min_compare |
81 | }; | 82 | }; |
82 | 83 | ||
@@ -86,7 +87,7 @@ static struct pm_qos_object network_lat_pm_qos = { | |||
86 | .notifiers = &network_lat_notifier, | 87 | .notifiers = &network_lat_notifier, |
87 | .name = "network_latency", | 88 | .name = "network_latency", |
88 | .default_value = 2000 * USEC_PER_SEC, | 89 | .default_value = 2000 * USEC_PER_SEC, |
89 | .target_value = 2000 * USEC_PER_SEC, | 90 | .target_value = ATOMIC_INIT(2000 * USEC_PER_SEC), |
90 | .comparitor = min_compare | 91 | .comparitor = min_compare |
91 | }; | 92 | }; |
92 | 93 | ||
@@ -98,7 +99,7 @@ static struct pm_qos_object network_throughput_pm_qos = { | |||
98 | .notifiers = &network_throughput_notifier, | 99 | .notifiers = &network_throughput_notifier, |
99 | .name = "network_throughput", | 100 | .name = "network_throughput", |
100 | .default_value = 0, | 101 | .default_value = 0, |
101 | .target_value = 0, | 102 | .target_value = ATOMIC_INIT(0), |
102 | .comparitor = max_compare | 103 | .comparitor = max_compare |
103 | }; | 104 | }; |
104 | 105 | ||
@@ -149,11 +150,11 @@ static void update_target(int target) | |||
149 | extreme_value = pm_qos_array[target]->comparitor( | 150 | extreme_value = pm_qos_array[target]->comparitor( |
150 | extreme_value, node->value); | 151 | extreme_value, node->value); |
151 | } | 152 | } |
152 | if (pm_qos_array[target]->target_value != extreme_value) { | 153 | if (atomic_read(&pm_qos_array[target]->target_value) != extreme_value) { |
153 | call_notifier = 1; | 154 | call_notifier = 1; |
154 | pm_qos_array[target]->target_value = extreme_value; | 155 | atomic_set(&pm_qos_array[target]->target_value, extreme_value); |
155 | pr_debug(KERN_ERR "new target for qos %d is %d\n", target, | 156 | pr_debug(KERN_ERR "new target for qos %d is %d\n", target, |
156 | pm_qos_array[target]->target_value); | 157 | atomic_read(&pm_qos_array[target]->target_value)); |
157 | } | 158 | } |
158 | spin_unlock_irqrestore(&pm_qos_lock, flags); | 159 | spin_unlock_irqrestore(&pm_qos_lock, flags); |
159 | 160 | ||
@@ -192,14 +193,7 @@ static int find_pm_qos_object_by_minor(int minor) | |||
192 | */ | 193 | */ |
193 | int pm_qos_requirement(int pm_qos_class) | 194 | int pm_qos_requirement(int pm_qos_class) |
194 | { | 195 | { |
195 | int ret_val; | 196 | return atomic_read(&pm_qos_array[pm_qos_class]->target_value); |
196 | unsigned long flags; | ||
197 | |||
198 | spin_lock_irqsave(&pm_qos_lock, flags); | ||
199 | ret_val = pm_qos_array[pm_qos_class]->target_value; | ||
200 | spin_unlock_irqrestore(&pm_qos_lock, flags); | ||
201 | |||
202 | return ret_val; | ||
203 | } | 197 | } |
204 | EXPORT_SYMBOL_GPL(pm_qos_requirement); | 198 | EXPORT_SYMBOL_GPL(pm_qos_requirement); |
205 | 199 | ||
@@ -210,8 +204,8 @@ EXPORT_SYMBOL_GPL(pm_qos_requirement); | |||
210 | * @value: defines the qos request | 204 | * @value: defines the qos request |
211 | * | 205 | * |
212 | * This function inserts a new entry in the pm_qos_class list of requested qos | 206 | * This function inserts a new entry in the pm_qos_class list of requested qos |
213 | * performance charactoistics. It recomputes the agregate QoS expectations for | 207 | * performance characteristics. It recomputes the aggregate QoS expectations |
214 | * the pm_qos_class of parrameters. | 208 | * for the pm_qos_class of parameters. |
215 | */ | 209 | */ |
216 | int pm_qos_add_requirement(int pm_qos_class, char *name, s32 value) | 210 | int pm_qos_add_requirement(int pm_qos_class, char *name, s32 value) |
217 | { | 211 | { |
@@ -249,10 +243,10 @@ EXPORT_SYMBOL_GPL(pm_qos_add_requirement); | |||
249 | * @name: identifies the request | 243 | * @name: identifies the request |
250 | * @value: defines the qos request | 244 | * @value: defines the qos request |
251 | * | 245 | * |
252 | * Updates an existing qos requierement for the pm_qos_class of parameters along | 246 | * Updates an existing qos requirement for the pm_qos_class of parameters along |
253 | * with updating the target pm_qos_class value. | 247 | * with updating the target pm_qos_class value. |
254 | * | 248 | * |
255 | * If the named request isn't in the lest then no change is made. | 249 | * If the named request isn't in the list then no change is made. |
256 | */ | 250 | */ |
257 | int pm_qos_update_requirement(int pm_qos_class, char *name, s32 new_value) | 251 | int pm_qos_update_requirement(int pm_qos_class, char *name, s32 new_value) |
258 | { | 252 | { |
@@ -286,7 +280,7 @@ EXPORT_SYMBOL_GPL(pm_qos_update_requirement); | |||
286 | * @pm_qos_class: identifies which list of qos request to us | 280 | * @pm_qos_class: identifies which list of qos request to us |
287 | * @name: identifies the request | 281 | * @name: identifies the request |
288 | * | 282 | * |
289 | * Will remove named qos request from pm_qos_class list of parrameters and | 283 | * Will remove named qos request from pm_qos_class list of parameters and |
290 | * recompute the current target value for the pm_qos_class. | 284 | * recompute the current target value for the pm_qos_class. |
291 | */ | 285 | */ |
292 | void pm_qos_remove_requirement(int pm_qos_class, char *name) | 286 | void pm_qos_remove_requirement(int pm_qos_class, char *name) |
@@ -318,7 +312,7 @@ EXPORT_SYMBOL_GPL(pm_qos_remove_requirement); | |||
318 | * @notifier: notifier block managed by caller. | 312 | * @notifier: notifier block managed by caller. |
319 | * | 313 | * |
320 | * will register the notifier into a notification chain that gets called | 314 | * will register the notifier into a notification chain that gets called |
321 | * uppon changes to the pm_qos_class target value. | 315 | * upon changes to the pm_qos_class target value. |
322 | */ | 316 | */ |
323 | int pm_qos_add_notifier(int pm_qos_class, struct notifier_block *notifier) | 317 | int pm_qos_add_notifier(int pm_qos_class, struct notifier_block *notifier) |
324 | { | 318 | { |
@@ -337,7 +331,7 @@ EXPORT_SYMBOL_GPL(pm_qos_add_notifier); | |||
337 | * @notifier: notifier block to be removed. | 331 | * @notifier: notifier block to be removed. |
338 | * | 332 | * |
339 | * will remove the notifier from the notification chain that gets called | 333 | * will remove the notifier from the notification chain that gets called |
340 | * uppon changes to the pm_qos_class target value. | 334 | * upon changes to the pm_qos_class target value. |
341 | */ | 335 | */ |
342 | int pm_qos_remove_notifier(int pm_qos_class, struct notifier_block *notifier) | 336 | int pm_qos_remove_notifier(int pm_qos_class, struct notifier_block *notifier) |
343 | { | 337 | { |
@@ -358,15 +352,19 @@ static int pm_qos_power_open(struct inode *inode, struct file *filp) | |||
358 | int ret; | 352 | int ret; |
359 | long pm_qos_class; | 353 | long pm_qos_class; |
360 | 354 | ||
355 | lock_kernel(); | ||
361 | pm_qos_class = find_pm_qos_object_by_minor(iminor(inode)); | 356 | pm_qos_class = find_pm_qos_object_by_minor(iminor(inode)); |
362 | if (pm_qos_class >= 0) { | 357 | if (pm_qos_class >= 0) { |
363 | filp->private_data = (void *)pm_qos_class; | 358 | filp->private_data = (void *)pm_qos_class; |
364 | sprintf(name, "process_%d", current->pid); | 359 | sprintf(name, "process_%d", current->pid); |
365 | ret = pm_qos_add_requirement(pm_qos_class, name, | 360 | ret = pm_qos_add_requirement(pm_qos_class, name, |
366 | PM_QOS_DEFAULT_VALUE); | 361 | PM_QOS_DEFAULT_VALUE); |
367 | if (ret >= 0) | 362 | if (ret >= 0) { |
363 | unlock_kernel(); | ||
368 | return 0; | 364 | return 0; |
365 | } | ||
369 | } | 366 | } |
367 | unlock_kernel(); | ||
370 | 368 | ||
371 | return -EPERM; | 369 | return -EPERM; |
372 | } | 370 | } |