diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-11-16 18:18:17 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-11-16 18:18:17 -0500 |
commit | 1e8703b2e6aefba84dd9633d90a4093ff1200b93 (patch) | |
tree | 648c6a9ebd0ecfae1d5ef9c44e9996300b7232cd | |
parent | 45314915ed8089634144c975357bf5ba17f06ab9 (diff) | |
parent | 00fafcda1773245a5292f953321ec3f0668c8c28 (diff) |
Merge branch 'pm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/suspend-2.6
* 'pm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/suspend-2.6:
PM / PM QoS: Fix reversed min and max
PM / OPP: Hide OPP configuration when SoCs do not provide an implementation
PM: Allow devices to be removed during late suspend and early resume
-rw-r--r-- | Documentation/power/opp.txt | 3 | ||||
-rw-r--r-- | drivers/base/power/main.c | 34 | ||||
-rw-r--r-- | kernel/pm_qos_params.c | 4 | ||||
-rw-r--r-- | kernel/power/Kconfig | 4 |
4 files changed, 39 insertions, 6 deletions
diff --git a/Documentation/power/opp.txt b/Documentation/power/opp.txt index 44d87ad3cea9..cd445582d1f8 100644 --- a/Documentation/power/opp.txt +++ b/Documentation/power/opp.txt | |||
@@ -37,6 +37,9 @@ Typical usage of the OPP library is as follows: | |||
37 | SoC framework -> modifies on required cases certain OPPs -> OPP layer | 37 | SoC framework -> modifies on required cases certain OPPs -> OPP layer |
38 | -> queries to search/retrieve information -> | 38 | -> queries to search/retrieve information -> |
39 | 39 | ||
40 | Architectures that provide a SoC framework for OPP should select ARCH_HAS_OPP | ||
41 | to make the OPP layer available. | ||
42 | |||
40 | OPP layer expects each domain to be represented by a unique device pointer. SoC | 43 | OPP layer expects each domain to be represented by a unique device pointer. SoC |
41 | framework registers a set of initial OPPs per device with the OPP layer. This | 44 | framework registers a set of initial OPPs per device with the OPP layer. This |
42 | list is expected to be an optimally small number typically around 5 per device. | 45 | list is expected to be an optimally small number typically around 5 per device. |
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 31b526661ec4..ead3e79d6fcf 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c | |||
@@ -475,20 +475,33 @@ End: | |||
475 | */ | 475 | */ |
476 | void dpm_resume_noirq(pm_message_t state) | 476 | void dpm_resume_noirq(pm_message_t state) |
477 | { | 477 | { |
478 | struct device *dev; | 478 | struct list_head list; |
479 | ktime_t starttime = ktime_get(); | 479 | ktime_t starttime = ktime_get(); |
480 | 480 | ||
481 | INIT_LIST_HEAD(&list); | ||
481 | mutex_lock(&dpm_list_mtx); | 482 | mutex_lock(&dpm_list_mtx); |
482 | transition_started = false; | 483 | transition_started = false; |
483 | list_for_each_entry(dev, &dpm_list, power.entry) | 484 | while (!list_empty(&dpm_list)) { |
485 | struct device *dev = to_device(dpm_list.next); | ||
486 | |||
487 | get_device(dev); | ||
484 | if (dev->power.status > DPM_OFF) { | 488 | if (dev->power.status > DPM_OFF) { |
485 | int error; | 489 | int error; |
486 | 490 | ||
487 | dev->power.status = DPM_OFF; | 491 | dev->power.status = DPM_OFF; |
492 | mutex_unlock(&dpm_list_mtx); | ||
493 | |||
488 | error = device_resume_noirq(dev, state); | 494 | error = device_resume_noirq(dev, state); |
495 | |||
496 | mutex_lock(&dpm_list_mtx); | ||
489 | if (error) | 497 | if (error) |
490 | pm_dev_err(dev, state, " early", error); | 498 | pm_dev_err(dev, state, " early", error); |
491 | } | 499 | } |
500 | if (!list_empty(&dev->power.entry)) | ||
501 | list_move_tail(&dev->power.entry, &list); | ||
502 | put_device(dev); | ||
503 | } | ||
504 | list_splice(&list, &dpm_list); | ||
492 | mutex_unlock(&dpm_list_mtx); | 505 | mutex_unlock(&dpm_list_mtx); |
493 | dpm_show_time(starttime, state, "early"); | 506 | dpm_show_time(starttime, state, "early"); |
494 | resume_device_irqs(); | 507 | resume_device_irqs(); |
@@ -789,20 +802,33 @@ End: | |||
789 | */ | 802 | */ |
790 | int dpm_suspend_noirq(pm_message_t state) | 803 | int dpm_suspend_noirq(pm_message_t state) |
791 | { | 804 | { |
792 | struct device *dev; | 805 | struct list_head list; |
793 | ktime_t starttime = ktime_get(); | 806 | ktime_t starttime = ktime_get(); |
794 | int error = 0; | 807 | int error = 0; |
795 | 808 | ||
809 | INIT_LIST_HEAD(&list); | ||
796 | suspend_device_irqs(); | 810 | suspend_device_irqs(); |
797 | mutex_lock(&dpm_list_mtx); | 811 | mutex_lock(&dpm_list_mtx); |
798 | list_for_each_entry_reverse(dev, &dpm_list, power.entry) { | 812 | while (!list_empty(&dpm_list)) { |
813 | struct device *dev = to_device(dpm_list.prev); | ||
814 | |||
815 | get_device(dev); | ||
816 | mutex_unlock(&dpm_list_mtx); | ||
817 | |||
799 | error = device_suspend_noirq(dev, state); | 818 | error = device_suspend_noirq(dev, state); |
819 | |||
820 | mutex_lock(&dpm_list_mtx); | ||
800 | if (error) { | 821 | if (error) { |
801 | pm_dev_err(dev, state, " late", error); | 822 | pm_dev_err(dev, state, " late", error); |
823 | put_device(dev); | ||
802 | break; | 824 | break; |
803 | } | 825 | } |
804 | dev->power.status = DPM_OFF_IRQ; | 826 | dev->power.status = DPM_OFF_IRQ; |
827 | if (!list_empty(&dev->power.entry)) | ||
828 | list_move(&dev->power.entry, &list); | ||
829 | put_device(dev); | ||
805 | } | 830 | } |
831 | list_splice_tail(&list, &dpm_list); | ||
806 | mutex_unlock(&dpm_list_mtx); | 832 | mutex_unlock(&dpm_list_mtx); |
807 | if (error) | 833 | if (error) |
808 | dpm_resume_noirq(resume_event(state)); | 834 | dpm_resume_noirq(resume_event(state)); |
diff --git a/kernel/pm_qos_params.c b/kernel/pm_qos_params.c index c7a8f453919e..aeaa7f846821 100644 --- a/kernel/pm_qos_params.c +++ b/kernel/pm_qos_params.c | |||
@@ -121,10 +121,10 @@ static inline int pm_qos_get_value(struct pm_qos_object *o) | |||
121 | 121 | ||
122 | switch (o->type) { | 122 | switch (o->type) { |
123 | case PM_QOS_MIN: | 123 | case PM_QOS_MIN: |
124 | return plist_last(&o->requests)->prio; | 124 | return plist_first(&o->requests)->prio; |
125 | 125 | ||
126 | case PM_QOS_MAX: | 126 | case PM_QOS_MAX: |
127 | return plist_first(&o->requests)->prio; | 127 | return plist_last(&o->requests)->prio; |
128 | 128 | ||
129 | default: | 129 | default: |
130 | /* runtime check for not using enum */ | 130 | /* runtime check for not using enum */ |
diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig index 29bff6117abc..a5aff3ebad38 100644 --- a/kernel/power/Kconfig +++ b/kernel/power/Kconfig | |||
@@ -246,9 +246,13 @@ config PM_OPS | |||
246 | depends on PM_SLEEP || PM_RUNTIME | 246 | depends on PM_SLEEP || PM_RUNTIME |
247 | default y | 247 | default y |
248 | 248 | ||
249 | config ARCH_HAS_OPP | ||
250 | bool | ||
251 | |||
249 | config PM_OPP | 252 | config PM_OPP |
250 | bool "Operating Performance Point (OPP) Layer library" | 253 | bool "Operating Performance Point (OPP) Layer library" |
251 | depends on PM | 254 | depends on PM |
255 | depends on ARCH_HAS_OPP | ||
252 | ---help--- | 256 | ---help--- |
253 | SOCs have a standard set of tuples consisting of frequency and | 257 | SOCs have a standard set of tuples consisting of frequency and |
254 | voltage pairs that the device will support per voltage domain. This | 258 | voltage pairs that the device will support per voltage domain. This |