Merge branches 'acpi-pm' and 'pm-sleep'
* acpi-pm: platform/x86: surfacepro3: Support for wakeup from suspend-to-idle ACPI / PM: Use Low Power S0 Idle on more systems ACPI / PM: Make it possible to ignore the system sleep blacklist * pm-sleep: PM / hibernate: Drop unused parameter of enough_swap block, scsi: Fix race between SPI domain validation and system suspend PM / sleep: Make lock/unlock_system_sleep() available to kernel modules PM: hibernate: Do not subtract NR_FILE_MAPPED in minimum_image_size()
This commit is contained in:
commit
bcaea4678f
@ -223,7 +223,7 @@
|
|||||||
|
|
||||||
acpi_sleep= [HW,ACPI] Sleep options
|
acpi_sleep= [HW,ACPI] Sleep options
|
||||||
Format: { s3_bios, s3_mode, s3_beep, s4_nohwsig,
|
Format: { s3_bios, s3_mode, s3_beep, s4_nohwsig,
|
||||||
old_ordering, nonvs, sci_force_enable }
|
old_ordering, nonvs, sci_force_enable, nobl }
|
||||||
See Documentation/power/video.txt for information on
|
See Documentation/power/video.txt for information on
|
||||||
s3_bios and s3_mode.
|
s3_bios and s3_mode.
|
||||||
s3_beep is for debugging; it makes the PC's speaker beep
|
s3_beep is for debugging; it makes the PC's speaker beep
|
||||||
@ -239,6 +239,9 @@
|
|||||||
sci_force_enable causes the kernel to set SCI_EN directly
|
sci_force_enable causes the kernel to set SCI_EN directly
|
||||||
on resume from S1/S3 (which is against the ACPI spec,
|
on resume from S1/S3 (which is against the ACPI spec,
|
||||||
but some broken systems don't work without it).
|
but some broken systems don't work without it).
|
||||||
|
nobl causes the internal blacklist of systems known to
|
||||||
|
behave incorrectly in some ways with respect to system
|
||||||
|
suspend and resume to be ignored (use wisely).
|
||||||
|
|
||||||
acpi_use_timer_override [HW,ACPI]
|
acpi_use_timer_override [HW,ACPI]
|
||||||
Use timer override. For some broken Nvidia NF5 boards
|
Use timer override. For some broken Nvidia NF5 boards
|
||||||
|
@ -138,6 +138,8 @@ static int __init acpi_sleep_setup(char *str)
|
|||||||
acpi_nvs_nosave_s3();
|
acpi_nvs_nosave_s3();
|
||||||
if (strncmp(str, "old_ordering", 12) == 0)
|
if (strncmp(str, "old_ordering", 12) == 0)
|
||||||
acpi_old_suspend_ordering();
|
acpi_old_suspend_ordering();
|
||||||
|
if (strncmp(str, "nobl", 4) == 0)
|
||||||
|
acpi_sleep_no_blacklist();
|
||||||
str = strchr(str, ',');
|
str = strchr(str, ',');
|
||||||
if (str != NULL)
|
if (str != NULL)
|
||||||
str += strspn(str, ", \t");
|
str += strspn(str, ", \t");
|
||||||
|
@ -367,10 +367,20 @@ static const struct dmi_system_id acpisleep_dmi_table[] __initconst = {
|
|||||||
{},
|
{},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static bool ignore_blacklist;
|
||||||
|
|
||||||
|
void __init acpi_sleep_no_blacklist(void)
|
||||||
|
{
|
||||||
|
ignore_blacklist = true;
|
||||||
|
}
|
||||||
|
|
||||||
static void __init acpi_sleep_dmi_check(void)
|
static void __init acpi_sleep_dmi_check(void)
|
||||||
{
|
{
|
||||||
int year;
|
int year;
|
||||||
|
|
||||||
|
if (ignore_blacklist)
|
||||||
|
return;
|
||||||
|
|
||||||
if (dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL) && year >= 2012)
|
if (dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL) && year >= 2012)
|
||||||
acpi_nvs_nosave_s3();
|
acpi_nvs_nosave_s3();
|
||||||
|
|
||||||
@ -697,7 +707,8 @@ static const struct acpi_device_id lps0_device_ids[] = {
|
|||||||
#define ACPI_LPS0_ENTRY 5
|
#define ACPI_LPS0_ENTRY 5
|
||||||
#define ACPI_LPS0_EXIT 6
|
#define ACPI_LPS0_EXIT 6
|
||||||
|
|
||||||
#define ACPI_S2IDLE_FUNC_MASK ((1 << ACPI_LPS0_ENTRY) | (1 << ACPI_LPS0_EXIT))
|
#define ACPI_LPS0_SCREEN_MASK ((1 << ACPI_LPS0_SCREEN_OFF) | (1 << ACPI_LPS0_SCREEN_ON))
|
||||||
|
#define ACPI_LPS0_PLATFORM_MASK ((1 << ACPI_LPS0_ENTRY) | (1 << ACPI_LPS0_EXIT))
|
||||||
|
|
||||||
static acpi_handle lps0_device_handle;
|
static acpi_handle lps0_device_handle;
|
||||||
static guid_t lps0_dsm_guid;
|
static guid_t lps0_dsm_guid;
|
||||||
@ -900,7 +911,8 @@ static int lps0_device_attach(struct acpi_device *adev,
|
|||||||
if (out_obj && out_obj->type == ACPI_TYPE_BUFFER) {
|
if (out_obj && out_obj->type == ACPI_TYPE_BUFFER) {
|
||||||
char bitmask = *(char *)out_obj->buffer.pointer;
|
char bitmask = *(char *)out_obj->buffer.pointer;
|
||||||
|
|
||||||
if ((bitmask & ACPI_S2IDLE_FUNC_MASK) == ACPI_S2IDLE_FUNC_MASK) {
|
if ((bitmask & ACPI_LPS0_PLATFORM_MASK) == ACPI_LPS0_PLATFORM_MASK ||
|
||||||
|
(bitmask & ACPI_LPS0_SCREEN_MASK) == ACPI_LPS0_SCREEN_MASK) {
|
||||||
lps0_dsm_func_mask = bitmask;
|
lps0_dsm_func_mask = bitmask;
|
||||||
lps0_device_handle = adev->handle;
|
lps0_device_handle = adev->handle;
|
||||||
/*
|
/*
|
||||||
|
@ -119,7 +119,7 @@ static void surface_button_notify(struct acpi_device *device, u32 event)
|
|||||||
if (key_code == KEY_RESERVED)
|
if (key_code == KEY_RESERVED)
|
||||||
return;
|
return;
|
||||||
if (pressed)
|
if (pressed)
|
||||||
pm_wakeup_event(&device->dev, 0);
|
pm_wakeup_dev_event(&device->dev, 0, button->suspended);
|
||||||
if (button->suspended)
|
if (button->suspended)
|
||||||
return;
|
return;
|
||||||
input_report_key(input, key_code, pressed?1:0);
|
input_report_key(input, key_code, pressed?1:0);
|
||||||
@ -185,6 +185,8 @@ static int surface_button_add(struct acpi_device *device)
|
|||||||
error = input_register_device(input);
|
error = input_register_device(input);
|
||||||
if (error)
|
if (error)
|
||||||
goto err_free_input;
|
goto err_free_input;
|
||||||
|
|
||||||
|
device_init_wakeup(&device->dev, true);
|
||||||
dev_info(&device->dev,
|
dev_info(&device->dev,
|
||||||
"%s [%s]\n", name, acpi_device_bid(device));
|
"%s [%s]\n", name, acpi_device_bid(device));
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include <linux/mutex.h>
|
#include <linux/mutex.h>
|
||||||
#include <linux/sysfs.h>
|
#include <linux/sysfs.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
|
#include <linux/suspend.h>
|
||||||
#include <scsi/scsi.h>
|
#include <scsi/scsi.h>
|
||||||
#include "scsi_priv.h"
|
#include "scsi_priv.h"
|
||||||
#include <scsi/scsi_device.h>
|
#include <scsi/scsi_device.h>
|
||||||
@ -1009,11 +1010,20 @@ spi_dv_device(struct scsi_device *sdev)
|
|||||||
u8 *buffer;
|
u8 *buffer;
|
||||||
const int len = SPI_MAX_ECHO_BUFFER_SIZE*2;
|
const int len = SPI_MAX_ECHO_BUFFER_SIZE*2;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Because this function and the power management code both call
|
||||||
|
* scsi_device_quiesce(), it is not safe to perform domain validation
|
||||||
|
* while suspend or resume is in progress. Hence the
|
||||||
|
* lock/unlock_system_sleep() calls.
|
||||||
|
*/
|
||||||
|
lock_system_sleep();
|
||||||
|
|
||||||
if (unlikely(spi_dv_in_progress(starget)))
|
if (unlikely(spi_dv_in_progress(starget)))
|
||||||
return;
|
goto unlock;
|
||||||
|
|
||||||
if (unlikely(scsi_device_get(sdev)))
|
if (unlikely(scsi_device_get(sdev)))
|
||||||
return;
|
goto unlock;
|
||||||
|
|
||||||
spi_dv_in_progress(starget) = 1;
|
spi_dv_in_progress(starget) = 1;
|
||||||
|
|
||||||
buffer = kzalloc(len, GFP_KERNEL);
|
buffer = kzalloc(len, GFP_KERNEL);
|
||||||
@ -1049,6 +1059,8 @@ spi_dv_device(struct scsi_device *sdev)
|
|||||||
out_put:
|
out_put:
|
||||||
spi_dv_in_progress(starget) = 0;
|
spi_dv_in_progress(starget) = 0;
|
||||||
scsi_device_put(sdev);
|
scsi_device_put(sdev);
|
||||||
|
unlock:
|
||||||
|
unlock_system_sleep();
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(spi_dv_device);
|
EXPORT_SYMBOL(spi_dv_device);
|
||||||
|
|
||||||
|
@ -451,6 +451,7 @@ void __init acpi_no_s4_hw_signature(void);
|
|||||||
void __init acpi_old_suspend_ordering(void);
|
void __init acpi_old_suspend_ordering(void);
|
||||||
void __init acpi_nvs_nosave(void);
|
void __init acpi_nvs_nosave(void);
|
||||||
void __init acpi_nvs_nosave_s3(void);
|
void __init acpi_nvs_nosave_s3(void);
|
||||||
|
void __init acpi_sleep_no_blacklist(void);
|
||||||
#endif /* CONFIG_PM_SLEEP */
|
#endif /* CONFIG_PM_SLEEP */
|
||||||
|
|
||||||
struct acpi_osc_context {
|
struct acpi_osc_context {
|
||||||
|
@ -443,32 +443,8 @@ extern bool pm_save_wakeup_count(unsigned int count);
|
|||||||
extern void pm_wakep_autosleep_enabled(bool set);
|
extern void pm_wakep_autosleep_enabled(bool set);
|
||||||
extern void pm_print_active_wakeup_sources(void);
|
extern void pm_print_active_wakeup_sources(void);
|
||||||
|
|
||||||
static inline void lock_system_sleep(void)
|
extern void lock_system_sleep(void);
|
||||||
{
|
extern void unlock_system_sleep(void);
|
||||||
current->flags |= PF_FREEZER_SKIP;
|
|
||||||
mutex_lock(&pm_mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void unlock_system_sleep(void)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Don't use freezer_count() because we don't want the call to
|
|
||||||
* try_to_freeze() here.
|
|
||||||
*
|
|
||||||
* Reason:
|
|
||||||
* Fundamentally, we just don't need it, because freezing condition
|
|
||||||
* doesn't come into effect until we release the pm_mutex lock,
|
|
||||||
* since the freezer always works with pm_mutex held.
|
|
||||||
*
|
|
||||||
* More importantly, in the case of hibernation,
|
|
||||||
* unlock_system_sleep() gets called in snapshot_read() and
|
|
||||||
* snapshot_write() when the freezing condition is still in effect.
|
|
||||||
* Which means, if we use try_to_freeze() here, it would make them
|
|
||||||
* enter the refrigerator, thus causing hibernation to lockup.
|
|
||||||
*/
|
|
||||||
current->flags &= ~PF_FREEZER_SKIP;
|
|
||||||
mutex_unlock(&pm_mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
#else /* !CONFIG_PM_SLEEP */
|
#else /* !CONFIG_PM_SLEEP */
|
||||||
|
|
||||||
|
@ -22,6 +22,35 @@ DEFINE_MUTEX(pm_mutex);
|
|||||||
|
|
||||||
#ifdef CONFIG_PM_SLEEP
|
#ifdef CONFIG_PM_SLEEP
|
||||||
|
|
||||||
|
void lock_system_sleep(void)
|
||||||
|
{
|
||||||
|
current->flags |= PF_FREEZER_SKIP;
|
||||||
|
mutex_lock(&pm_mutex);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(lock_system_sleep);
|
||||||
|
|
||||||
|
void unlock_system_sleep(void)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Don't use freezer_count() because we don't want the call to
|
||||||
|
* try_to_freeze() here.
|
||||||
|
*
|
||||||
|
* Reason:
|
||||||
|
* Fundamentally, we just don't need it, because freezing condition
|
||||||
|
* doesn't come into effect until we release the pm_mutex lock,
|
||||||
|
* since the freezer always works with pm_mutex held.
|
||||||
|
*
|
||||||
|
* More importantly, in the case of hibernation,
|
||||||
|
* unlock_system_sleep() gets called in snapshot_read() and
|
||||||
|
* snapshot_write() when the freezing condition is still in effect.
|
||||||
|
* Which means, if we use try_to_freeze() here, it would make them
|
||||||
|
* enter the refrigerator, thus causing hibernation to lockup.
|
||||||
|
*/
|
||||||
|
current->flags &= ~PF_FREEZER_SKIP;
|
||||||
|
mutex_unlock(&pm_mutex);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(unlock_system_sleep);
|
||||||
|
|
||||||
/* Routines for PM-transition notifications */
|
/* Routines for PM-transition notifications */
|
||||||
|
|
||||||
static BLOCKING_NOTIFIER_HEAD(pm_chain_head);
|
static BLOCKING_NOTIFIER_HEAD(pm_chain_head);
|
||||||
|
@ -1645,8 +1645,7 @@ static unsigned long free_unnecessary_pages(void)
|
|||||||
* [number of saveable pages] - [number of pages that can be freed in theory]
|
* [number of saveable pages] - [number of pages that can be freed in theory]
|
||||||
*
|
*
|
||||||
* where the second term is the sum of (1) reclaimable slab pages, (2) active
|
* where the second term is the sum of (1) reclaimable slab pages, (2) active
|
||||||
* and (3) inactive anonymous pages, (4) active and (5) inactive file pages,
|
* and (3) inactive anonymous pages, (4) active and (5) inactive file pages.
|
||||||
* minus mapped file pages.
|
|
||||||
*/
|
*/
|
||||||
static unsigned long minimum_image_size(unsigned long saveable)
|
static unsigned long minimum_image_size(unsigned long saveable)
|
||||||
{
|
{
|
||||||
@ -1656,8 +1655,7 @@ static unsigned long minimum_image_size(unsigned long saveable)
|
|||||||
+ global_node_page_state(NR_ACTIVE_ANON)
|
+ global_node_page_state(NR_ACTIVE_ANON)
|
||||||
+ global_node_page_state(NR_INACTIVE_ANON)
|
+ global_node_page_state(NR_INACTIVE_ANON)
|
||||||
+ global_node_page_state(NR_ACTIVE_FILE)
|
+ global_node_page_state(NR_ACTIVE_FILE)
|
||||||
+ global_node_page_state(NR_INACTIVE_FILE)
|
+ global_node_page_state(NR_INACTIVE_FILE);
|
||||||
- global_node_page_state(NR_FILE_MAPPED);
|
|
||||||
|
|
||||||
return saveable <= size ? 0 : saveable - size;
|
return saveable <= size ? 0 : saveable - size;
|
||||||
}
|
}
|
||||||
|
@ -879,7 +879,7 @@ out_clean:
|
|||||||
* space avaiable from the resume partition.
|
* space avaiable from the resume partition.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int enough_swap(unsigned int nr_pages, unsigned int flags)
|
static int enough_swap(unsigned int nr_pages)
|
||||||
{
|
{
|
||||||
unsigned int free_swap = count_swap_pages(root_swap, 1);
|
unsigned int free_swap = count_swap_pages(root_swap, 1);
|
||||||
unsigned int required;
|
unsigned int required;
|
||||||
@ -915,7 +915,7 @@ int swsusp_write(unsigned int flags)
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
if (flags & SF_NOCOMPRESS_MODE) {
|
if (flags & SF_NOCOMPRESS_MODE) {
|
||||||
if (!enough_swap(pages, flags)) {
|
if (!enough_swap(pages)) {
|
||||||
pr_err("Not enough free swap\n");
|
pr_err("Not enough free swap\n");
|
||||||
error = -ENOSPC;
|
error = -ENOSPC;
|
||||||
goto out_finish;
|
goto out_finish;
|
||||||
|
Loading…
Reference in New Issue
Block a user