diff options
-rw-r--r-- | Documentation/ABI/testing/sysfs-devices-power | 31 | ||||
-rw-r--r-- | drivers/base/power/power.h | 6 | ||||
-rw-r--r-- | drivers/base/power/qos.c | 168 | ||||
-rw-r--r-- | drivers/base/power/sysfs.c | 94 | ||||
-rw-r--r-- | include/linux/pm.h | 1 | ||||
-rw-r--r-- | include/linux/pm_qos.h | 26 |
6 files changed, 278 insertions, 48 deletions
diff --git a/Documentation/ABI/testing/sysfs-devices-power b/Documentation/ABI/testing/sysfs-devices-power index 45000f0db4d4..7fc2997b23a6 100644 --- a/Documentation/ABI/testing/sysfs-devices-power +++ b/Documentation/ABI/testing/sysfs-devices-power | |||
@@ -204,3 +204,34 @@ Description: | |||
204 | 204 | ||
205 | This attribute has no effect on system-wide suspend/resume and | 205 | This attribute has no effect on system-wide suspend/resume and |
206 | hibernation. | 206 | hibernation. |
207 | |||
208 | What: /sys/devices/.../power/pm_qos_no_power_off | ||
209 | Date: September 2012 | ||
210 | Contact: Rafael J. Wysocki <rjw@sisk.pl> | ||
211 | Description: | ||
212 | The /sys/devices/.../power/pm_qos_no_power_off attribute | ||
213 | is used for manipulating the PM QoS "no power off" flag. If | ||
214 | set, this flag indicates to the kernel that power should not | ||
215 | be removed entirely from the device. | ||
216 | |||
217 | Not all drivers support this attribute. If it isn't supported, | ||
218 | it is not present. | ||
219 | |||
220 | This attribute has no effect on system-wide suspend/resume and | ||
221 | hibernation. | ||
222 | |||
223 | What: /sys/devices/.../power/pm_qos_remote_wakeup | ||
224 | Date: September 2012 | ||
225 | Contact: Rafael J. Wysocki <rjw@sisk.pl> | ||
226 | Description: | ||
227 | The /sys/devices/.../power/pm_qos_remote_wakeup attribute | ||
228 | is used for manipulating the PM QoS "remote wakeup required" | ||
229 | flag. If set, this flag indicates to the kernel that the | ||
230 | device is a source of user events that have to be signaled from | ||
231 | its low-power states. | ||
232 | |||
233 | Not all drivers support this attribute. If it isn't supported, | ||
234 | it is not present. | ||
235 | |||
236 | This attribute has no effect on system-wide suspend/resume and | ||
237 | hibernation. | ||
diff --git a/drivers/base/power/power.h b/drivers/base/power/power.h index 0dbfdf4419af..b16686a0a5a2 100644 --- a/drivers/base/power/power.h +++ b/drivers/base/power/power.h | |||
@@ -93,8 +93,10 @@ extern void dpm_sysfs_remove(struct device *dev); | |||
93 | extern void rpm_sysfs_remove(struct device *dev); | 93 | extern void rpm_sysfs_remove(struct device *dev); |
94 | extern int wakeup_sysfs_add(struct device *dev); | 94 | extern int wakeup_sysfs_add(struct device *dev); |
95 | extern void wakeup_sysfs_remove(struct device *dev); | 95 | extern void wakeup_sysfs_remove(struct device *dev); |
96 | extern int pm_qos_sysfs_add(struct device *dev); | 96 | extern int pm_qos_sysfs_add_latency(struct device *dev); |
97 | extern void pm_qos_sysfs_remove(struct device *dev); | 97 | extern void pm_qos_sysfs_remove_latency(struct device *dev); |
98 | extern int pm_qos_sysfs_add_flags(struct device *dev); | ||
99 | extern void pm_qos_sysfs_remove_flags(struct device *dev); | ||
98 | 100 | ||
99 | #else /* CONFIG_PM */ | 101 | #else /* CONFIG_PM */ |
100 | 102 | ||
diff --git a/drivers/base/power/qos.c b/drivers/base/power/qos.c index 3c66f75d14b0..167834dcc82a 100644 --- a/drivers/base/power/qos.c +++ b/drivers/base/power/qos.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <linux/device.h> | 40 | #include <linux/device.h> |
41 | #include <linux/mutex.h> | 41 | #include <linux/mutex.h> |
42 | #include <linux/export.h> | 42 | #include <linux/export.h> |
43 | #include <linux/pm_runtime.h> | ||
43 | 44 | ||
44 | #include "power.h" | 45 | #include "power.h" |
45 | 46 | ||
@@ -322,6 +323,37 @@ int dev_pm_qos_add_request(struct device *dev, struct dev_pm_qos_request *req, | |||
322 | EXPORT_SYMBOL_GPL(dev_pm_qos_add_request); | 323 | EXPORT_SYMBOL_GPL(dev_pm_qos_add_request); |
323 | 324 | ||
324 | /** | 325 | /** |
326 | * __dev_pm_qos_update_request - Modify an existing device PM QoS request. | ||
327 | * @req : PM QoS request to modify. | ||
328 | * @new_value: New value to request. | ||
329 | */ | ||
330 | static int __dev_pm_qos_update_request(struct dev_pm_qos_request *req, | ||
331 | s32 new_value) | ||
332 | { | ||
333 | s32 curr_value; | ||
334 | int ret = 0; | ||
335 | |||
336 | if (!req->dev->power.qos) | ||
337 | return -ENODEV; | ||
338 | |||
339 | switch(req->type) { | ||
340 | case DEV_PM_QOS_LATENCY: | ||
341 | curr_value = req->data.pnode.prio; | ||
342 | break; | ||
343 | case DEV_PM_QOS_FLAGS: | ||
344 | curr_value = req->data.flr.flags; | ||
345 | break; | ||
346 | default: | ||
347 | return -EINVAL; | ||
348 | } | ||
349 | |||
350 | if (curr_value != new_value) | ||
351 | ret = apply_constraint(req, PM_QOS_UPDATE_REQ, new_value); | ||
352 | |||
353 | return ret; | ||
354 | } | ||
355 | |||
356 | /** | ||
325 | * dev_pm_qos_update_request - modifies an existing qos request | 357 | * dev_pm_qos_update_request - modifies an existing qos request |
326 | * @req : handle to list element holding a dev_pm_qos request to use | 358 | * @req : handle to list element holding a dev_pm_qos request to use |
327 | * @new_value: defines the qos request | 359 | * @new_value: defines the qos request |
@@ -336,11 +368,9 @@ EXPORT_SYMBOL_GPL(dev_pm_qos_add_request); | |||
336 | * -EINVAL in case of wrong parameters, -ENODEV if the device has been | 368 | * -EINVAL in case of wrong parameters, -ENODEV if the device has been |
337 | * removed from the system | 369 | * removed from the system |
338 | */ | 370 | */ |
339 | int dev_pm_qos_update_request(struct dev_pm_qos_request *req, | 371 | int dev_pm_qos_update_request(struct dev_pm_qos_request *req, s32 new_value) |
340 | s32 new_value) | ||
341 | { | 372 | { |
342 | s32 curr_value; | 373 | int ret; |
343 | int ret = 0; | ||
344 | 374 | ||
345 | if (!req) /*guard against callers passing in null */ | 375 | if (!req) /*guard against callers passing in null */ |
346 | return -EINVAL; | 376 | return -EINVAL; |
@@ -350,29 +380,9 @@ int dev_pm_qos_update_request(struct dev_pm_qos_request *req, | |||
350 | return -EINVAL; | 380 | return -EINVAL; |
351 | 381 | ||
352 | mutex_lock(&dev_pm_qos_mtx); | 382 | mutex_lock(&dev_pm_qos_mtx); |
353 | 383 | __dev_pm_qos_update_request(req, new_value); | |
354 | if (!req->dev->power.qos) { | ||
355 | ret = -ENODEV; | ||
356 | goto out; | ||
357 | } | ||
358 | |||
359 | switch(req->type) { | ||
360 | case DEV_PM_QOS_LATENCY: | ||
361 | curr_value = req->data.pnode.prio; | ||
362 | break; | ||
363 | case DEV_PM_QOS_FLAGS: | ||
364 | curr_value = req->data.flr.flags; | ||
365 | break; | ||
366 | default: | ||
367 | ret = -EINVAL; | ||
368 | goto out; | ||
369 | } | ||
370 | |||
371 | if (curr_value != new_value) | ||
372 | ret = apply_constraint(req, PM_QOS_UPDATE_REQ, new_value); | ||
373 | |||
374 | out: | ||
375 | mutex_unlock(&dev_pm_qos_mtx); | 384 | mutex_unlock(&dev_pm_qos_mtx); |
385 | |||
376 | return ret; | 386 | return ret; |
377 | } | 387 | } |
378 | EXPORT_SYMBOL_GPL(dev_pm_qos_update_request); | 388 | EXPORT_SYMBOL_GPL(dev_pm_qos_update_request); |
@@ -533,10 +543,19 @@ int dev_pm_qos_add_ancestor_request(struct device *dev, | |||
533 | EXPORT_SYMBOL_GPL(dev_pm_qos_add_ancestor_request); | 543 | EXPORT_SYMBOL_GPL(dev_pm_qos_add_ancestor_request); |
534 | 544 | ||
535 | #ifdef CONFIG_PM_RUNTIME | 545 | #ifdef CONFIG_PM_RUNTIME |
536 | static void __dev_pm_qos_drop_user_request(struct device *dev) | 546 | static void __dev_pm_qos_drop_user_request(struct device *dev, |
547 | enum dev_pm_qos_req_type type) | ||
537 | { | 548 | { |
538 | dev_pm_qos_remove_request(dev->power.pq_req); | 549 | switch(type) { |
539 | dev->power.pq_req = NULL; | 550 | case DEV_PM_QOS_LATENCY: |
551 | dev_pm_qos_remove_request(dev->power.qos->latency_req); | ||
552 | dev->power.qos->latency_req = NULL; | ||
553 | break; | ||
554 | case DEV_PM_QOS_FLAGS: | ||
555 | dev_pm_qos_remove_request(dev->power.qos->flags_req); | ||
556 | dev->power.qos->flags_req = NULL; | ||
557 | break; | ||
558 | } | ||
540 | } | 559 | } |
541 | 560 | ||
542 | /** | 561 | /** |
@@ -552,7 +571,7 @@ int dev_pm_qos_expose_latency_limit(struct device *dev, s32 value) | |||
552 | if (!device_is_registered(dev) || value < 0) | 571 | if (!device_is_registered(dev) || value < 0) |
553 | return -EINVAL; | 572 | return -EINVAL; |
554 | 573 | ||
555 | if (dev->power.pq_req) | 574 | if (dev->power.qos && dev->power.qos->latency_req) |
556 | return -EEXIST; | 575 | return -EEXIST; |
557 | 576 | ||
558 | req = kzalloc(sizeof(*req), GFP_KERNEL); | 577 | req = kzalloc(sizeof(*req), GFP_KERNEL); |
@@ -563,10 +582,10 @@ int dev_pm_qos_expose_latency_limit(struct device *dev, s32 value) | |||
563 | if (ret < 0) | 582 | if (ret < 0) |
564 | return ret; | 583 | return ret; |
565 | 584 | ||
566 | dev->power.pq_req = req; | 585 | dev->power.qos->latency_req = req; |
567 | ret = pm_qos_sysfs_add(dev); | 586 | ret = pm_qos_sysfs_add_latency(dev); |
568 | if (ret) | 587 | if (ret) |
569 | __dev_pm_qos_drop_user_request(dev); | 588 | __dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_LATENCY); |
570 | 589 | ||
571 | return ret; | 590 | return ret; |
572 | } | 591 | } |
@@ -578,10 +597,87 @@ EXPORT_SYMBOL_GPL(dev_pm_qos_expose_latency_limit); | |||
578 | */ | 597 | */ |
579 | void dev_pm_qos_hide_latency_limit(struct device *dev) | 598 | void dev_pm_qos_hide_latency_limit(struct device *dev) |
580 | { | 599 | { |
581 | if (dev->power.pq_req) { | 600 | if (dev->power.qos && dev->power.qos->latency_req) { |
582 | pm_qos_sysfs_remove(dev); | 601 | pm_qos_sysfs_remove_latency(dev); |
583 | __dev_pm_qos_drop_user_request(dev); | 602 | __dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_LATENCY); |
584 | } | 603 | } |
585 | } | 604 | } |
586 | EXPORT_SYMBOL_GPL(dev_pm_qos_hide_latency_limit); | 605 | EXPORT_SYMBOL_GPL(dev_pm_qos_hide_latency_limit); |
606 | |||
607 | /** | ||
608 | * dev_pm_qos_expose_flags - Expose PM QoS flags of a device to user space. | ||
609 | * @dev: Device whose PM QoS flags are to be exposed to user space. | ||
610 | * @val: Initial values of the flags. | ||
611 | */ | ||
612 | int dev_pm_qos_expose_flags(struct device *dev, s32 val) | ||
613 | { | ||
614 | struct dev_pm_qos_request *req; | ||
615 | int ret; | ||
616 | |||
617 | if (!device_is_registered(dev)) | ||
618 | return -EINVAL; | ||
619 | |||
620 | if (dev->power.qos && dev->power.qos->flags_req) | ||
621 | return -EEXIST; | ||
622 | |||
623 | req = kzalloc(sizeof(*req), GFP_KERNEL); | ||
624 | if (!req) | ||
625 | return -ENOMEM; | ||
626 | |||
627 | ret = dev_pm_qos_add_request(dev, req, DEV_PM_QOS_FLAGS, val); | ||
628 | if (ret < 0) | ||
629 | return ret; | ||
630 | |||
631 | dev->power.qos->flags_req = req; | ||
632 | ret = pm_qos_sysfs_add_flags(dev); | ||
633 | if (ret) | ||
634 | __dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_FLAGS); | ||
635 | |||
636 | return ret; | ||
637 | } | ||
638 | EXPORT_SYMBOL_GPL(dev_pm_qos_expose_flags); | ||
639 | |||
640 | /** | ||
641 | * dev_pm_qos_hide_flags - Hide PM QoS flags of a device from user space. | ||
642 | * @dev: Device whose PM QoS flags are to be hidden from user space. | ||
643 | */ | ||
644 | void dev_pm_qos_hide_flags(struct device *dev) | ||
645 | { | ||
646 | if (dev->power.qos && dev->power.qos->flags_req) { | ||
647 | pm_qos_sysfs_remove_flags(dev); | ||
648 | __dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_FLAGS); | ||
649 | } | ||
650 | } | ||
651 | EXPORT_SYMBOL_GPL(dev_pm_qos_hide_flags); | ||
652 | |||
653 | /** | ||
654 | * dev_pm_qos_update_flags - Update PM QoS flags request owned by user space. | ||
655 | * @dev: Device to update the PM QoS flags request for. | ||
656 | * @mask: Flags to set/clear. | ||
657 | * @set: Whether to set or clear the flags (true means set). | ||
658 | */ | ||
659 | int dev_pm_qos_update_flags(struct device *dev, s32 mask, bool set) | ||
660 | { | ||
661 | s32 value; | ||
662 | int ret; | ||
663 | |||
664 | if (!dev->power.qos || !dev->power.qos->flags_req) | ||
665 | return -EINVAL; | ||
666 | |||
667 | pm_runtime_get_sync(dev); | ||
668 | mutex_lock(&dev_pm_qos_mtx); | ||
669 | |||
670 | value = dev_pm_qos_requested_flags(dev); | ||
671 | if (set) | ||
672 | value |= mask; | ||
673 | else | ||
674 | value &= ~mask; | ||
675 | |||
676 | ret = __dev_pm_qos_update_request(dev->power.qos->flags_req, value); | ||
677 | |||
678 | mutex_unlock(&dev_pm_qos_mtx); | ||
679 | pm_runtime_put(dev); | ||
680 | |||
681 | return ret; | ||
682 | } | ||
587 | #endif /* CONFIG_PM_RUNTIME */ | 683 | #endif /* CONFIG_PM_RUNTIME */ |
diff --git a/drivers/base/power/sysfs.c b/drivers/base/power/sysfs.c index 54c61ffa2044..50d16e3cb0a9 100644 --- a/drivers/base/power/sysfs.c +++ b/drivers/base/power/sysfs.c | |||
@@ -221,7 +221,7 @@ static DEVICE_ATTR(autosuspend_delay_ms, 0644, autosuspend_delay_ms_show, | |||
221 | static ssize_t pm_qos_latency_show(struct device *dev, | 221 | static ssize_t pm_qos_latency_show(struct device *dev, |
222 | struct device_attribute *attr, char *buf) | 222 | struct device_attribute *attr, char *buf) |
223 | { | 223 | { |
224 | return sprintf(buf, "%d\n", dev->power.pq_req->data.pnode.prio); | 224 | return sprintf(buf, "%d\n", dev_pm_qos_requested_latency(dev)); |
225 | } | 225 | } |
226 | 226 | ||
227 | static ssize_t pm_qos_latency_store(struct device *dev, | 227 | static ssize_t pm_qos_latency_store(struct device *dev, |
@@ -237,12 +237,66 @@ static ssize_t pm_qos_latency_store(struct device *dev, | |||
237 | if (value < 0) | 237 | if (value < 0) |
238 | return -EINVAL; | 238 | return -EINVAL; |
239 | 239 | ||
240 | ret = dev_pm_qos_update_request(dev->power.pq_req, value); | 240 | ret = dev_pm_qos_update_request(dev->power.qos->latency_req, value); |
241 | return ret < 0 ? ret : n; | 241 | return ret < 0 ? ret : n; |
242 | } | 242 | } |
243 | 243 | ||
244 | static DEVICE_ATTR(pm_qos_resume_latency_us, 0644, | 244 | static DEVICE_ATTR(pm_qos_resume_latency_us, 0644, |
245 | pm_qos_latency_show, pm_qos_latency_store); | 245 | pm_qos_latency_show, pm_qos_latency_store); |
246 | |||
247 | static ssize_t pm_qos_no_power_off_show(struct device *dev, | ||
248 | struct device_attribute *attr, | ||
249 | char *buf) | ||
250 | { | ||
251 | return sprintf(buf, "%d\n", !!(dev_pm_qos_requested_flags(dev) | ||
252 | & PM_QOS_FLAG_NO_POWER_OFF)); | ||
253 | } | ||
254 | |||
255 | static ssize_t pm_qos_no_power_off_store(struct device *dev, | ||
256 | struct device_attribute *attr, | ||
257 | const char *buf, size_t n) | ||
258 | { | ||
259 | int ret; | ||
260 | |||
261 | if (kstrtoint(buf, 0, &ret)) | ||
262 | return -EINVAL; | ||
263 | |||
264 | if (ret != 0 && ret != 1) | ||
265 | return -EINVAL; | ||
266 | |||
267 | ret = dev_pm_qos_update_flags(dev, PM_QOS_FLAG_NO_POWER_OFF, ret); | ||
268 | return ret < 0 ? ret : n; | ||
269 | } | ||
270 | |||
271 | static DEVICE_ATTR(pm_qos_no_power_off, 0644, | ||
272 | pm_qos_no_power_off_show, pm_qos_no_power_off_store); | ||
273 | |||
274 | static ssize_t pm_qos_remote_wakeup_show(struct device *dev, | ||
275 | struct device_attribute *attr, | ||
276 | char *buf) | ||
277 | { | ||
278 | return sprintf(buf, "%d\n", !!(dev_pm_qos_requested_flags(dev) | ||
279 | & PM_QOS_FLAG_REMOTE_WAKEUP)); | ||
280 | } | ||
281 | |||
282 | static ssize_t pm_qos_remote_wakeup_store(struct device *dev, | ||
283 | struct device_attribute *attr, | ||
284 | const char *buf, size_t n) | ||
285 | { | ||
286 | int ret; | ||
287 | |||
288 | if (kstrtoint(buf, 0, &ret)) | ||
289 | return -EINVAL; | ||
290 | |||
291 | if (ret != 0 && ret != 1) | ||
292 | return -EINVAL; | ||
293 | |||
294 | ret = dev_pm_qos_update_flags(dev, PM_QOS_FLAG_REMOTE_WAKEUP, ret); | ||
295 | return ret < 0 ? ret : n; | ||
296 | } | ||
297 | |||
298 | static DEVICE_ATTR(pm_qos_remote_wakeup, 0644, | ||
299 | pm_qos_remote_wakeup_show, pm_qos_remote_wakeup_store); | ||
246 | #endif /* CONFIG_PM_RUNTIME */ | 300 | #endif /* CONFIG_PM_RUNTIME */ |
247 | 301 | ||
248 | #ifdef CONFIG_PM_SLEEP | 302 | #ifdef CONFIG_PM_SLEEP |
@@ -564,15 +618,27 @@ static struct attribute_group pm_runtime_attr_group = { | |||
564 | .attrs = runtime_attrs, | 618 | .attrs = runtime_attrs, |
565 | }; | 619 | }; |
566 | 620 | ||
567 | static struct attribute *pm_qos_attrs[] = { | 621 | static struct attribute *pm_qos_latency_attrs[] = { |
568 | #ifdef CONFIG_PM_RUNTIME | 622 | #ifdef CONFIG_PM_RUNTIME |
569 | &dev_attr_pm_qos_resume_latency_us.attr, | 623 | &dev_attr_pm_qos_resume_latency_us.attr, |
570 | #endif /* CONFIG_PM_RUNTIME */ | 624 | #endif /* CONFIG_PM_RUNTIME */ |
571 | NULL, | 625 | NULL, |
572 | }; | 626 | }; |
573 | static struct attribute_group pm_qos_attr_group = { | 627 | static struct attribute_group pm_qos_latency_attr_group = { |
574 | .name = power_group_name, | 628 | .name = power_group_name, |
575 | .attrs = pm_qos_attrs, | 629 | .attrs = pm_qos_latency_attrs, |
630 | }; | ||
631 | |||
632 | static struct attribute *pm_qos_flags_attrs[] = { | ||
633 | #ifdef CONFIG_PM_RUNTIME | ||
634 | &dev_attr_pm_qos_no_power_off.attr, | ||
635 | &dev_attr_pm_qos_remote_wakeup.attr, | ||
636 | #endif /* CONFIG_PM_RUNTIME */ | ||
637 | NULL, | ||
638 | }; | ||
639 | static struct attribute_group pm_qos_flags_attr_group = { | ||
640 | .name = power_group_name, | ||
641 | .attrs = pm_qos_flags_attrs, | ||
576 | }; | 642 | }; |
577 | 643 | ||
578 | int dpm_sysfs_add(struct device *dev) | 644 | int dpm_sysfs_add(struct device *dev) |
@@ -615,14 +681,24 @@ void wakeup_sysfs_remove(struct device *dev) | |||
615 | sysfs_unmerge_group(&dev->kobj, &pm_wakeup_attr_group); | 681 | sysfs_unmerge_group(&dev->kobj, &pm_wakeup_attr_group); |
616 | } | 682 | } |
617 | 683 | ||
618 | int pm_qos_sysfs_add(struct device *dev) | 684 | int pm_qos_sysfs_add_latency(struct device *dev) |
685 | { | ||
686 | return sysfs_merge_group(&dev->kobj, &pm_qos_latency_attr_group); | ||
687 | } | ||
688 | |||
689 | void pm_qos_sysfs_remove_latency(struct device *dev) | ||
690 | { | ||
691 | sysfs_unmerge_group(&dev->kobj, &pm_qos_latency_attr_group); | ||
692 | } | ||
693 | |||
694 | int pm_qos_sysfs_add_flags(struct device *dev) | ||
619 | { | 695 | { |
620 | return sysfs_merge_group(&dev->kobj, &pm_qos_attr_group); | 696 | return sysfs_merge_group(&dev->kobj, &pm_qos_flags_attr_group); |
621 | } | 697 | } |
622 | 698 | ||
623 | void pm_qos_sysfs_remove(struct device *dev) | 699 | void pm_qos_sysfs_remove_flags(struct device *dev) |
624 | { | 700 | { |
625 | sysfs_unmerge_group(&dev->kobj, &pm_qos_attr_group); | 701 | sysfs_unmerge_group(&dev->kobj, &pm_qos_flags_attr_group); |
626 | } | 702 | } |
627 | 703 | ||
628 | void rpm_sysfs_remove(struct device *dev) | 704 | void rpm_sysfs_remove(struct device *dev) |
diff --git a/include/linux/pm.h b/include/linux/pm.h index 0ce6df94221a..03d7bb145311 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h | |||
@@ -546,7 +546,6 @@ struct dev_pm_info { | |||
546 | unsigned long active_jiffies; | 546 | unsigned long active_jiffies; |
547 | unsigned long suspended_jiffies; | 547 | unsigned long suspended_jiffies; |
548 | unsigned long accounting_timestamp; | 548 | unsigned long accounting_timestamp; |
549 | struct dev_pm_qos_request *pq_req; | ||
550 | #endif | 549 | #endif |
551 | struct pm_subsys_data *subsys_data; /* Owned by the subsystem. */ | 550 | struct pm_subsys_data *subsys_data; /* Owned by the subsystem. */ |
552 | struct dev_pm_qos *qos; | 551 | struct dev_pm_qos *qos; |
diff --git a/include/linux/pm_qos.h b/include/linux/pm_qos.h index 3af7d8573c23..5a95013905c8 100644 --- a/include/linux/pm_qos.h +++ b/include/linux/pm_qos.h | |||
@@ -34,6 +34,9 @@ enum pm_qos_flags_status { | |||
34 | #define PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE 0 | 34 | #define PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE 0 |
35 | #define PM_QOS_DEV_LAT_DEFAULT_VALUE 0 | 35 | #define PM_QOS_DEV_LAT_DEFAULT_VALUE 0 |
36 | 36 | ||
37 | #define PM_QOS_FLAG_NO_POWER_OFF (1 << 0) | ||
38 | #define PM_QOS_FLAG_REMOTE_WAKEUP (1 << 1) | ||
39 | |||
37 | struct pm_qos_request { | 40 | struct pm_qos_request { |
38 | struct plist_node node; | 41 | struct plist_node node; |
39 | int pm_qos_class; | 42 | int pm_qos_class; |
@@ -86,6 +89,8 @@ struct pm_qos_flags { | |||
86 | struct dev_pm_qos { | 89 | struct dev_pm_qos { |
87 | struct pm_qos_constraints latency; | 90 | struct pm_qos_constraints latency; |
88 | struct pm_qos_flags flags; | 91 | struct pm_qos_flags flags; |
92 | struct dev_pm_qos_request *latency_req; | ||
93 | struct dev_pm_qos_request *flags_req; | ||
89 | }; | 94 | }; |
90 | 95 | ||
91 | /* Action requested to pm_qos_update_target */ | 96 | /* Action requested to pm_qos_update_target */ |
@@ -187,10 +192,31 @@ static inline int dev_pm_qos_add_ancestor_request(struct device *dev, | |||
187 | #ifdef CONFIG_PM_RUNTIME | 192 | #ifdef CONFIG_PM_RUNTIME |
188 | int dev_pm_qos_expose_latency_limit(struct device *dev, s32 value); | 193 | int dev_pm_qos_expose_latency_limit(struct device *dev, s32 value); |
189 | void dev_pm_qos_hide_latency_limit(struct device *dev); | 194 | void dev_pm_qos_hide_latency_limit(struct device *dev); |
195 | int dev_pm_qos_expose_flags(struct device *dev, s32 value); | ||
196 | void dev_pm_qos_hide_flags(struct device *dev); | ||
197 | int dev_pm_qos_update_flags(struct device *dev, s32 mask, bool set); | ||
198 | |||
199 | static inline s32 dev_pm_qos_requested_latency(struct device *dev) | ||
200 | { | ||
201 | return dev->power.qos->latency_req->data.pnode.prio; | ||
202 | } | ||
203 | |||
204 | static inline s32 dev_pm_qos_requested_flags(struct device *dev) | ||
205 | { | ||
206 | return dev->power.qos->flags_req->data.flr.flags; | ||
207 | } | ||
190 | #else | 208 | #else |
191 | static inline int dev_pm_qos_expose_latency_limit(struct device *dev, s32 value) | 209 | static inline int dev_pm_qos_expose_latency_limit(struct device *dev, s32 value) |
192 | { return 0; } | 210 | { return 0; } |
193 | static inline void dev_pm_qos_hide_latency_limit(struct device *dev) {} | 211 | static inline void dev_pm_qos_hide_latency_limit(struct device *dev) {} |
212 | static inline int dev_pm_qos_expose_flags(struct device *dev, s32 value) | ||
213 | { return 0; } | ||
214 | static inline void dev_pm_qos_hide_flags(struct device *dev) {} | ||
215 | static inline int dev_pm_qos_update_flags(struct device *dev, s32 m, bool set) | ||
216 | { return 0; } | ||
217 | |||
218 | static inline s32 dev_pm_qos_requested_latency(struct device *dev) { return 0; } | ||
219 | static inline s32 dev_pm_qos_requested_flags(struct device *dev) { return 0; } | ||
194 | #endif | 220 | #endif |
195 | 221 | ||
196 | #endif | 222 | #endif |