aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-11-16 18:18:17 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2010-11-16 18:18:17 -0500
commit1e8703b2e6aefba84dd9633d90a4093ff1200b93 (patch)
tree648c6a9ebd0ecfae1d5ef9c44e9996300b7232cd
parent45314915ed8089634144c975357bf5ba17f06ab9 (diff)
parent00fafcda1773245a5292f953321ec3f0668c8c28 (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.txt3
-rw-r--r--drivers/base/power/main.c34
-rw-r--r--kernel/pm_qos_params.c4
-rw-r--r--kernel/power/Kconfig4
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:
37SoC framework -> modifies on required cases certain OPPs -> OPP layer 37SoC framework -> modifies on required cases certain OPPs -> OPP layer
38 -> queries to search/retrieve information -> 38 -> queries to search/retrieve information ->
39 39
40Architectures that provide a SoC framework for OPP should select ARCH_HAS_OPP
41to make the OPP layer available.
42
40OPP layer expects each domain to be represented by a unique device pointer. SoC 43OPP layer expects each domain to be represented by a unique device pointer. SoC
41framework registers a set of initial OPPs per device with the OPP layer. This 44framework registers a set of initial OPPs per device with the OPP layer. This
42list is expected to be an optimally small number typically around 5 per device. 45list 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 */
476void dpm_resume_noirq(pm_message_t state) 476void 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 */
790int dpm_suspend_noirq(pm_message_t state) 803int 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
249config ARCH_HAS_OPP
250 bool
251
249config PM_OPP 252config 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