Power management fixes for v4.12-rc5
- Revert a recent commit that attempted to avoid spurious wakeups from suspend-to-idle via ACPI SCI, but introduced regressions on some systems (Rafael Wysocki). We will get back to the problem it tried to address in the next cycle. - Fix a possible division by 0 during intel_pstate initialization due to a missing check (Rafael Wysocki). -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAABCAAGBQJZOeX+AAoJEILEb/54YlRxYksQAIczTx5toDqcmMbyXUbS/KBp /kQK5iwGo9WV5V4ZsWugmwrTY9R4xwBdeBow/nacO5NGVtjYix95wTlGlw84RLIi 2QO4SzN0ZKqh8DUxvjro/exIe+YPqX4Bodvo9CX4hr60xjutcZRVz5Dq6ZS80KPw o0/fWUlQzT1BM9IorfJ0YT2XEdMpdVbPWrwTpm8l2G42vWXSQwsd6fFnOLpTrd46 580JAH5Dux6YNMsSejTazQon/3P0sChYxbJkpm6nvv819EMbFDy8p+ebIgceBlos l6Zlckd7ETwDwL3G3OGi5/Zcpb/YMg5Slm3+IGM/J5ccVIfdG8gjqTJklrxH7I4S /+0MzwlXUbRYEvurB6nsP3kIofrZN+t+c609ewmIFLy2QIDJF9BiVhKnRrjNfsuU KrY0zFATtxGy/0CfkZCmSWZBid06tAQ0ZZ1dYkO/1Qf5dn1ge+Yr8tcc0WKqJqbq NR+BfsCVa84b6s+uBsMdKR6kAg0tz7uG5njXlH7bupH3ZCtttbbWp0znmd/ow/jU usJyEHStvzhjC4T9s0tRzEi96B2/MlsGYmL+qq9GBScdhYKc6K/4xzdUkp+yGQwD 311sheKvQZ06kwj0v+hK1aBOH2y3pjcBMvKjCdr/IiMtX8/kD0tsKx1+0QESR91D H80L6EjjEAUm1KEsQcpy =oWdX -----END PGP SIGNATURE----- Merge tag 'pm-4.12-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm Pull power management fixes from Rafael Wysocki: "These revert one problematic commit related to system sleep and fix one recent intel_pstate regression. Specifics: - Revert a recent commit that attempted to avoid spurious wakeups from suspend-to-idle via ACPI SCI, but introduced regressions on some systems (Rafael Wysocki). We will get back to the problem it tried to address in the next cycle. - Fix a possible division by 0 during intel_pstate initialization due to a missing check (Rafael Wysocki)" * tag 'pm-4.12-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: Revert "ACPI / sleep: Ignore spurious SCI wakeups from suspend-to-idle" cpufreq: intel_pstate: Avoid division by 0 in min_perf_pct_min()
This commit is contained in:
commit
0d22df90c7
|
@ -782,7 +782,7 @@ static int acpi_battery_update(struct acpi_battery *battery, bool resume)
|
|||
if ((battery->state & ACPI_BATTERY_STATE_CRITICAL) ||
|
||||
(test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags) &&
|
||||
(battery->capacity_now <= battery->alarm)))
|
||||
pm_wakeup_hard_event(&battery->device->dev);
|
||||
pm_wakeup_event(&battery->device->dev, 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -217,7 +217,7 @@ static int acpi_lid_notify_state(struct acpi_device *device, int state)
|
|||
}
|
||||
|
||||
if (state)
|
||||
pm_wakeup_hard_event(&device->dev);
|
||||
pm_wakeup_event(&device->dev, 0);
|
||||
|
||||
ret = blocking_notifier_call_chain(&acpi_lid_notifier, state, device);
|
||||
if (ret == NOTIFY_DONE)
|
||||
|
@ -402,7 +402,7 @@ static void acpi_button_notify(struct acpi_device *device, u32 event)
|
|||
} else {
|
||||
int keycode;
|
||||
|
||||
pm_wakeup_hard_event(&device->dev);
|
||||
pm_wakeup_event(&device->dev, 0);
|
||||
if (button->suspended)
|
||||
break;
|
||||
|
||||
|
@ -534,7 +534,6 @@ static int acpi_button_add(struct acpi_device *device)
|
|||
lid_device = device;
|
||||
}
|
||||
|
||||
device_init_wakeup(&device->dev, true);
|
||||
printk(KERN_INFO PREFIX "%s [%s]\n", name, acpi_device_bid(device));
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
#include <linux/pm_qos.h>
|
||||
#include <linux/pm_domain.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/suspend.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
|
@ -400,7 +399,7 @@ static void acpi_pm_notify_handler(acpi_handle handle, u32 val, void *not_used)
|
|||
mutex_lock(&acpi_pm_notifier_lock);
|
||||
|
||||
if (adev->wakeup.flags.notifier_present) {
|
||||
pm_wakeup_ws_event(adev->wakeup.ws, 0, true);
|
||||
__pm_wakeup_event(adev->wakeup.ws, 0);
|
||||
if (adev->wakeup.context.work.func)
|
||||
queue_pm_work(&adev->wakeup.context.work);
|
||||
}
|
||||
|
|
|
@ -663,40 +663,14 @@ static int acpi_freeze_prepare(void)
|
|||
acpi_os_wait_events_complete();
|
||||
if (acpi_sci_irq_valid())
|
||||
enable_irq_wake(acpi_sci_irq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void acpi_freeze_wake(void)
|
||||
{
|
||||
/*
|
||||
* If IRQD_WAKEUP_ARMED is not set for the SCI at this point, it means
|
||||
* that the SCI has triggered while suspended, so cancel the wakeup in
|
||||
* case it has not been a wakeup event (the GPEs will be checked later).
|
||||
*/
|
||||
if (acpi_sci_irq_valid() &&
|
||||
!irqd_is_wakeup_armed(irq_get_irq_data(acpi_sci_irq)))
|
||||
pm_system_cancel_wakeup();
|
||||
}
|
||||
|
||||
static void acpi_freeze_sync(void)
|
||||
{
|
||||
/*
|
||||
* Process all pending events in case there are any wakeup ones.
|
||||
*
|
||||
* The EC driver uses the system workqueue, so that one needs to be
|
||||
* flushed too.
|
||||
*/
|
||||
acpi_os_wait_events_complete();
|
||||
flush_scheduled_work();
|
||||
}
|
||||
|
||||
static void acpi_freeze_restore(void)
|
||||
{
|
||||
acpi_disable_wakeup_devices(ACPI_STATE_S0);
|
||||
if (acpi_sci_irq_valid())
|
||||
disable_irq_wake(acpi_sci_irq);
|
||||
|
||||
acpi_enable_all_runtime_gpes();
|
||||
}
|
||||
|
||||
|
@ -708,8 +682,6 @@ static void acpi_freeze_end(void)
|
|||
static const struct platform_freeze_ops acpi_freeze_ops = {
|
||||
.begin = acpi_freeze_begin,
|
||||
.prepare = acpi_freeze_prepare,
|
||||
.wake = acpi_freeze_wake,
|
||||
.sync = acpi_freeze_sync,
|
||||
.restore = acpi_freeze_restore,
|
||||
.end = acpi_freeze_end,
|
||||
};
|
||||
|
|
|
@ -1091,6 +1091,11 @@ static int __device_suspend_noirq(struct device *dev, pm_message_t state, bool a
|
|||
if (async_error)
|
||||
goto Complete;
|
||||
|
||||
if (pm_wakeup_pending()) {
|
||||
async_error = -EBUSY;
|
||||
goto Complete;
|
||||
}
|
||||
|
||||
if (dev->power.syscore || dev->power.direct_complete)
|
||||
goto Complete;
|
||||
|
||||
|
|
|
@ -28,8 +28,8 @@ bool events_check_enabled __read_mostly;
|
|||
/* First wakeup IRQ seen by the kernel in the last cycle. */
|
||||
unsigned int pm_wakeup_irq __read_mostly;
|
||||
|
||||
/* If greater than 0 and the system is suspending, terminate the suspend. */
|
||||
static atomic_t pm_abort_suspend __read_mostly;
|
||||
/* If set and the system is suspending, terminate the suspend. */
|
||||
static bool pm_abort_suspend __read_mostly;
|
||||
|
||||
/*
|
||||
* Combined counters of registered wakeup events and wakeup events in progress.
|
||||
|
@ -855,26 +855,20 @@ bool pm_wakeup_pending(void)
|
|||
pm_print_active_wakeup_sources();
|
||||
}
|
||||
|
||||
return ret || atomic_read(&pm_abort_suspend) > 0;
|
||||
return ret || pm_abort_suspend;
|
||||
}
|
||||
|
||||
void pm_system_wakeup(void)
|
||||
{
|
||||
atomic_inc(&pm_abort_suspend);
|
||||
pm_abort_suspend = true;
|
||||
freeze_wake();
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pm_system_wakeup);
|
||||
|
||||
void pm_system_cancel_wakeup(void)
|
||||
{
|
||||
atomic_dec(&pm_abort_suspend);
|
||||
}
|
||||
|
||||
void pm_wakeup_clear(bool reset)
|
||||
void pm_wakeup_clear(void)
|
||||
{
|
||||
pm_abort_suspend = false;
|
||||
pm_wakeup_irq = 0;
|
||||
if (reset)
|
||||
atomic_set(&pm_abort_suspend, 0);
|
||||
}
|
||||
|
||||
void pm_system_irq_wakeup(unsigned int irq_number)
|
||||
|
|
|
@ -571,9 +571,10 @@ static inline void update_turbo_state(void)
|
|||
static int min_perf_pct_min(void)
|
||||
{
|
||||
struct cpudata *cpu = all_cpu_data[0];
|
||||
int turbo_pstate = cpu->pstate.turbo_pstate;
|
||||
|
||||
return DIV_ROUND_UP(cpu->pstate.min_pstate * 100,
|
||||
cpu->pstate.turbo_pstate);
|
||||
return turbo_pstate ?
|
||||
DIV_ROUND_UP(cpu->pstate.min_pstate * 100, turbo_pstate) : 0;
|
||||
}
|
||||
|
||||
static s16 intel_pstate_get_epb(struct cpudata *cpu_data)
|
||||
|
|
|
@ -189,8 +189,6 @@ struct platform_suspend_ops {
|
|||
struct platform_freeze_ops {
|
||||
int (*begin)(void);
|
||||
int (*prepare)(void);
|
||||
void (*wake)(void);
|
||||
void (*sync)(void);
|
||||
void (*restore)(void);
|
||||
void (*end)(void);
|
||||
};
|
||||
|
@ -430,8 +428,7 @@ extern unsigned int pm_wakeup_irq;
|
|||
|
||||
extern bool pm_wakeup_pending(void);
|
||||
extern void pm_system_wakeup(void);
|
||||
extern void pm_system_cancel_wakeup(void);
|
||||
extern void pm_wakeup_clear(bool reset);
|
||||
extern void pm_wakeup_clear(void);
|
||||
extern void pm_system_irq_wakeup(unsigned int irq_number);
|
||||
extern bool pm_get_wakeup_count(unsigned int *count, bool block);
|
||||
extern bool pm_save_wakeup_count(unsigned int count);
|
||||
|
@ -481,7 +478,7 @@ static inline int unregister_pm_notifier(struct notifier_block *nb)
|
|||
|
||||
static inline bool pm_wakeup_pending(void) { return false; }
|
||||
static inline void pm_system_wakeup(void) {}
|
||||
static inline void pm_wakeup_clear(bool reset) {}
|
||||
static inline void pm_wakeup_clear(void) {}
|
||||
static inline void pm_system_irq_wakeup(unsigned int irq_number) {}
|
||||
|
||||
static inline void lock_system_sleep(void) {}
|
||||
|
|
|
@ -132,7 +132,7 @@ int freeze_processes(void)
|
|||
if (!pm_freezing)
|
||||
atomic_inc(&system_freezing_cnt);
|
||||
|
||||
pm_wakeup_clear(true);
|
||||
pm_wakeup_clear();
|
||||
pr_info("Freezing user space processes ... ");
|
||||
pm_freezing = true;
|
||||
error = try_to_freeze_tasks(true);
|
||||
|
|
|
@ -72,8 +72,6 @@ static void freeze_begin(void)
|
|||
|
||||
static void freeze_enter(void)
|
||||
{
|
||||
trace_suspend_resume(TPS("machine_suspend"), PM_SUSPEND_FREEZE, true);
|
||||
|
||||
spin_lock_irq(&suspend_freeze_lock);
|
||||
if (pm_wakeup_pending())
|
||||
goto out;
|
||||
|
@ -100,27 +98,6 @@ static void freeze_enter(void)
|
|||
out:
|
||||
suspend_freeze_state = FREEZE_STATE_NONE;
|
||||
spin_unlock_irq(&suspend_freeze_lock);
|
||||
|
||||
trace_suspend_resume(TPS("machine_suspend"), PM_SUSPEND_FREEZE, false);
|
||||
}
|
||||
|
||||
static void s2idle_loop(void)
|
||||
{
|
||||
do {
|
||||
freeze_enter();
|
||||
|
||||
if (freeze_ops && freeze_ops->wake)
|
||||
freeze_ops->wake();
|
||||
|
||||
dpm_resume_noirq(PMSG_RESUME);
|
||||
if (freeze_ops && freeze_ops->sync)
|
||||
freeze_ops->sync();
|
||||
|
||||
if (pm_wakeup_pending())
|
||||
break;
|
||||
|
||||
pm_wakeup_clear(false);
|
||||
} while (!dpm_suspend_noirq(PMSG_SUSPEND));
|
||||
}
|
||||
|
||||
void freeze_wake(void)
|
||||
|
@ -394,8 +371,10 @@ static int suspend_enter(suspend_state_t state, bool *wakeup)
|
|||
* all the devices are suspended.
|
||||
*/
|
||||
if (state == PM_SUSPEND_FREEZE) {
|
||||
s2idle_loop();
|
||||
goto Platform_early_resume;
|
||||
trace_suspend_resume(TPS("machine_suspend"), state, true);
|
||||
freeze_enter();
|
||||
trace_suspend_resume(TPS("machine_suspend"), state, false);
|
||||
goto Platform_wake;
|
||||
}
|
||||
|
||||
error = disable_nonboot_cpus();
|
||||
|
|
Loading…
Reference in New Issue