Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'pm-qos' into pm-for-linus

* pm-qos:
PM / QoS: Update Documentation for the pm_qos and dev_pm_qos frameworks
PM / QoS: Add function dev_pm_qos_read_value() (v3)
PM QoS: Add global notification mechanism for device constraints
PM QoS: Implement per-device PM QoS constraints
PM QoS: Generalize and export constraints management code
PM QoS: Reorganize data structs
PM QoS: Code reorganization
PM QoS: Minor clean-ups
PM QoS: Move and rename the implementation files

+926 -285
+87 -5
Documentation/power/pm_qos_interface.txt
··· 4 4 performance expectations by drivers, subsystems and user space applications on 5 5 one of the parameters. 6 6 7 - Currently we have {cpu_dma_latency, network_latency, network_throughput} as the 8 - initial set of pm_qos parameters. 7 + Two different PM QoS frameworks are available: 8 + 1. PM QoS classes for cpu_dma_latency, network_latency, network_throughput. 9 + 2. the per-device PM QoS framework provides the API to manage the per-device latency 10 + constraints. 9 11 10 12 Each parameters have defined units: 11 13 * latency: usec 12 14 * timeout: usec 13 15 * throughput: kbs (kilo bit / sec) 16 + 17 + 18 + 1. PM QoS framework 14 19 15 20 The infrastructure exposes multiple misc device nodes one per implemented 16 21 parameter. The set of parameters implement is defined by pm_qos_power_init() ··· 28 23 changes to the request list or elements of the list. Typically the 29 24 aggregated target value is simply the max or min of the request values held 30 25 in the parameter list elements. 26 + Note: the aggregated target value is implemented as an atomic variable so that 27 + reading the aggregated value does not require any locking mechanism. 28 + 31 29 32 30 From kernel mode the use of this interface is simple: 33 31 34 - handle = pm_qos_add_request(param_class, target_value): 35 - Will insert an element into the list for that identified PM_QOS class with the 32 + void pm_qos_add_request(handle, param_class, target_value): 33 + Will insert an element into the list for that identified PM QoS class with the 36 34 target value. Upon change to this list the new target is recomputed and any 37 35 registered notifiers are called only if the target value is now different. 38 - Clients of pm_qos need to save the returned handle. 36 + Clients of pm_qos need to save the returned handle for future use in other 37 + pm_qos API functions. 39 38 40 39 void pm_qos_update_request(handle, new_target_value): 41 40 Will update the list element pointed to by the handle with the new target value ··· 50 41 Will remove the element. After removal it will update the aggregate target and 51 42 call the notification tree if the target was changed as a result of removing 52 43 the request. 44 + 45 + int pm_qos_request(param_class): 46 + Returns the aggregated value for a given PM QoS class. 47 + 48 + int pm_qos_request_active(handle): 49 + Returns if the request is still active, i.e. it has not been removed from a 50 + PM QoS class constraints list. 51 + 52 + int pm_qos_add_notifier(param_class, notifier): 53 + Adds a notification callback function to the PM QoS class. The callback is 54 + called when the aggregated value for the PM QoS class is changed. 55 + 56 + int pm_qos_remove_notifier(int param_class, notifier): 57 + Removes the notification callback function for the PM QoS class. 53 58 54 59 55 60 From user mode: ··· 86 63 node. 87 64 88 65 66 + 2. PM QoS per-device latency framework 67 + 68 + For each device a list of performance requests is maintained along with 69 + an aggregated target value. The aggregated target value is updated with 70 + changes to the request list or elements of the list. Typically the 71 + aggregated target value is simply the max or min of the request values held 72 + in the parameter list elements. 73 + Note: the aggregated target value is implemented as an atomic variable so that 74 + reading the aggregated value does not require any locking mechanism. 75 + 76 + 77 + From kernel mode the use of this interface is the following: 78 + 79 + int dev_pm_qos_add_request(device, handle, value): 80 + Will insert an element into the list for that identified device with the 81 + target value. Upon change to this list the new target is recomputed and any 82 + registered notifiers are called only if the target value is now different. 83 + Clients of dev_pm_qos need to save the handle for future use in other 84 + dev_pm_qos API functions. 85 + 86 + int dev_pm_qos_update_request(handle, new_value): 87 + Will update the list element pointed to by the handle with the new target value 88 + and recompute the new aggregated target, calling the notification trees if the 89 + target is changed. 90 + 91 + int dev_pm_qos_remove_request(handle): 92 + Will remove the element. After removal it will update the aggregate target and 93 + call the notification trees if the target was changed as a result of removing 94 + the request. 95 + 96 + s32 dev_pm_qos_read_value(device): 97 + Returns the aggregated value for a given device's constraints list. 98 + 99 + 100 + Notification mechanisms: 101 + The per-device PM QoS framework has 2 different and distinct notification trees: 102 + a per-device notification tree and a global notification tree. 103 + 104 + int dev_pm_qos_add_notifier(device, notifier): 105 + Adds a notification callback function for the device. 106 + The callback is called when the aggregated value of the device constraints list 107 + is changed. 108 + 109 + int dev_pm_qos_remove_notifier(device, notifier): 110 + Removes the notification callback function for the device. 111 + 112 + int dev_pm_qos_add_global_notifier(notifier): 113 + Adds a notification callback function in the global notification tree of the 114 + framework. 115 + The callback is called when the aggregated value for any device is changed. 116 + 117 + int dev_pm_qos_remove_global_notifier(notifier): 118 + Removes the notification callback function from the global notification tree 119 + of the framework. 120 + 121 + 122 + From user mode: 123 + No API for user space access to the per-device latency constraints is provided 124 + yet - still under discussion. 89 125
+1 -1
arch/arm/mach-msm/clock.c
··· 18 18 #include <linux/list.h> 19 19 #include <linux/err.h> 20 20 #include <linux/spinlock.h> 21 - #include <linux/pm_qos_params.h> 21 + #include <linux/pm_qos.h> 22 22 #include <linux/mutex.h> 23 23 #include <linux/clk.h> 24 24 #include <linux/string.h>
+1 -1
drivers/acpi/processor_idle.c
··· 37 37 #include <linux/dmi.h> 38 38 #include <linux/moduleparam.h> 39 39 #include <linux/sched.h> /* need_resched() */ 40 - #include <linux/pm_qos_params.h> 40 + #include <linux/pm_qos.h> 41 41 #include <linux/clockchips.h> 42 42 #include <linux/cpuidle.h> 43 43 #include <linux/irqflags.h>
+1 -1
drivers/base/power/Makefile
··· 1 - obj-$(CONFIG_PM) += sysfs.o generic_ops.o common.o 1 + obj-$(CONFIG_PM) += sysfs.o generic_ops.o common.o qos.o 2 2 obj-$(CONFIG_PM_SLEEP) += main.o wakeup.o 3 3 obj-$(CONFIG_PM_RUNTIME) += runtime.o 4 4 obj-$(CONFIG_PM_TRACE_RTC) += trace.o
+3
drivers/base/power/main.c
··· 65 65 spin_lock_init(&dev->power.lock); 66 66 pm_runtime_init(dev); 67 67 INIT_LIST_HEAD(&dev->power.entry); 68 + dev->power.power_state = PMSG_INVALID; 68 69 } 69 70 70 71 /** ··· 97 96 dev_warn(dev, "parent %s should not be sleeping\n", 98 97 dev_name(dev->parent)); 99 98 list_add_tail(&dev->power.entry, &dpm_list); 99 + dev_pm_qos_constraints_init(dev); 100 100 mutex_unlock(&dpm_list_mtx); 101 101 } 102 102 ··· 111 109 dev->bus ? dev->bus->name : "No Bus", dev_name(dev)); 112 110 complete_all(&dev->power.completion); 113 111 mutex_lock(&dpm_list_mtx); 112 + dev_pm_qos_constraints_destroy(dev); 114 113 list_del_init(&dev->power.entry); 115 114 mutex_unlock(&dpm_list_mtx); 116 115 device_wakeup_disable(dev);
+9 -1
drivers/base/power/power.h
··· 1 + #include <linux/pm_qos.h> 2 + 1 3 #ifdef CONFIG_PM_RUNTIME 2 4 3 5 extern void pm_runtime_init(struct device *dev); ··· 37 35 static inline void device_pm_init(struct device *dev) 38 36 { 39 37 spin_lock_init(&dev->power.lock); 38 + dev->power.power_state = PMSG_INVALID; 40 39 pm_runtime_init(dev); 40 + } 41 + 42 + static inline void device_pm_add(struct device *dev) 43 + { 44 + dev_pm_qos_constraints_init(dev); 41 45 } 42 46 43 47 static inline void device_pm_remove(struct device *dev) 44 48 { 49 + dev_pm_qos_constraints_destroy(dev); 45 50 pm_runtime_remove(dev); 46 51 } 47 52 48 - static inline void device_pm_add(struct device *dev) {} 49 53 static inline void device_pm_move_before(struct device *deva, 50 54 struct device *devb) {} 51 55 static inline void device_pm_move_after(struct device *deva,
+419
drivers/base/power/qos.c
··· 1 + /* 2 + * Devices PM QoS constraints management 3 + * 4 + * Copyright (C) 2011 Texas Instruments, Inc. 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License version 2 as 8 + * published by the Free Software Foundation. 9 + * 10 + * 11 + * This module exposes the interface to kernel space for specifying 12 + * per-device PM QoS dependencies. It provides infrastructure for registration 13 + * of: 14 + * 15 + * Dependents on a QoS value : register requests 16 + * Watchers of QoS value : get notified when target QoS value changes 17 + * 18 + * This QoS design is best effort based. Dependents register their QoS needs. 19 + * Watchers register to keep track of the current QoS needs of the system. 20 + * Watchers can register different types of notification callbacks: 21 + * . a per-device notification callback using the dev_pm_qos_*_notifier API. 22 + * The notification chain data is stored in the per-device constraint 23 + * data struct. 24 + * . a system-wide notification callback using the dev_pm_qos_*_global_notifier 25 + * API. The notification chain data is stored in a static variable. 26 + * 27 + * Note about the per-device constraint data struct allocation: 28 + * . The per-device constraints data struct ptr is tored into the device 29 + * dev_pm_info. 30 + * . To minimize the data usage by the per-device constraints, the data struct 31 + * is only allocated at the first call to dev_pm_qos_add_request. 32 + * . The data is later free'd when the device is removed from the system. 33 + * . A global mutex protects the constraints users from the data being 34 + * allocated and free'd. 35 + */ 36 + 37 + #include <linux/pm_qos.h> 38 + #include <linux/spinlock.h> 39 + #include <linux/slab.h> 40 + #include <linux/device.h> 41 + #include <linux/mutex.h> 42 + 43 + 44 + static DEFINE_MUTEX(dev_pm_qos_mtx); 45 + 46 + static BLOCKING_NOTIFIER_HEAD(dev_pm_notifiers); 47 + 48 + /** 49 + * dev_pm_qos_read_value - Get PM QoS constraint for a given device. 50 + * @dev: Device to get the PM QoS constraint value for. 51 + */ 52 + s32 dev_pm_qos_read_value(struct device *dev) 53 + { 54 + struct pm_qos_constraints *c; 55 + unsigned long flags; 56 + s32 ret = 0; 57 + 58 + spin_lock_irqsave(&dev->power.lock, flags); 59 + 60 + c = dev->power.constraints; 61 + if (c) 62 + ret = pm_qos_read_value(c); 63 + 64 + spin_unlock_irqrestore(&dev->power.lock, flags); 65 + 66 + return ret; 67 + } 68 + 69 + /* 70 + * apply_constraint 71 + * @req: constraint request to apply 72 + * @action: action to perform add/update/remove, of type enum pm_qos_req_action 73 + * @value: defines the qos request 74 + * 75 + * Internal function to update the constraints list using the PM QoS core 76 + * code and if needed call the per-device and the global notification 77 + * callbacks 78 + */ 79 + static int apply_constraint(struct dev_pm_qos_request *req, 80 + enum pm_qos_req_action action, int value) 81 + { 82 + int ret, curr_value; 83 + 84 + ret = pm_qos_update_target(req->dev->power.constraints, 85 + &req->node, action, value); 86 + 87 + if (ret) { 88 + /* Call the global callbacks if needed */ 89 + curr_value = pm_qos_read_value(req->dev->power.constraints); 90 + blocking_notifier_call_chain(&dev_pm_notifiers, 91 + (unsigned long)curr_value, 92 + req); 93 + } 94 + 95 + return ret; 96 + } 97 + 98 + /* 99 + * dev_pm_qos_constraints_allocate 100 + * @dev: device to allocate data for 101 + * 102 + * Called at the first call to add_request, for constraint data allocation 103 + * Must be called with the dev_pm_qos_mtx mutex held 104 + */ 105 + static int dev_pm_qos_constraints_allocate(struct device *dev) 106 + { 107 + struct pm_qos_constraints *c; 108 + struct blocking_notifier_head *n; 109 + 110 + c = kzalloc(sizeof(*c), GFP_KERNEL); 111 + if (!c) 112 + return -ENOMEM; 113 + 114 + n = kzalloc(sizeof(*n), GFP_KERNEL); 115 + if (!n) { 116 + kfree(c); 117 + return -ENOMEM; 118 + } 119 + BLOCKING_INIT_NOTIFIER_HEAD(n); 120 + 121 + plist_head_init(&c->list); 122 + c->target_value = PM_QOS_DEV_LAT_DEFAULT_VALUE; 123 + c->default_value = PM_QOS_DEV_LAT_DEFAULT_VALUE; 124 + c->type = PM_QOS_MIN; 125 + c->notifiers = n; 126 + 127 + spin_lock_irq(&dev->power.lock); 128 + dev->power.constraints = c; 129 + spin_unlock_irq(&dev->power.lock); 130 + 131 + return 0; 132 + } 133 + 134 + /** 135 + * dev_pm_qos_constraints_init - Initalize device's PM QoS constraints pointer. 136 + * @dev: target device 137 + * 138 + * Called from the device PM subsystem during device insertion under 139 + * device_pm_lock(). 140 + */ 141 + void dev_pm_qos_constraints_init(struct device *dev) 142 + { 143 + mutex_lock(&dev_pm_qos_mtx); 144 + dev->power.constraints = NULL; 145 + dev->power.power_state = PMSG_ON; 146 + mutex_unlock(&dev_pm_qos_mtx); 147 + } 148 + 149 + /** 150 + * dev_pm_qos_constraints_destroy 151 + * @dev: target device 152 + * 153 + * Called from the device PM subsystem on device removal under device_pm_lock(). 154 + */ 155 + void dev_pm_qos_constraints_destroy(struct device *dev) 156 + { 157 + struct dev_pm_qos_request *req, *tmp; 158 + struct pm_qos_constraints *c; 159 + 160 + mutex_lock(&dev_pm_qos_mtx); 161 + 162 + dev->power.power_state = PMSG_INVALID; 163 + c = dev->power.constraints; 164 + if (!c) 165 + goto out; 166 + 167 + /* Flush the constraints list for the device */ 168 + plist_for_each_entry_safe(req, tmp, &c->list, node) { 169 + /* 170 + * Update constraints list and call the notification 171 + * callbacks if needed 172 + */ 173 + apply_constraint(req, PM_QOS_REMOVE_REQ, PM_QOS_DEFAULT_VALUE); 174 + memset(req, 0, sizeof(*req)); 175 + } 176 + 177 + spin_lock_irq(&dev->power.lock); 178 + dev->power.constraints = NULL; 179 + spin_unlock_irq(&dev->power.lock); 180 + 181 + kfree(c->notifiers); 182 + kfree(c); 183 + 184 + out: 185 + mutex_unlock(&dev_pm_qos_mtx); 186 + } 187 + 188 + /** 189 + * dev_pm_qos_add_request - inserts new qos request into the list 190 + * @dev: target device for the constraint 191 + * @req: pointer to a preallocated handle 192 + * @value: defines the qos request 193 + * 194 + * This function inserts a new entry in the device constraints list of 195 + * requested qos performance characteristics. It recomputes the aggregate 196 + * QoS expectations of parameters and initializes the dev_pm_qos_request 197 + * handle. Caller needs to save this handle for later use in updates and 198 + * removal. 199 + * 200 + * Returns 1 if the aggregated constraint value has changed, 201 + * 0 if the aggregated constraint value has not changed, 202 + * -EINVAL in case of wrong parameters, -ENOMEM if there's not enough memory 203 + * to allocate for data structures, -ENODEV if the device has just been removed 204 + * from the system. 205 + */ 206 + int dev_pm_qos_add_request(struct device *dev, struct dev_pm_qos_request *req, 207 + s32 value) 208 + { 209 + int ret = 0; 210 + 211 + if (!dev || !req) /*guard against callers passing in null */ 212 + return -EINVAL; 213 + 214 + if (dev_pm_qos_request_active(req)) { 215 + WARN(1, KERN_ERR "dev_pm_qos_add_request() called for already " 216 + "added request\n"); 217 + return -EINVAL; 218 + } 219 + 220 + req->dev = dev; 221 + 222 + mutex_lock(&dev_pm_qos_mtx); 223 + 224 + if (!dev->power.constraints) { 225 + if (dev->power.power_state.event == PM_EVENT_INVALID) { 226 + /* The device has been removed from the system. */ 227 + req->dev = NULL; 228 + ret = -ENODEV; 229 + goto out; 230 + } else { 231 + /* 232 + * Allocate the constraints data on the first call to 233 + * add_request, i.e. only if the data is not already 234 + * allocated and if the device has not been removed. 235 + */ 236 + ret = dev_pm_qos_constraints_allocate(dev); 237 + } 238 + } 239 + 240 + if (!ret) 241 + ret = apply_constraint(req, PM_QOS_ADD_REQ, value); 242 + 243 + out: 244 + mutex_unlock(&dev_pm_qos_mtx); 245 + 246 + return ret; 247 + } 248 + EXPORT_SYMBOL_GPL(dev_pm_qos_add_request); 249 + 250 + /** 251 + * dev_pm_qos_update_request - modifies an existing qos request 252 + * @req : handle to list element holding a dev_pm_qos request to use 253 + * @new_value: defines the qos request 254 + * 255 + * Updates an existing dev PM qos request along with updating the 256 + * target value. 257 + * 258 + * Attempts are made to make this code callable on hot code paths. 259 + * 260 + * Returns 1 if the aggregated constraint value has changed, 261 + * 0 if the aggregated constraint value has not changed, 262 + * -EINVAL in case of wrong parameters, -ENODEV if the device has been 263 + * removed from the system 264 + */ 265 + int dev_pm_qos_update_request(struct dev_pm_qos_request *req, 266 + s32 new_value) 267 + { 268 + int ret = 0; 269 + 270 + if (!req) /*guard against callers passing in null */ 271 + return -EINVAL; 272 + 273 + if (!dev_pm_qos_request_active(req)) { 274 + WARN(1, KERN_ERR "dev_pm_qos_update_request() called for " 275 + "unknown object\n"); 276 + return -EINVAL; 277 + } 278 + 279 + mutex_lock(&dev_pm_qos_mtx); 280 + 281 + if (req->dev->power.constraints) { 282 + if (new_value != req->node.prio) 283 + ret = apply_constraint(req, PM_QOS_UPDATE_REQ, 284 + new_value); 285 + } else { 286 + /* Return if the device has been removed */ 287 + ret = -ENODEV; 288 + } 289 + 290 + mutex_unlock(&dev_pm_qos_mtx); 291 + return ret; 292 + } 293 + EXPORT_SYMBOL_GPL(dev_pm_qos_update_request); 294 + 295 + /** 296 + * dev_pm_qos_remove_request - modifies an existing qos request 297 + * @req: handle to request list element 298 + * 299 + * Will remove pm qos request from the list of constraints and 300 + * recompute the current target value. Call this on slow code paths. 301 + * 302 + * Returns 1 if the aggregated constraint value has changed, 303 + * 0 if the aggregated constraint value has not changed, 304 + * -EINVAL in case of wrong parameters, -ENODEV if the device has been 305 + * removed from the system 306 + */ 307 + int dev_pm_qos_remove_request(struct dev_pm_qos_request *req) 308 + { 309 + int ret = 0; 310 + 311 + if (!req) /*guard against callers passing in null */ 312 + return -EINVAL; 313 + 314 + if (!dev_pm_qos_request_active(req)) { 315 + WARN(1, KERN_ERR "dev_pm_qos_remove_request() called for " 316 + "unknown object\n"); 317 + return -EINVAL; 318 + } 319 + 320 + mutex_lock(&dev_pm_qos_mtx); 321 + 322 + if (req->dev->power.constraints) { 323 + ret = apply_constraint(req, PM_QOS_REMOVE_REQ, 324 + PM_QOS_DEFAULT_VALUE); 325 + memset(req, 0, sizeof(*req)); 326 + } else { 327 + /* Return if the device has been removed */ 328 + ret = -ENODEV; 329 + } 330 + 331 + mutex_unlock(&dev_pm_qos_mtx); 332 + return ret; 333 + } 334 + EXPORT_SYMBOL_GPL(dev_pm_qos_remove_request); 335 + 336 + /** 337 + * dev_pm_qos_add_notifier - sets notification entry for changes to target value 338 + * of per-device PM QoS constraints 339 + * 340 + * @dev: target device for the constraint 341 + * @notifier: notifier block managed by caller. 342 + * 343 + * Will register the notifier into a notification chain that gets called 344 + * upon changes to the target value for the device. 345 + */ 346 + int dev_pm_qos_add_notifier(struct device *dev, struct notifier_block *notifier) 347 + { 348 + int retval = 0; 349 + 350 + mutex_lock(&dev_pm_qos_mtx); 351 + 352 + /* Silently return if the constraints object is not present. */ 353 + if (dev->power.constraints) 354 + retval = blocking_notifier_chain_register( 355 + dev->power.constraints->notifiers, 356 + notifier); 357 + 358 + mutex_unlock(&dev_pm_qos_mtx); 359 + return retval; 360 + } 361 + EXPORT_SYMBOL_GPL(dev_pm_qos_add_notifier); 362 + 363 + /** 364 + * dev_pm_qos_remove_notifier - deletes notification for changes to target value 365 + * of per-device PM QoS constraints 366 + * 367 + * @dev: target device for the constraint 368 + * @notifier: notifier block to be removed. 369 + * 370 + * Will remove the notifier from the notification chain that gets called 371 + * upon changes to the target value. 372 + */ 373 + int dev_pm_qos_remove_notifier(struct device *dev, 374 + struct notifier_block *notifier) 375 + { 376 + int retval = 0; 377 + 378 + mutex_lock(&dev_pm_qos_mtx); 379 + 380 + /* Silently return if the constraints object is not present. */ 381 + if (dev->power.constraints) 382 + retval = blocking_notifier_chain_unregister( 383 + dev->power.constraints->notifiers, 384 + notifier); 385 + 386 + mutex_unlock(&dev_pm_qos_mtx); 387 + return retval; 388 + } 389 + EXPORT_SYMBOL_GPL(dev_pm_qos_remove_notifier); 390 + 391 + /** 392 + * dev_pm_qos_add_global_notifier - sets notification entry for changes to 393 + * target value of the PM QoS constraints for any device 394 + * 395 + * @notifier: notifier block managed by caller. 396 + * 397 + * Will register the notifier into a notification chain that gets called 398 + * upon changes to the target value for any device. 399 + */ 400 + int dev_pm_qos_add_global_notifier(struct notifier_block *notifier) 401 + { 402 + return blocking_notifier_chain_register(&dev_pm_notifiers, notifier); 403 + } 404 + EXPORT_SYMBOL_GPL(dev_pm_qos_add_global_notifier); 405 + 406 + /** 407 + * dev_pm_qos_remove_global_notifier - deletes notification for changes to 408 + * target value of PM QoS constraints for any device 409 + * 410 + * @notifier: notifier block to be removed. 411 + * 412 + * Will remove the notifier from the notification chain that gets called 413 + * upon changes to the target value for any device. 414 + */ 415 + int dev_pm_qos_remove_global_notifier(struct notifier_block *notifier) 416 + { 417 + return blocking_notifier_chain_unregister(&dev_pm_notifiers, notifier); 418 + } 419 + EXPORT_SYMBOL_GPL(dev_pm_qos_remove_global_notifier);
+1 -1
drivers/cpuidle/cpuidle.c
··· 12 12 #include <linux/mutex.h> 13 13 #include <linux/sched.h> 14 14 #include <linux/notifier.h> 15 - #include <linux/pm_qos_params.h> 15 + #include <linux/pm_qos.h> 16 16 #include <linux/cpu.h> 17 17 #include <linux/cpuidle.h> 18 18 #include <linux/ktime.h>
+1 -1
drivers/cpuidle/governors/ladder.c
··· 14 14 15 15 #include <linux/kernel.h> 16 16 #include <linux/cpuidle.h> 17 - #include <linux/pm_qos_params.h> 17 + #include <linux/pm_qos.h> 18 18 #include <linux/moduleparam.h> 19 19 #include <linux/jiffies.h> 20 20
+1 -1
drivers/cpuidle/governors/menu.c
··· 12 12 13 13 #include <linux/kernel.h> 14 14 #include <linux/cpuidle.h> 15 - #include <linux/pm_qos_params.h> 15 + #include <linux/pm_qos.h> 16 16 #include <linux/time.h> 17 17 #include <linux/ktime.h> 18 18 #include <linux/hrtimer.h>
+2 -2
drivers/media/video/via-camera.c
··· 21 21 #include <media/videobuf-dma-sg.h> 22 22 #include <linux/delay.h> 23 23 #include <linux/dma-mapping.h> 24 - #include <linux/pm_qos_params.h> 24 + #include <linux/pm_qos.h> 25 25 #include <linux/via-core.h> 26 26 #include <linux/via-gpio.h> 27 27 #include <linux/via_i2c.h> ··· 69 69 struct mutex lock; 70 70 enum viacam_opstate opstate; 71 71 unsigned long flags; 72 - struct pm_qos_request_list qos_request; 72 + struct pm_qos_request qos_request; 73 73 /* 74 74 * GPIO info for power/reset management 75 75 */
+1 -1
drivers/net/e1000e/netdev.c
··· 47 47 #include <linux/if_vlan.h> 48 48 #include <linux/cpu.h> 49 49 #include <linux/smp.h> 50 - #include <linux/pm_qos_params.h> 50 + #include <linux/pm_qos.h> 51 51 #include <linux/pm_runtime.h> 52 52 #include <linux/aer.h> 53 53 #include <linux/prefetch.h>
+2 -2
drivers/net/wireless/ipw2x00/ipw2100.c
··· 161 161 #include <linux/firmware.h> 162 162 #include <linux/acpi.h> 163 163 #include <linux/ctype.h> 164 - #include <linux/pm_qos_params.h> 164 + #include <linux/pm_qos.h> 165 165 166 166 #include <net/lib80211.h> 167 167 ··· 174 174 #define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2100 Network Driver" 175 175 #define DRV_COPYRIGHT "Copyright(c) 2003-2006 Intel Corporation" 176 176 177 - static struct pm_qos_request_list ipw2100_pm_qos_req; 177 + static struct pm_qos_request ipw2100_pm_qos_req; 178 178 179 179 /* Debugging stuff */ 180 180 #ifdef CONFIG_IPW2100_DEBUG
+2 -2
include/linux/netdevice.h
··· 31 31 #include <linux/if_link.h> 32 32 33 33 #ifdef __KERNEL__ 34 - #include <linux/pm_qos_params.h> 34 + #include <linux/pm_qos.h> 35 35 #include <linux/timer.h> 36 36 #include <linux/delay.h> 37 37 #include <linux/atomic.h> ··· 964 964 */ 965 965 char name[IFNAMSIZ]; 966 966 967 - struct pm_qos_request_list pm_qos_req; 967 + struct pm_qos_request pm_qos_req; 968 968 969 969 /* device name hash chain */ 970 970 struct hlist_node name_hlist;
+3
include/linux/pm.h
··· 326 326 * requested by a driver. 327 327 */ 328 328 329 + #define PM_EVENT_INVALID (-1) 329 330 #define PM_EVENT_ON 0x0000 330 331 #define PM_EVENT_FREEZE 0x0001 331 332 #define PM_EVENT_SUSPEND 0x0002 ··· 347 346 #define PM_EVENT_AUTO_SUSPEND (PM_EVENT_AUTO | PM_EVENT_SUSPEND) 348 347 #define PM_EVENT_AUTO_RESUME (PM_EVENT_AUTO | PM_EVENT_RESUME) 349 348 349 + #define PMSG_INVALID ((struct pm_message){ .event = PM_EVENT_INVALID, }) 350 350 #define PMSG_ON ((struct pm_message){ .event = PM_EVENT_ON, }) 351 351 #define PMSG_FREEZE ((struct pm_message){ .event = PM_EVENT_FREEZE, }) 352 352 #define PMSG_QUIESCE ((struct pm_message){ .event = PM_EVENT_QUIESCE, }) ··· 483 481 unsigned long accounting_timestamp; 484 482 #endif 485 483 struct pm_subsys_data *subsys_data; /* Owned by the subsystem. */ 484 + struct pm_qos_constraints *constraints; 486 485 }; 487 486 488 487 extern void update_pm_runtime_accounting(struct device *dev);
+155
include/linux/pm_qos.h
··· 1 + #ifndef _LINUX_PM_QOS_H 2 + #define _LINUX_PM_QOS_H 3 + /* interface for the pm_qos_power infrastructure of the linux kernel. 4 + * 5 + * Mark Gross <mgross@linux.intel.com> 6 + */ 7 + #include <linux/plist.h> 8 + #include <linux/notifier.h> 9 + #include <linux/miscdevice.h> 10 + #include <linux/device.h> 11 + 12 + #define PM_QOS_RESERVED 0 13 + #define PM_QOS_CPU_DMA_LATENCY 1 14 + #define PM_QOS_NETWORK_LATENCY 2 15 + #define PM_QOS_NETWORK_THROUGHPUT 3 16 + 17 + #define PM_QOS_NUM_CLASSES 4 18 + #define PM_QOS_DEFAULT_VALUE -1 19 + 20 + #define PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE (2000 * USEC_PER_SEC) 21 + #define PM_QOS_NETWORK_LAT_DEFAULT_VALUE (2000 * USEC_PER_SEC) 22 + #define PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE 0 23 + #define PM_QOS_DEV_LAT_DEFAULT_VALUE 0 24 + 25 + struct pm_qos_request { 26 + struct plist_node node; 27 + int pm_qos_class; 28 + }; 29 + 30 + struct dev_pm_qos_request { 31 + struct plist_node node; 32 + struct device *dev; 33 + }; 34 + 35 + enum pm_qos_type { 36 + PM_QOS_UNITIALIZED, 37 + PM_QOS_MAX, /* return the largest value */ 38 + PM_QOS_MIN /* return the smallest value */ 39 + }; 40 + 41 + /* 42 + * Note: The lockless read path depends on the CPU accessing 43 + * target_value atomically. Atomic access is only guaranteed on all CPU 44 + * types linux supports for 32 bit quantites 45 + */ 46 + struct pm_qos_constraints { 47 + struct plist_head list; 48 + s32 target_value; /* Do not change to 64 bit */ 49 + s32 default_value; 50 + enum pm_qos_type type; 51 + struct blocking_notifier_head *notifiers; 52 + }; 53 + 54 + /* Action requested to pm_qos_update_target */ 55 + enum pm_qos_req_action { 56 + PM_QOS_ADD_REQ, /* Add a new request */ 57 + PM_QOS_UPDATE_REQ, /* Update an existing request */ 58 + PM_QOS_REMOVE_REQ /* Remove an existing request */ 59 + }; 60 + 61 + static inline int dev_pm_qos_request_active(struct dev_pm_qos_request *req) 62 + { 63 + return req->dev != 0; 64 + } 65 + 66 + #ifdef CONFIG_PM 67 + int pm_qos_update_target(struct pm_qos_constraints *c, struct plist_node *node, 68 + enum pm_qos_req_action action, int value); 69 + void pm_qos_add_request(struct pm_qos_request *req, int pm_qos_class, 70 + s32 value); 71 + void pm_qos_update_request(struct pm_qos_request *req, 72 + s32 new_value); 73 + void pm_qos_remove_request(struct pm_qos_request *req); 74 + 75 + int pm_qos_request(int pm_qos_class); 76 + int pm_qos_add_notifier(int pm_qos_class, struct notifier_block *notifier); 77 + int pm_qos_remove_notifier(int pm_qos_class, struct notifier_block *notifier); 78 + int pm_qos_request_active(struct pm_qos_request *req); 79 + s32 pm_qos_read_value(struct pm_qos_constraints *c); 80 + 81 + s32 dev_pm_qos_read_value(struct device *dev); 82 + int dev_pm_qos_add_request(struct device *dev, struct dev_pm_qos_request *req, 83 + s32 value); 84 + int dev_pm_qos_update_request(struct dev_pm_qos_request *req, s32 new_value); 85 + int dev_pm_qos_remove_request(struct dev_pm_qos_request *req); 86 + int dev_pm_qos_add_notifier(struct device *dev, 87 + struct notifier_block *notifier); 88 + int dev_pm_qos_remove_notifier(struct device *dev, 89 + struct notifier_block *notifier); 90 + int dev_pm_qos_add_global_notifier(struct notifier_block *notifier); 91 + int dev_pm_qos_remove_global_notifier(struct notifier_block *notifier); 92 + void dev_pm_qos_constraints_init(struct device *dev); 93 + void dev_pm_qos_constraints_destroy(struct device *dev); 94 + #else 95 + static inline int pm_qos_update_target(struct pm_qos_constraints *c, 96 + struct plist_node *node, 97 + enum pm_qos_req_action action, 98 + int value) 99 + { return 0; } 100 + static inline void pm_qos_add_request(struct pm_qos_request *req, 101 + int pm_qos_class, s32 value) 102 + { return; } 103 + static inline void pm_qos_update_request(struct pm_qos_request *req, 104 + s32 new_value) 105 + { return; } 106 + static inline void pm_qos_remove_request(struct pm_qos_request *req) 107 + { return; } 108 + 109 + static inline int pm_qos_request(int pm_qos_class) 110 + { return 0; } 111 + static inline int pm_qos_add_notifier(int pm_qos_class, 112 + struct notifier_block *notifier) 113 + { return 0; } 114 + static inline int pm_qos_remove_notifier(int pm_qos_class, 115 + struct notifier_block *notifier) 116 + { return 0; } 117 + static inline int pm_qos_request_active(struct pm_qos_request *req) 118 + { return 0; } 119 + static inline s32 pm_qos_read_value(struct pm_qos_constraints *c) 120 + { return 0; } 121 + 122 + static inline s32 dev_pm_qos_read_value(struct device *dev) 123 + { return 0; } 124 + static inline int dev_pm_qos_add_request(struct device *dev, 125 + struct dev_pm_qos_request *req, 126 + s32 value) 127 + { return 0; } 128 + static inline int dev_pm_qos_update_request(struct dev_pm_qos_request *req, 129 + s32 new_value) 130 + { return 0; } 131 + static inline int dev_pm_qos_remove_request(struct dev_pm_qos_request *req) 132 + { return 0; } 133 + static inline int dev_pm_qos_add_notifier(struct device *dev, 134 + struct notifier_block *notifier) 135 + { return 0; } 136 + static inline int dev_pm_qos_remove_notifier(struct device *dev, 137 + struct notifier_block *notifier) 138 + { return 0; } 139 + static inline int dev_pm_qos_add_global_notifier( 140 + struct notifier_block *notifier) 141 + { return 0; } 142 + static inline int dev_pm_qos_remove_global_notifier( 143 + struct notifier_block *notifier) 144 + { return 0; } 145 + static inline void dev_pm_qos_constraints_init(struct device *dev) 146 + { 147 + dev->power.power_state = PMSG_ON; 148 + } 149 + static inline void dev_pm_qos_constraints_destroy(struct device *dev) 150 + { 151 + dev->power.power_state = PMSG_INVALID; 152 + } 153 + #endif 154 + 155 + #endif
-38
include/linux/pm_qos_params.h
··· 1 - #ifndef _LINUX_PM_QOS_PARAMS_H 2 - #define _LINUX_PM_QOS_PARAMS_H 3 - /* interface for the pm_qos_power infrastructure of the linux kernel. 4 - * 5 - * Mark Gross <mgross@linux.intel.com> 6 - */ 7 - #include <linux/plist.h> 8 - #include <linux/notifier.h> 9 - #include <linux/miscdevice.h> 10 - 11 - #define PM_QOS_RESERVED 0 12 - #define PM_QOS_CPU_DMA_LATENCY 1 13 - #define PM_QOS_NETWORK_LATENCY 2 14 - #define PM_QOS_NETWORK_THROUGHPUT 3 15 - 16 - #define PM_QOS_NUM_CLASSES 4 17 - #define PM_QOS_DEFAULT_VALUE -1 18 - 19 - #define PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE (2000 * USEC_PER_SEC) 20 - #define PM_QOS_NETWORK_LAT_DEFAULT_VALUE (2000 * USEC_PER_SEC) 21 - #define PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE 0 22 - 23 - struct pm_qos_request_list { 24 - struct plist_node list; 25 - int pm_qos_class; 26 - }; 27 - 28 - void pm_qos_add_request(struct pm_qos_request_list *l, int pm_qos_class, s32 value); 29 - void pm_qos_update_request(struct pm_qos_request_list *pm_qos_req, 30 - s32 new_value); 31 - void pm_qos_remove_request(struct pm_qos_request_list *pm_qos_req); 32 - 33 - int pm_qos_request(int pm_qos_class); 34 - int pm_qos_add_notifier(int pm_qos_class, struct notifier_block *notifier); 35 - int pm_qos_remove_notifier(int pm_qos_class, struct notifier_block *notifier); 36 - int pm_qos_request_active(struct pm_qos_request_list *req); 37 - 38 - #endif
+2 -2
include/sound/pcm.h
··· 29 29 #include <linux/poll.h> 30 30 #include <linux/mm.h> 31 31 #include <linux/bitops.h> 32 - #include <linux/pm_qos_params.h> 32 + #include <linux/pm_qos.h> 33 33 34 34 #define snd_pcm_substream_chip(substream) ((substream)->private_data) 35 35 #define snd_pcm_chip(pcm) ((pcm)->private_data) ··· 373 373 int number; 374 374 char name[32]; /* substream name */ 375 375 int stream; /* stream (direction) */ 376 - struct pm_qos_request_list latency_pm_qos_req; /* pm_qos request */ 376 + struct pm_qos_request latency_pm_qos_req; /* pm_qos request */ 377 377 size_t buffer_bytes_max; /* limit ring buffer size */ 378 378 struct snd_dma_buffer dma_buffer; 379 379 unsigned int dma_buf_id;
+1 -1
kernel/Makefile
··· 9 9 rcupdate.o extable.o params.o posix-timers.o \ 10 10 kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \ 11 11 hrtimer.o rwsem.o nsproxy.o srcu.o semaphore.o \ 12 - notifier.o ksysfs.o pm_qos_params.o sched_clock.o cred.o \ 12 + notifier.o ksysfs.o sched_clock.o cred.o \ 13 13 async.o range.o 14 14 obj-y += groups.o 15 15
+229 -220
kernel/pm_qos_params.c kernel/power/qos.c
··· 29 29 30 30 /*#define DEBUG*/ 31 31 32 - #include <linux/pm_qos_params.h> 32 + #include <linux/pm_qos.h> 33 33 #include <linux/sched.h> 34 34 #include <linux/spinlock.h> 35 35 #include <linux/slab.h> ··· 45 45 #include <linux/uaccess.h> 46 46 47 47 /* 48 - * locking rule: all changes to requests or notifiers lists 48 + * locking rule: all changes to constraints or notifiers lists 49 49 * or pm_qos_object list and pm_qos_objects need to happen with pm_qos_lock 50 50 * held, taken with _irqsave. One lock to rule them all 51 51 */ 52 - enum pm_qos_type { 53 - PM_QOS_MAX, /* return the largest value */ 54 - PM_QOS_MIN /* return the smallest value */ 55 - }; 56 - 57 - /* 58 - * Note: The lockless read path depends on the CPU accessing 59 - * target_value atomically. Atomic access is only guaranteed on all CPU 60 - * types linux supports for 32 bit quantites 61 - */ 62 52 struct pm_qos_object { 63 - struct plist_head requests; 64 - struct blocking_notifier_head *notifiers; 53 + struct pm_qos_constraints *constraints; 65 54 struct miscdevice pm_qos_power_miscdev; 66 55 char *name; 67 - s32 target_value; /* Do not change to 64 bit */ 68 - s32 default_value; 69 - enum pm_qos_type type; 70 56 }; 71 57 72 58 static DEFINE_SPINLOCK(pm_qos_lock); 73 59 74 60 static struct pm_qos_object null_pm_qos; 61 + 75 62 static BLOCKING_NOTIFIER_HEAD(cpu_dma_lat_notifier); 76 - static struct pm_qos_object cpu_dma_pm_qos = { 77 - .requests = PLIST_HEAD_INIT(cpu_dma_pm_qos.requests), 78 - .notifiers = &cpu_dma_lat_notifier, 79 - .name = "cpu_dma_latency", 63 + static struct pm_qos_constraints cpu_dma_constraints = { 64 + .list = PLIST_HEAD_INIT(cpu_dma_constraints.list), 80 65 .target_value = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE, 81 66 .default_value = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE, 82 67 .type = PM_QOS_MIN, 68 + .notifiers = &cpu_dma_lat_notifier, 69 + }; 70 + static struct pm_qos_object cpu_dma_pm_qos = { 71 + .constraints = &cpu_dma_constraints, 83 72 }; 84 73 85 74 static BLOCKING_NOTIFIER_HEAD(network_lat_notifier); 86 - static struct pm_qos_object network_lat_pm_qos = { 87 - .requests = PLIST_HEAD_INIT(network_lat_pm_qos.requests), 88 - .notifiers = &network_lat_notifier, 89 - .name = "network_latency", 75 + static struct pm_qos_constraints network_lat_constraints = { 76 + .list = PLIST_HEAD_INIT(network_lat_constraints.list), 90 77 .target_value = PM_QOS_NETWORK_LAT_DEFAULT_VALUE, 91 78 .default_value = PM_QOS_NETWORK_LAT_DEFAULT_VALUE, 92 - .type = PM_QOS_MIN 79 + .type = PM_QOS_MIN, 80 + .notifiers = &network_lat_notifier, 81 + }; 82 + static struct pm_qos_object network_lat_pm_qos = { 83 + .constraints = &network_lat_constraints, 84 + .name = "network_latency", 93 85 }; 94 86 95 87 96 88 static BLOCKING_NOTIFIER_HEAD(network_throughput_notifier); 97 - static struct pm_qos_object network_throughput_pm_qos = { 98 - .requests = PLIST_HEAD_INIT(network_throughput_pm_qos.requests), 99 - .notifiers = &network_throughput_notifier, 100 - .name = "network_throughput", 89 + static struct pm_qos_constraints network_tput_constraints = { 90 + .list = PLIST_HEAD_INIT(network_tput_constraints.list), 101 91 .target_value = PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE, 102 92 .default_value = PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE, 103 93 .type = PM_QOS_MAX, 94 + .notifiers = &network_throughput_notifier, 95 + }; 96 + static struct pm_qos_object network_throughput_pm_qos = { 97 + .constraints = &network_tput_constraints, 98 + .name = "network_throughput", 104 99 }; 105 100 106 101 ··· 122 127 }; 123 128 124 129 /* unlocked internal variant */ 125 - static inline int pm_qos_get_value(struct pm_qos_object *o) 130 + static inline int pm_qos_get_value(struct pm_qos_constraints *c) 126 131 { 127 - if (plist_head_empty(&o->requests)) 128 - return o->default_value; 132 + if (plist_head_empty(&c->list)) 133 + return c->default_value; 129 134 130 - switch (o->type) { 135 + switch (c->type) { 131 136 case PM_QOS_MIN: 132 - return plist_first(&o->requests)->prio; 137 + return plist_first(&c->list)->prio; 133 138 134 139 case PM_QOS_MAX: 135 - return plist_last(&o->requests)->prio; 140 + return plist_last(&c->list)->prio; 136 141 137 142 default: 138 143 /* runtime check for not using enum */ ··· 140 145 } 141 146 } 142 147 143 - static inline s32 pm_qos_read_value(struct pm_qos_object *o) 148 + s32 pm_qos_read_value(struct pm_qos_constraints *c) 144 149 { 145 - return o->target_value; 150 + return c->target_value; 146 151 } 147 152 148 - static inline void pm_qos_set_value(struct pm_qos_object *o, s32 value) 153 + static inline void pm_qos_set_value(struct pm_qos_constraints *c, s32 value) 149 154 { 150 - o->target_value = value; 155 + c->target_value = value; 151 156 } 152 157 153 - static void update_target(struct pm_qos_object *o, struct plist_node *node, 154 - int del, int value) 158 + /** 159 + * pm_qos_update_target - manages the constraints list and calls the notifiers 160 + * if needed 161 + * @c: constraints data struct 162 + * @node: request to add to the list, to update or to remove 163 + * @action: action to take on the constraints list 164 + * @value: value of the request to add or update 165 + * 166 + * This function returns 1 if the aggregated constraint value has changed, 0 167 + * otherwise. 168 + */ 169 + int pm_qos_update_target(struct pm_qos_constraints *c, struct plist_node *node, 170 + enum pm_qos_req_action action, int value) 155 171 { 156 172 unsigned long flags; 157 - int prev_value, curr_value; 173 + int prev_value, curr_value, new_value; 158 174 159 175 spin_lock_irqsave(&pm_qos_lock, flags); 160 - prev_value = pm_qos_get_value(o); 161 - /* PM_QOS_DEFAULT_VALUE is a signal that the value is unchanged */ 162 - if (value != PM_QOS_DEFAULT_VALUE) { 176 + prev_value = pm_qos_get_value(c); 177 + if (value == PM_QOS_DEFAULT_VALUE) 178 + new_value = c->default_value; 179 + else 180 + new_value = value; 181 + 182 + switch (action) { 183 + case PM_QOS_REMOVE_REQ: 184 + plist_del(node, &c->list); 185 + break; 186 + case PM_QOS_UPDATE_REQ: 163 187 /* 164 188 * to change the list, we atomically remove, reinit 165 189 * with new value and add, then see if the extremal 166 190 * changed 167 191 */ 168 - plist_del(node, &o->requests); 169 - plist_node_init(node, value); 170 - plist_add(node, &o->requests); 171 - } else if (del) { 172 - plist_del(node, &o->requests); 173 - } else { 174 - plist_add(node, &o->requests); 192 + plist_del(node, &c->list); 193 + case PM_QOS_ADD_REQ: 194 + plist_node_init(node, new_value); 195 + plist_add(node, &c->list); 196 + break; 197 + default: 198 + /* no action */ 199 + ; 175 200 } 176 - curr_value = pm_qos_get_value(o); 177 - pm_qos_set_value(o, curr_value); 201 + 202 + curr_value = pm_qos_get_value(c); 203 + pm_qos_set_value(c, curr_value); 204 + 178 205 spin_unlock_irqrestore(&pm_qos_lock, flags); 179 206 180 - if (prev_value != curr_value) 181 - blocking_notifier_call_chain(o->notifiers, 207 + if (prev_value != curr_value) { 208 + blocking_notifier_call_chain(c->notifiers, 182 209 (unsigned long)curr_value, 183 210 NULL); 211 + return 1; 212 + } else { 213 + return 0; 214 + } 184 215 } 185 216 217 + /** 218 + * pm_qos_request - returns current system wide qos expectation 219 + * @pm_qos_class: identification of which qos value is requested 220 + * 221 + * This function returns the current target value. 222 + */ 223 + int pm_qos_request(int pm_qos_class) 224 + { 225 + return pm_qos_read_value(pm_qos_array[pm_qos_class]->constraints); 226 + } 227 + EXPORT_SYMBOL_GPL(pm_qos_request); 228 + 229 + int pm_qos_request_active(struct pm_qos_request *req) 230 + { 231 + return req->pm_qos_class != 0; 232 + } 233 + EXPORT_SYMBOL_GPL(pm_qos_request_active); 234 + 235 + /** 236 + * pm_qos_add_request - inserts new qos request into the list 237 + * @req: pointer to a preallocated handle 238 + * @pm_qos_class: identifies which list of qos request to use 239 + * @value: defines the qos request 240 + * 241 + * This function inserts a new entry in the pm_qos_class list of requested qos 242 + * performance characteristics. It recomputes the aggregate QoS expectations 243 + * for the pm_qos_class of parameters and initializes the pm_qos_request 244 + * handle. Caller needs to save this handle for later use in updates and 245 + * removal. 246 + */ 247 + 248 + void pm_qos_add_request(struct pm_qos_request *req, 249 + int pm_qos_class, s32 value) 250 + { 251 + if (!req) /*guard against callers passing in null */ 252 + return; 253 + 254 + if (pm_qos_request_active(req)) { 255 + WARN(1, KERN_ERR "pm_qos_add_request() called for already added request\n"); 256 + return; 257 + } 258 + req->pm_qos_class = pm_qos_class; 259 + pm_qos_update_target(pm_qos_array[pm_qos_class]->constraints, 260 + &req->node, PM_QOS_ADD_REQ, value); 261 + } 262 + EXPORT_SYMBOL_GPL(pm_qos_add_request); 263 + 264 + /** 265 + * pm_qos_update_request - modifies an existing qos request 266 + * @req : handle to list element holding a pm_qos request to use 267 + * @value: defines the qos request 268 + * 269 + * Updates an existing qos request for the pm_qos_class of parameters along 270 + * with updating the target pm_qos_class value. 271 + * 272 + * Attempts are made to make this code callable on hot code paths. 273 + */ 274 + void pm_qos_update_request(struct pm_qos_request *req, 275 + s32 new_value) 276 + { 277 + if (!req) /*guard against callers passing in null */ 278 + return; 279 + 280 + if (!pm_qos_request_active(req)) { 281 + WARN(1, KERN_ERR "pm_qos_update_request() called for unknown object\n"); 282 + return; 283 + } 284 + 285 + if (new_value != req->node.prio) 286 + pm_qos_update_target( 287 + pm_qos_array[req->pm_qos_class]->constraints, 288 + &req->node, PM_QOS_UPDATE_REQ, new_value); 289 + } 290 + EXPORT_SYMBOL_GPL(pm_qos_update_request); 291 + 292 + /** 293 + * pm_qos_remove_request - modifies an existing qos request 294 + * @req: handle to request list element 295 + * 296 + * Will remove pm qos request from the list of constraints and 297 + * recompute the current target value for the pm_qos_class. Call this 298 + * on slow code paths. 299 + */ 300 + void pm_qos_remove_request(struct pm_qos_request *req) 301 + { 302 + if (!req) /*guard against callers passing in null */ 303 + return; 304 + /* silent return to keep pcm code cleaner */ 305 + 306 + if (!pm_qos_request_active(req)) { 307 + WARN(1, KERN_ERR "pm_qos_remove_request() called for unknown object\n"); 308 + return; 309 + } 310 + 311 + pm_qos_update_target(pm_qos_array[req->pm_qos_class]->constraints, 312 + &req->node, PM_QOS_REMOVE_REQ, 313 + PM_QOS_DEFAULT_VALUE); 314 + memset(req, 0, sizeof(*req)); 315 + } 316 + EXPORT_SYMBOL_GPL(pm_qos_remove_request); 317 + 318 + /** 319 + * pm_qos_add_notifier - sets notification entry for changes to target value 320 + * @pm_qos_class: identifies which qos target changes should be notified. 321 + * @notifier: notifier block managed by caller. 322 + * 323 + * will register the notifier into a notification chain that gets called 324 + * upon changes to the pm_qos_class target value. 325 + */ 326 + int pm_qos_add_notifier(int pm_qos_class, struct notifier_block *notifier) 327 + { 328 + int retval; 329 + 330 + retval = blocking_notifier_chain_register( 331 + pm_qos_array[pm_qos_class]->constraints->notifiers, 332 + notifier); 333 + 334 + return retval; 335 + } 336 + EXPORT_SYMBOL_GPL(pm_qos_add_notifier); 337 + 338 + /** 339 + * pm_qos_remove_notifier - deletes notification entry from chain. 340 + * @pm_qos_class: identifies which qos target changes are notified. 341 + * @notifier: notifier block to be removed. 342 + * 343 + * will remove the notifier from the notification chain that gets called 344 + * upon changes to the pm_qos_class target value. 345 + */ 346 + int pm_qos_remove_notifier(int pm_qos_class, struct notifier_block *notifier) 347 + { 348 + int retval; 349 + 350 + retval = blocking_notifier_chain_unregister( 351 + pm_qos_array[pm_qos_class]->constraints->notifiers, 352 + notifier); 353 + 354 + return retval; 355 + } 356 + EXPORT_SYMBOL_GPL(pm_qos_remove_notifier); 357 + 358 + /* User space interface to PM QoS classes via misc devices */ 186 359 static int register_pm_qos_misc(struct pm_qos_object *qos) 187 360 { 188 361 qos->pm_qos_power_miscdev.minor = MISC_DYNAMIC_MINOR; ··· 373 210 return -1; 374 211 } 375 212 376 - /** 377 - * pm_qos_request - returns current system wide qos expectation 378 - * @pm_qos_class: identification of which qos value is requested 379 - * 380 - * This function returns the current target value. 381 - */ 382 - int pm_qos_request(int pm_qos_class) 383 - { 384 - return pm_qos_read_value(pm_qos_array[pm_qos_class]); 385 - } 386 - EXPORT_SYMBOL_GPL(pm_qos_request); 387 - 388 - int pm_qos_request_active(struct pm_qos_request_list *req) 389 - { 390 - return req->pm_qos_class != 0; 391 - } 392 - EXPORT_SYMBOL_GPL(pm_qos_request_active); 393 - 394 - /** 395 - * pm_qos_add_request - inserts new qos request into the list 396 - * @dep: pointer to a preallocated handle 397 - * @pm_qos_class: identifies which list of qos request to use 398 - * @value: defines the qos request 399 - * 400 - * This function inserts a new entry in the pm_qos_class list of requested qos 401 - * performance characteristics. It recomputes the aggregate QoS expectations 402 - * for the pm_qos_class of parameters and initializes the pm_qos_request_list 403 - * handle. Caller needs to save this handle for later use in updates and 404 - * removal. 405 - */ 406 - 407 - void pm_qos_add_request(struct pm_qos_request_list *dep, 408 - int pm_qos_class, s32 value) 409 - { 410 - struct pm_qos_object *o = pm_qos_array[pm_qos_class]; 411 - int new_value; 412 - 413 - if (pm_qos_request_active(dep)) { 414 - WARN(1, KERN_ERR "pm_qos_add_request() called for already added request\n"); 415 - return; 416 - } 417 - if (value == PM_QOS_DEFAULT_VALUE) 418 - new_value = o->default_value; 419 - else 420 - new_value = value; 421 - plist_node_init(&dep->list, new_value); 422 - dep->pm_qos_class = pm_qos_class; 423 - update_target(o, &dep->list, 0, PM_QOS_DEFAULT_VALUE); 424 - } 425 - EXPORT_SYMBOL_GPL(pm_qos_add_request); 426 - 427 - /** 428 - * pm_qos_update_request - modifies an existing qos request 429 - * @pm_qos_req : handle to list element holding a pm_qos request to use 430 - * @value: defines the qos request 431 - * 432 - * Updates an existing qos request for the pm_qos_class of parameters along 433 - * with updating the target pm_qos_class value. 434 - * 435 - * Attempts are made to make this code callable on hot code paths. 436 - */ 437 - void pm_qos_update_request(struct pm_qos_request_list *pm_qos_req, 438 - s32 new_value) 439 - { 440 - s32 temp; 441 - struct pm_qos_object *o; 442 - 443 - if (!pm_qos_req) /*guard against callers passing in null */ 444 - return; 445 - 446 - if (!pm_qos_request_active(pm_qos_req)) { 447 - WARN(1, KERN_ERR "pm_qos_update_request() called for unknown object\n"); 448 - return; 449 - } 450 - 451 - o = pm_qos_array[pm_qos_req->pm_qos_class]; 452 - 453 - if (new_value == PM_QOS_DEFAULT_VALUE) 454 - temp = o->default_value; 455 - else 456 - temp = new_value; 457 - 458 - if (temp != pm_qos_req->list.prio) 459 - update_target(o, &pm_qos_req->list, 0, temp); 460 - } 461 - EXPORT_SYMBOL_GPL(pm_qos_update_request); 462 - 463 - /** 464 - * pm_qos_remove_request - modifies an existing qos request 465 - * @pm_qos_req: handle to request list element 466 - * 467 - * Will remove pm qos request from the list of requests and 468 - * recompute the current target value for the pm_qos_class. Call this 469 - * on slow code paths. 470 - */ 471 - void pm_qos_remove_request(struct pm_qos_request_list *pm_qos_req) 472 - { 473 - struct pm_qos_object *o; 474 - 475 - if (pm_qos_req == NULL) 476 - return; 477 - /* silent return to keep pcm code cleaner */ 478 - 479 - if (!pm_qos_request_active(pm_qos_req)) { 480 - WARN(1, KERN_ERR "pm_qos_remove_request() called for unknown object\n"); 481 - return; 482 - } 483 - 484 - o = pm_qos_array[pm_qos_req->pm_qos_class]; 485 - update_target(o, &pm_qos_req->list, 1, PM_QOS_DEFAULT_VALUE); 486 - memset(pm_qos_req, 0, sizeof(*pm_qos_req)); 487 - } 488 - EXPORT_SYMBOL_GPL(pm_qos_remove_request); 489 - 490 - /** 491 - * pm_qos_add_notifier - sets notification entry for changes to target value 492 - * @pm_qos_class: identifies which qos target changes should be notified. 493 - * @notifier: notifier block managed by caller. 494 - * 495 - * will register the notifier into a notification chain that gets called 496 - * upon changes to the pm_qos_class target value. 497 - */ 498 - int pm_qos_add_notifier(int pm_qos_class, struct notifier_block *notifier) 499 - { 500 - int retval; 501 - 502 - retval = blocking_notifier_chain_register( 503 - pm_qos_array[pm_qos_class]->notifiers, notifier); 504 - 505 - return retval; 506 - } 507 - EXPORT_SYMBOL_GPL(pm_qos_add_notifier); 508 - 509 - /** 510 - * pm_qos_remove_notifier - deletes notification entry from chain. 511 - * @pm_qos_class: identifies which qos target changes are notified. 512 - * @notifier: notifier block to be removed. 513 - * 514 - * will remove the notifier from the notification chain that gets called 515 - * upon changes to the pm_qos_class target value. 516 - */ 517 - int pm_qos_remove_notifier(int pm_qos_class, struct notifier_block *notifier) 518 - { 519 - int retval; 520 - 521 - retval = blocking_notifier_chain_unregister( 522 - pm_qos_array[pm_qos_class]->notifiers, notifier); 523 - 524 - return retval; 525 - } 526 - EXPORT_SYMBOL_GPL(pm_qos_remove_notifier); 527 - 528 213 static int pm_qos_power_open(struct inode *inode, struct file *filp) 529 214 { 530 215 long pm_qos_class; 531 216 532 217 pm_qos_class = find_pm_qos_object_by_minor(iminor(inode)); 533 218 if (pm_qos_class >= 0) { 534 - struct pm_qos_request_list *req = kzalloc(sizeof(*req), GFP_KERNEL); 219 + struct pm_qos_request *req = kzalloc(sizeof(*req), GFP_KERNEL); 535 220 if (!req) 536 221 return -ENOMEM; 537 222 ··· 394 383 395 384 static int pm_qos_power_release(struct inode *inode, struct file *filp) 396 385 { 397 - struct pm_qos_request_list *req; 386 + struct pm_qos_request *req; 398 387 399 388 req = filp->private_data; 400 389 pm_qos_remove_request(req); ··· 409 398 { 410 399 s32 value; 411 400 unsigned long flags; 412 - struct pm_qos_object *o; 413 - struct pm_qos_request_list *pm_qos_req = filp->private_data; 401 + struct pm_qos_request *req = filp->private_data; 414 402 415 - if (!pm_qos_req) 403 + if (!req) 416 404 return -EINVAL; 417 - if (!pm_qos_request_active(pm_qos_req)) 405 + if (!pm_qos_request_active(req)) 418 406 return -EINVAL; 419 407 420 - o = pm_qos_array[pm_qos_req->pm_qos_class]; 421 408 spin_lock_irqsave(&pm_qos_lock, flags); 422 - value = pm_qos_get_value(o); 409 + value = pm_qos_get_value(pm_qos_array[req->pm_qos_class]->constraints); 423 410 spin_unlock_irqrestore(&pm_qos_lock, flags); 424 411 425 412 return simple_read_from_buffer(buf, count, f_pos, &value, sizeof(s32)); ··· 427 418 size_t count, loff_t *f_pos) 428 419 { 429 420 s32 value; 430 - struct pm_qos_request_list *pm_qos_req; 421 + struct pm_qos_request *req; 431 422 432 423 if (count == sizeof(s32)) { 433 424 if (copy_from_user(&value, buf, sizeof(s32))) ··· 458 449 return -EINVAL; 459 450 } 460 451 461 - pm_qos_req = filp->private_data; 462 - pm_qos_update_request(pm_qos_req, value); 452 + req = filp->private_data; 453 + pm_qos_update_request(req, value); 463 454 464 455 return count; 465 456 }
+1 -1
kernel/power/Makefile
··· 1 1 2 2 ccflags-$(CONFIG_PM_DEBUG) := -DDEBUG 3 3 4 - obj-$(CONFIG_PM) += main.o 4 + obj-$(CONFIG_PM) += main.o qos.o 5 5 obj-$(CONFIG_PM_SLEEP) += console.o 6 6 obj-$(CONFIG_FREEZER) += process.o 7 7 obj-$(CONFIG_SUSPEND) += suspend.o
+1 -1
net/mac80211/main.c
··· 19 19 #include <linux/if_arp.h> 20 20 #include <linux/rtnetlink.h> 21 21 #include <linux/bitmap.h> 22 - #include <linux/pm_qos_params.h> 22 + #include <linux/pm_qos.h> 23 23 #include <linux/inetdevice.h> 24 24 #include <net/net_namespace.h> 25 25 #include <net/cfg80211.h>
+1 -1
net/mac80211/mlme.c
··· 17 17 #include <linux/if_arp.h> 18 18 #include <linux/etherdevice.h> 19 19 #include <linux/rtnetlink.h> 20 - #include <linux/pm_qos_params.h> 20 + #include <linux/pm_qos.h> 21 21 #include <linux/crc32.h> 22 22 #include <linux/slab.h> 23 23 #include <net/mac80211.h>
+1 -1
net/mac80211/scan.c
··· 14 14 15 15 #include <linux/if_arp.h> 16 16 #include <linux/rtnetlink.h> 17 - #include <linux/pm_qos_params.h> 17 + #include <linux/pm_qos.h> 18 18 #include <net/sch_generic.h> 19 19 #include <linux/slab.h> 20 20 #include <net/mac80211.h>
+1 -1
sound/core/pcm_native.c
··· 23 23 #include <linux/file.h> 24 24 #include <linux/slab.h> 25 25 #include <linux/time.h> 26 - #include <linux/pm_qos_params.h> 26 + #include <linux/pm_qos.h> 27 27 #include <linux/uio.h> 28 28 #include <linux/dma-mapping.h> 29 29 #include <sound/core.h>