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