Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'pm-extra-4.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull more power management updates from Rafael Wysocki:
"These add new CPU IDs to a couple of drivers, fix a possible NULL
pointer dereference in the cpuidle core, update DT-related things in
the generic power domains framework and finally update the
suspend/resume infrastructure to improve the handling of wakeups from
suspend-to-idle.

Specifics:

- Add Intel Gemini Lake CPU IDs to the intel_idle and intel_rapl
drivers (David Box).

- Add a NULL pointer check to the cpuidle core to prevent it from
crashing on platforms with incomplete cpuidle configuration (Fei
Li).

- Fix DT-related documentation in the generic power domains (genpd)
framework and add a MAINTAINERS entry for DT-related material in
genpd (Viresh Kumar).

- Update the system suspend/resume infrastructure to improve the
handling of aborts of suspend transitions in progress in the wakeup
framework and rework the suspend-to-idle core loop to make it
possible to filter out spurious wakeup events (specifically the
ones coming from ACPI) without resuming all the way up to user
space every time (Rafael Wysocki)"

* tag 'pm-extra-4.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
ACPI / sleep: Ignore spurious SCI wakeups from suspend-to-idle
PM / wakeup: Integrate mechanism to abort transitions in progress
x86/intel_idle: add Gemini Lake support
cpuidle: check dev before usage in cpuidle_use_deepest_state()
powercap: intel_rapl: Add support for Gemini Lake
PM / Domains: Add DT file to MAINTAINERS
PM / Domains: Fix DT example

+123 -46
+1 -1
Documentation/devicetree/bindings/power/power_domain.txt
··· 81 81 child: power-controller@12341000 { 82 82 compatible = "foo,power-controller"; 83 83 reg = <0x12341000 0x1000>; 84 - power-domains = <&parent 0>; 84 + power-domains = <&parent>; 85 85 #power-domain-cells = <0>; 86 86 domain-idle-states = <&DOMAIN_PWR_DN>; 87 87 };
+1
MAINTAINERS
··· 5590 5590 S: Supported 5591 5591 F: drivers/base/power/domain*.c 5592 5592 F: include/linux/pm_domain.h 5593 + F: Documentation/devicetree/bindings/power/power_domain.txt 5593 5594 5594 5595 GENERIC UIO DRIVER FOR PCI DEVICES 5595 5596 M: "Michael S. Tsirkin" <mst@redhat.com>
+1 -1
drivers/acpi/battery.c
··· 782 782 if ((battery->state & ACPI_BATTERY_STATE_CRITICAL) || 783 783 (test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags) && 784 784 (battery->capacity_now <= battery->alarm))) 785 - pm_wakeup_event(&battery->device->dev, 0); 785 + pm_wakeup_hard_event(&battery->device->dev); 786 786 787 787 return result; 788 788 }
+3 -2
drivers/acpi/button.c
··· 216 216 } 217 217 218 218 if (state) 219 - pm_wakeup_event(&device->dev, 0); 219 + pm_wakeup_hard_event(&device->dev); 220 220 221 221 ret = blocking_notifier_call_chain(&acpi_lid_notifier, state, device); 222 222 if (ret == NOTIFY_DONE) ··· 398 398 } else { 399 399 int keycode; 400 400 401 - pm_wakeup_event(&device->dev, 0); 401 + pm_wakeup_hard_event(&device->dev); 402 402 if (button->suspended) 403 403 break; 404 404 ··· 530 530 lid_device = device; 531 531 } 532 532 533 + device_init_wakeup(&device->dev, true); 533 534 printk(KERN_INFO PREFIX "%s [%s]\n", name, acpi_device_bid(device)); 534 535 return 0; 535 536
+2 -1
drivers/acpi/device_pm.c
··· 24 24 #include <linux/pm_qos.h> 25 25 #include <linux/pm_domain.h> 26 26 #include <linux/pm_runtime.h> 27 + #include <linux/suspend.h> 27 28 28 29 #include "internal.h" 29 30 ··· 400 399 mutex_lock(&acpi_pm_notifier_lock); 401 400 402 401 if (adev->wakeup.flags.notifier_present) { 403 - __pm_wakeup_event(adev->wakeup.ws, 0); 402 + pm_wakeup_ws_event(adev->wakeup.ws, 0, true); 404 403 if (adev->wakeup.context.work.func) 405 404 queue_pm_work(&adev->wakeup.context.work); 406 405 }
+28
drivers/acpi/sleep.c
··· 662 662 acpi_os_wait_events_complete(); 663 663 if (acpi_sci_irq_valid()) 664 664 enable_irq_wake(acpi_sci_irq); 665 + 665 666 return 0; 667 + } 668 + 669 + static void acpi_freeze_wake(void) 670 + { 671 + /* 672 + * If IRQD_WAKEUP_ARMED is not set for the SCI at this point, it means 673 + * that the SCI has triggered while suspended, so cancel the wakeup in 674 + * case it has not been a wakeup event (the GPEs will be checked later). 675 + */ 676 + if (acpi_sci_irq_valid() && 677 + !irqd_is_wakeup_armed(irq_get_irq_data(acpi_sci_irq))) 678 + pm_system_cancel_wakeup(); 679 + } 680 + 681 + static void acpi_freeze_sync(void) 682 + { 683 + /* 684 + * Process all pending events in case there are any wakeup ones. 685 + * 686 + * The EC driver uses the system workqueue, so that one needs to be 687 + * flushed too. 688 + */ 689 + acpi_os_wait_events_complete(); 690 + flush_scheduled_work(); 666 691 } 667 692 668 693 static void acpi_freeze_restore(void) ··· 695 670 acpi_disable_wakeup_devices(ACPI_STATE_S0); 696 671 if (acpi_sci_irq_valid()) 697 672 disable_irq_wake(acpi_sci_irq); 673 + 698 674 acpi_enable_all_runtime_gpes(); 699 675 } 700 676 ··· 707 681 static const struct platform_freeze_ops acpi_freeze_ops = { 708 682 .begin = acpi_freeze_begin, 709 683 .prepare = acpi_freeze_prepare, 684 + .wake = acpi_freeze_wake, 685 + .sync = acpi_freeze_sync, 710 686 .restore = acpi_freeze_restore, 711 687 .end = acpi_freeze_end, 712 688 };
-5
drivers/base/power/main.c
··· 1091 1091 if (async_error) 1092 1092 goto Complete; 1093 1093 1094 - if (pm_wakeup_pending()) { 1095 - async_error = -EBUSY; 1096 - goto Complete; 1097 - } 1098 - 1099 1094 if (dev->power.syscore || dev->power.direct_complete) 1100 1095 goto Complete; 1101 1096
+30 -24
drivers/base/power/wakeup.c
··· 28 28 /* First wakeup IRQ seen by the kernel in the last cycle. */ 29 29 unsigned int pm_wakeup_irq __read_mostly; 30 30 31 - /* If set and the system is suspending, terminate the suspend. */ 32 - static bool pm_abort_suspend __read_mostly; 31 + /* If greater than 0 and the system is suspending, terminate the suspend. */ 32 + static atomic_t pm_abort_suspend __read_mostly; 33 33 34 34 /* 35 35 * Combined counters of registered wakeup events and wakeup events in progress. ··· 512 512 /** 513 513 * wakup_source_activate - Mark given wakeup source as active. 514 514 * @ws: Wakeup source to handle. 515 + * @hard: If set, abort suspends in progress and wake up from suspend-to-idle. 515 516 * 516 517 * Update the @ws' statistics and, if @ws has just been activated, notify the PM 517 518 * core of the event by incrementing the counter of of wakeup events being 518 519 * processed. 519 520 */ 520 - static void wakeup_source_activate(struct wakeup_source *ws) 521 + static void wakeup_source_activate(struct wakeup_source *ws, bool hard) 521 522 { 522 523 unsigned int cec; 523 524 ··· 526 525 "unregistered wakeup source\n")) 527 526 return; 528 527 529 - /* 530 - * active wakeup source should bring the system 531 - * out of PM_SUSPEND_FREEZE state 532 - */ 533 - freeze_wake(); 528 + if (hard) 529 + pm_system_wakeup(); 534 530 535 531 ws->active = true; 536 532 ws->active_count++; ··· 544 546 /** 545 547 * wakeup_source_report_event - Report wakeup event using the given source. 546 548 * @ws: Wakeup source to report the event for. 549 + * @hard: If set, abort suspends in progress and wake up from suspend-to-idle. 547 550 */ 548 - static void wakeup_source_report_event(struct wakeup_source *ws) 551 + static void wakeup_source_report_event(struct wakeup_source *ws, bool hard) 549 552 { 550 553 ws->event_count++; 551 554 /* This is racy, but the counter is approximate anyway. */ ··· 554 555 ws->wakeup_count++; 555 556 556 557 if (!ws->active) 557 - wakeup_source_activate(ws); 558 + wakeup_source_activate(ws, hard); 558 559 } 559 560 560 561 /** ··· 572 573 573 574 spin_lock_irqsave(&ws->lock, flags); 574 575 575 - wakeup_source_report_event(ws); 576 + wakeup_source_report_event(ws, false); 576 577 del_timer(&ws->timer); 577 578 ws->timer_expires = 0; 578 579 ··· 738 739 } 739 740 740 741 /** 741 - * __pm_wakeup_event - Notify the PM core of a wakeup event. 742 + * pm_wakeup_ws_event - Notify the PM core of a wakeup event. 742 743 * @ws: Wakeup source object associated with the event source. 743 744 * @msec: Anticipated event processing time (in milliseconds). 745 + * @hard: If set, abort suspends in progress and wake up from suspend-to-idle. 744 746 * 745 747 * Notify the PM core of a wakeup event whose source is @ws that will take 746 748 * approximately @msec milliseconds to be processed by the kernel. If @ws is ··· 750 750 * 751 751 * It is safe to call this function from interrupt context. 752 752 */ 753 - void __pm_wakeup_event(struct wakeup_source *ws, unsigned int msec) 753 + void pm_wakeup_ws_event(struct wakeup_source *ws, unsigned int msec, bool hard) 754 754 { 755 755 unsigned long flags; 756 756 unsigned long expires; ··· 760 760 761 761 spin_lock_irqsave(&ws->lock, flags); 762 762 763 - wakeup_source_report_event(ws); 763 + wakeup_source_report_event(ws, hard); 764 764 765 765 if (!msec) { 766 766 wakeup_source_deactivate(ws); ··· 779 779 unlock: 780 780 spin_unlock_irqrestore(&ws->lock, flags); 781 781 } 782 - EXPORT_SYMBOL_GPL(__pm_wakeup_event); 783 - 782 + EXPORT_SYMBOL_GPL(pm_wakeup_ws_event); 784 783 785 784 /** 786 785 * pm_wakeup_event - Notify the PM core of a wakeup event. 787 786 * @dev: Device the wakeup event is related to. 788 787 * @msec: Anticipated event processing time (in milliseconds). 788 + * @hard: If set, abort suspends in progress and wake up from suspend-to-idle. 789 789 * 790 - * Call __pm_wakeup_event() for the @dev's wakeup source object. 790 + * Call pm_wakeup_ws_event() for the @dev's wakeup source object. 791 791 */ 792 - void pm_wakeup_event(struct device *dev, unsigned int msec) 792 + void pm_wakeup_dev_event(struct device *dev, unsigned int msec, bool hard) 793 793 { 794 794 unsigned long flags; 795 795 ··· 797 797 return; 798 798 799 799 spin_lock_irqsave(&dev->power.lock, flags); 800 - __pm_wakeup_event(dev->power.wakeup, msec); 800 + pm_wakeup_ws_event(dev->power.wakeup, msec, hard); 801 801 spin_unlock_irqrestore(&dev->power.lock, flags); 802 802 } 803 - EXPORT_SYMBOL_GPL(pm_wakeup_event); 803 + EXPORT_SYMBOL_GPL(pm_wakeup_dev_event); 804 804 805 805 void pm_print_active_wakeup_sources(void) 806 806 { ··· 856 856 pm_print_active_wakeup_sources(); 857 857 } 858 858 859 - return ret || pm_abort_suspend; 859 + return ret || atomic_read(&pm_abort_suspend) > 0; 860 860 } 861 861 862 862 void pm_system_wakeup(void) 863 863 { 864 - pm_abort_suspend = true; 864 + atomic_inc(&pm_abort_suspend); 865 865 freeze_wake(); 866 866 } 867 867 EXPORT_SYMBOL_GPL(pm_system_wakeup); 868 868 869 - void pm_wakeup_clear(void) 869 + void pm_system_cancel_wakeup(void) 870 870 { 871 - pm_abort_suspend = false; 871 + atomic_dec(&pm_abort_suspend); 872 + } 873 + 874 + void pm_wakeup_clear(bool reset) 875 + { 872 876 pm_wakeup_irq = 0; 877 + if (reset) 878 + atomic_set(&pm_abort_suspend, 0); 873 879 } 874 880 875 881 void pm_system_irq_wakeup(unsigned int irq_number)
+2 -1
drivers/cpuidle/cpuidle.c
··· 111 111 112 112 preempt_disable(); 113 113 dev = cpuidle_get_device(); 114 - dev->use_deepest_state = enable; 114 + if (dev) 115 + dev->use_deepest_state = enable; 115 116 preempt_enable(); 116 117 } 117 118
+2
drivers/idle/intel_idle.c
··· 1097 1097 ICPU(INTEL_FAM6_XEON_PHI_KNL, idle_cpu_knl), 1098 1098 ICPU(INTEL_FAM6_XEON_PHI_KNM, idle_cpu_knl), 1099 1099 ICPU(INTEL_FAM6_ATOM_GOLDMONT, idle_cpu_bxt), 1100 + ICPU(INTEL_FAM6_ATOM_GEMINI_LAKE, idle_cpu_bxt), 1100 1101 ICPU(INTEL_FAM6_ATOM_DENVERTON, idle_cpu_dnv), 1101 1102 {} 1102 1103 }; ··· 1310 1309 ivt_idle_state_table_update(); 1311 1310 break; 1312 1311 case INTEL_FAM6_ATOM_GOLDMONT: 1312 + case INTEL_FAM6_ATOM_GEMINI_LAKE: 1313 1313 bxt_idle_state_table_update(); 1314 1314 break; 1315 1315 case INTEL_FAM6_SKYLAKE_DESKTOP:
+1
drivers/powercap/intel_rapl.c
··· 1164 1164 RAPL_CPU(INTEL_FAM6_ATOM_MERRIFIELD, rapl_defaults_tng), 1165 1165 RAPL_CPU(INTEL_FAM6_ATOM_MOOREFIELD, rapl_defaults_ann), 1166 1166 RAPL_CPU(INTEL_FAM6_ATOM_GOLDMONT, rapl_defaults_core), 1167 + RAPL_CPU(INTEL_FAM6_ATOM_GEMINI_LAKE, rapl_defaults_core), 1167 1168 RAPL_CPU(INTEL_FAM6_ATOM_DENVERTON, rapl_defaults_core), 1168 1169 1169 1170 RAPL_CPU(INTEL_FAM6_XEON_PHI_KNL, rapl_defaults_hsw_server),
+21 -4
include/linux/pm_wakeup.h
··· 106 106 extern void pm_stay_awake(struct device *dev); 107 107 extern void __pm_relax(struct wakeup_source *ws); 108 108 extern void pm_relax(struct device *dev); 109 - extern void __pm_wakeup_event(struct wakeup_source *ws, unsigned int msec); 110 - extern void pm_wakeup_event(struct device *dev, unsigned int msec); 109 + extern void pm_wakeup_ws_event(struct wakeup_source *ws, unsigned int msec, bool hard); 110 + extern void pm_wakeup_dev_event(struct device *dev, unsigned int msec, bool hard); 111 111 112 112 #else /* !CONFIG_PM_SLEEP */ 113 113 ··· 182 182 183 183 static inline void pm_relax(struct device *dev) {} 184 184 185 - static inline void __pm_wakeup_event(struct wakeup_source *ws, unsigned int msec) {} 185 + static inline void pm_wakeup_ws_event(struct wakeup_source *ws, 186 + unsigned int msec, bool hard) {} 186 187 187 - static inline void pm_wakeup_event(struct device *dev, unsigned int msec) {} 188 + static inline void pm_wakeup_dev_event(struct device *dev, unsigned int msec, 189 + bool hard) {} 188 190 189 191 #endif /* !CONFIG_PM_SLEEP */ 190 192 ··· 201 199 { 202 200 wakeup_source_remove(ws); 203 201 wakeup_source_drop(ws); 202 + } 203 + 204 + static inline void __pm_wakeup_event(struct wakeup_source *ws, unsigned int msec) 205 + { 206 + return pm_wakeup_ws_event(ws, msec, false); 207 + } 208 + 209 + static inline void pm_wakeup_event(struct device *dev, unsigned int msec) 210 + { 211 + return pm_wakeup_dev_event(dev, msec, false); 212 + } 213 + 214 + static inline void pm_wakeup_hard_event(struct device *dev) 215 + { 216 + return pm_wakeup_dev_event(dev, 0, true); 204 217 } 205 218 206 219 #endif /* _LINUX_PM_WAKEUP_H */
+5 -2
include/linux/suspend.h
··· 189 189 struct platform_freeze_ops { 190 190 int (*begin)(void); 191 191 int (*prepare)(void); 192 + void (*wake)(void); 193 + void (*sync)(void); 192 194 void (*restore)(void); 193 195 void (*end)(void); 194 196 }; ··· 430 428 431 429 extern bool pm_wakeup_pending(void); 432 430 extern void pm_system_wakeup(void); 433 - extern void pm_wakeup_clear(void); 431 + extern void pm_system_cancel_wakeup(void); 432 + extern void pm_wakeup_clear(bool reset); 434 433 extern void pm_system_irq_wakeup(unsigned int irq_number); 435 434 extern bool pm_get_wakeup_count(unsigned int *count, bool block); 436 435 extern bool pm_save_wakeup_count(unsigned int count); ··· 481 478 482 479 static inline bool pm_wakeup_pending(void) { return false; } 483 480 static inline void pm_system_wakeup(void) {} 484 - static inline void pm_wakeup_clear(void) {} 481 + static inline void pm_wakeup_clear(bool reset) {} 485 482 static inline void pm_system_irq_wakeup(unsigned int irq_number) {} 486 483 487 484 static inline void lock_system_sleep(void) {}
+1 -1
kernel/power/process.c
··· 132 132 if (!pm_freezing) 133 133 atomic_inc(&system_freezing_cnt); 134 134 135 - pm_wakeup_clear(); 135 + pm_wakeup_clear(true); 136 136 pr_info("Freezing user space processes ... "); 137 137 pm_freezing = true; 138 138 error = try_to_freeze_tasks(true);
+25 -4
kernel/power/suspend.c
··· 72 72 73 73 static void freeze_enter(void) 74 74 { 75 + trace_suspend_resume(TPS("machine_suspend"), PM_SUSPEND_FREEZE, true); 76 + 75 77 spin_lock_irq(&suspend_freeze_lock); 76 78 if (pm_wakeup_pending()) 77 79 goto out; ··· 100 98 out: 101 99 suspend_freeze_state = FREEZE_STATE_NONE; 102 100 spin_unlock_irq(&suspend_freeze_lock); 101 + 102 + trace_suspend_resume(TPS("machine_suspend"), PM_SUSPEND_FREEZE, false); 103 + } 104 + 105 + static void s2idle_loop(void) 106 + { 107 + do { 108 + freeze_enter(); 109 + 110 + if (freeze_ops && freeze_ops->wake) 111 + freeze_ops->wake(); 112 + 113 + dpm_resume_noirq(PMSG_RESUME); 114 + if (freeze_ops && freeze_ops->sync) 115 + freeze_ops->sync(); 116 + 117 + if (pm_wakeup_pending()) 118 + break; 119 + 120 + pm_wakeup_clear(false); 121 + } while (!dpm_suspend_noirq(PMSG_SUSPEND)); 103 122 } 104 123 105 124 void freeze_wake(void) ··· 394 371 * all the devices are suspended. 395 372 */ 396 373 if (state == PM_SUSPEND_FREEZE) { 397 - trace_suspend_resume(TPS("machine_suspend"), state, true); 398 - freeze_enter(); 399 - trace_suspend_resume(TPS("machine_suspend"), state, false); 400 - goto Platform_wake; 374 + s2idle_loop(); 375 + goto Platform_early_resume; 401 376 } 402 377 403 378 error = disable_nonboot_cpus();