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

+39 -6
+3
Documentation/power/opp.txt
··· 37 SoC framework -> modifies on required cases certain OPPs -> OPP layer 38 -> queries to search/retrieve information -> 39 40 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 42 list is expected to be an optimally small number typically around 5 per device.
··· 37 SoC framework -> modifies on required cases certain OPPs -> OPP layer 38 -> queries to search/retrieve information -> 39 40 + Architectures that provide a SoC framework for OPP should select ARCH_HAS_OPP 41 + to make the OPP layer available. 42 + 43 OPP layer expects each domain to be represented by a unique device pointer. SoC 44 framework registers a set of initial OPPs per device with the OPP layer. This 45 list is expected to be an optimally small number typically around 5 per device.
+30 -4
drivers/base/power/main.c
··· 475 */ 476 void dpm_resume_noirq(pm_message_t state) 477 { 478 - struct device *dev; 479 ktime_t starttime = ktime_get(); 480 481 mutex_lock(&dpm_list_mtx); 482 transition_started = false; 483 - list_for_each_entry(dev, &dpm_list, power.entry) 484 if (dev->power.status > DPM_OFF) { 485 int error; 486 487 dev->power.status = DPM_OFF; 488 error = device_resume_noirq(dev, state); 489 if (error) 490 pm_dev_err(dev, state, " early", error); 491 } 492 mutex_unlock(&dpm_list_mtx); 493 dpm_show_time(starttime, state, "early"); 494 resume_device_irqs(); ··· 802 */ 803 int dpm_suspend_noirq(pm_message_t state) 804 { 805 - struct device *dev; 806 ktime_t starttime = ktime_get(); 807 int error = 0; 808 809 suspend_device_irqs(); 810 mutex_lock(&dpm_list_mtx); 811 - list_for_each_entry_reverse(dev, &dpm_list, power.entry) { 812 error = device_suspend_noirq(dev, state); 813 if (error) { 814 pm_dev_err(dev, state, " late", error); 815 break; 816 } 817 dev->power.status = DPM_OFF_IRQ; 818 } 819 mutex_unlock(&dpm_list_mtx); 820 if (error) 821 dpm_resume_noirq(resume_event(state));
··· 475 */ 476 void dpm_resume_noirq(pm_message_t state) 477 { 478 + struct list_head list; 479 ktime_t starttime = ktime_get(); 480 481 + INIT_LIST_HEAD(&list); 482 mutex_lock(&dpm_list_mtx); 483 transition_started = false; 484 + while (!list_empty(&dpm_list)) { 485 + struct device *dev = to_device(dpm_list.next); 486 + 487 + get_device(dev); 488 if (dev->power.status > DPM_OFF) { 489 int error; 490 491 dev->power.status = DPM_OFF; 492 + mutex_unlock(&dpm_list_mtx); 493 + 494 error = device_resume_noirq(dev, state); 495 + 496 + mutex_lock(&dpm_list_mtx); 497 if (error) 498 pm_dev_err(dev, state, " early", error); 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); 505 mutex_unlock(&dpm_list_mtx); 506 dpm_show_time(starttime, state, "early"); 507 resume_device_irqs(); ··· 789 */ 790 int dpm_suspend_noirq(pm_message_t state) 791 { 792 + struct list_head list; 793 ktime_t starttime = ktime_get(); 794 int error = 0; 795 796 + INIT_LIST_HEAD(&list); 797 suspend_device_irqs(); 798 mutex_lock(&dpm_list_mtx); 799 + while (!list_empty(&dpm_list)) { 800 + struct device *dev = to_device(dpm_list.prev); 801 + 802 + get_device(dev); 803 + mutex_unlock(&dpm_list_mtx); 804 + 805 error = device_suspend_noirq(dev, state); 806 + 807 + mutex_lock(&dpm_list_mtx); 808 if (error) { 809 pm_dev_err(dev, state, " late", error); 810 + put_device(dev); 811 break; 812 } 813 dev->power.status = DPM_OFF_IRQ; 814 + if (!list_empty(&dev->power.entry)) 815 + list_move(&dev->power.entry, &list); 816 + put_device(dev); 817 } 818 + list_splice_tail(&list, &dpm_list); 819 mutex_unlock(&dpm_list_mtx); 820 if (error) 821 dpm_resume_noirq(resume_event(state));
+2 -2
kernel/pm_qos_params.c
··· 121 122 switch (o->type) { 123 case PM_QOS_MIN: 124 - return plist_last(&o->requests)->prio; 125 126 case PM_QOS_MAX: 127 - return plist_first(&o->requests)->prio; 128 129 default: 130 /* runtime check for not using enum */
··· 121 122 switch (o->type) { 123 case PM_QOS_MIN: 124 + return plist_first(&o->requests)->prio; 125 126 case PM_QOS_MAX: 127 + return plist_last(&o->requests)->prio; 128 129 default: 130 /* runtime check for not using enum */
+4
kernel/power/Kconfig
··· 246 depends on PM_SLEEP || PM_RUNTIME 247 default y 248 249 config PM_OPP 250 bool "Operating Performance Point (OPP) Layer library" 251 depends on PM 252 ---help--- 253 SOCs have a standard set of tuples consisting of frequency and 254 voltage pairs that the device will support per voltage domain. This
··· 246 depends on PM_SLEEP || PM_RUNTIME 247 default y 248 249 + config ARCH_HAS_OPP 250 + bool 251 + 252 config PM_OPP 253 bool "Operating Performance Point (OPP) Layer library" 254 depends on PM 255 + depends on ARCH_HAS_OPP 256 ---help--- 257 SOCs have a standard set of tuples consisting of frequency and 258 voltage pairs that the device will support per voltage domain. This