]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
Merge branches 'acpi-pm' and 'pm-sleep'
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>
Thu, 18 Jan 2018 01:55:28 +0000 (02:55 +0100)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Thu, 18 Jan 2018 01:55:28 +0000 (02:55 +0100)
* 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()

Documentation/admin-guide/kernel-parameters.txt
arch/x86/kernel/acpi/sleep.c
drivers/acpi/sleep.c
drivers/platform/x86/surfacepro3_button.c
drivers/scsi/scsi_transport_spi.c
include/linux/acpi.h
include/linux/suspend.h
kernel/power/main.c
kernel/power/snapshot.c
kernel/power/swap.c

index 46b26bfee27ba81267703a1ceac7c0e082f1e5ec..281c85839c1781037542236305940a21c3f113b4 100644 (file)
 
        acpi_sleep=     [HW,ACPI] Sleep options
                        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
                        s3_bios and s3_mode.
                        s3_beep is for debugging; it makes the PC's speaker beep
                        sci_force_enable causes the kernel to set SCI_EN directly
                        on resume from S1/S3 (which is against the ACPI spec,
                        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]
                        Use timer override. For some broken Nvidia NF5 boards
index 7188aea91549bb31450d049b689fda1032b21f5f..f1915b7440522a82642a0b3369df1a570d8c834a 100644 (file)
@@ -138,6 +138,8 @@ static int __init acpi_sleep_setup(char *str)
                        acpi_nvs_nosave_s3();
                if (strncmp(str, "old_ordering", 12) == 0)
                        acpi_old_suspend_ordering();
+               if (strncmp(str, "nobl", 4) == 0)
+                       acpi_sleep_no_blacklist();
                str = strchr(str, ',');
                if (str != NULL)
                        str += strspn(str, ", \t");
index 8082871b409a6d631a80b5d2327e9fcb6a1509d4..46cde0912762e5d8d68aaa5611a7eebb9d4caedd 100644 (file)
@@ -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)
 {
        int year;
 
+       if (ignore_blacklist)
+               return;
+
        if (dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL) && year >= 2012)
                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_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 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) {
                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_device_handle = adev->handle;
                        /*
index 6505c97705e1486391088baa8728aafd3540403a..1b491690ce07018bffbeaef42a3aee788102e3ac 100644 (file)
@@ -119,7 +119,7 @@ static void surface_button_notify(struct acpi_device *device, u32 event)
        if (key_code == KEY_RESERVED)
                return;
        if (pressed)
-               pm_wakeup_event(&device->dev, 0);
+               pm_wakeup_dev_event(&device->dev, 0, button->suspended);
        if (button->suspended)
                return;
        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);
        if (error)
                goto err_free_input;
+
+       device_init_wakeup(&device->dev, true);
        dev_info(&device->dev,
                        "%s [%s]\n", name, acpi_device_bid(device));
        return 0;
index 10ebb213ddb33e2920e2fe83e60cc712a50c3002..871ea582029ea7a6b0e1a5c5b1f6ed55a812e020 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/mutex.h>
 #include <linux/sysfs.h>
 #include <linux/slab.h>
+#include <linux/suspend.h>
 #include <scsi/scsi.h>
 #include "scsi_priv.h"
 #include <scsi/scsi_device.h>
@@ -1009,11 +1010,20 @@ spi_dv_device(struct scsi_device *sdev)
        u8 *buffer;
        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)))
-               return;
+               goto unlock;
 
        if (unlikely(scsi_device_get(sdev)))
-               return;
+               goto unlock;
+
        spi_dv_in_progress(starget) = 1;
 
        buffer = kzalloc(len, GFP_KERNEL);
@@ -1049,6 +1059,8 @@ spi_dv_device(struct scsi_device *sdev)
  out_put:
        spi_dv_in_progress(starget) = 0;
        scsi_device_put(sdev);
+unlock:
+       unlock_system_sleep();
 }
 EXPORT_SYMBOL(spi_dv_device);
 
index dc1ebfeeb5ecc10e248f57084f80c72d32c6c14a..699655a9618be0c22a8f6728ee2c131be6b22c46 100644 (file)
@@ -451,6 +451,7 @@ void __init acpi_no_s4_hw_signature(void);
 void __init acpi_old_suspend_ordering(void);
 void __init acpi_nvs_nosave(void);
 void __init acpi_nvs_nosave_s3(void);
+void __init acpi_sleep_no_blacklist(void);
 #endif /* CONFIG_PM_SLEEP */
 
 struct acpi_osc_context {
index d60b0f5c38d504e52a2c1c2726476def808595c7..cc22a24516d699582a639329a99df51eb5bb2fb4 100644 (file)
@@ -443,32 +443,8 @@ extern bool pm_save_wakeup_count(unsigned int count);
 extern void pm_wakep_autosleep_enabled(bool set);
 extern void pm_print_active_wakeup_sources(void);
 
-static inline void lock_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);
-}
+extern void lock_system_sleep(void);
+extern void unlock_system_sleep(void);
 
 #else /* !CONFIG_PM_SLEEP */
 
index 3a2ca9066583fad36e3b91fe99515058d453a62e..705c2366dafe19c13f011885df1e2ae93c2687e7 100644 (file)
@@ -22,6 +22,35 @@ DEFINE_MUTEX(pm_mutex);
 
 #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 */
 
 static BLOCKING_NOTIFIER_HEAD(pm_chain_head);
index bce0464524d868ac47733035ba7d84e96927cbdb..3d37c279c09008b74c41a71abb850bfcdaa99e99 100644 (file)
@@ -1645,8 +1645,7 @@ static unsigned long free_unnecessary_pages(void)
  * [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
- * and (3) inactive anonymous pages, (4) active and (5) inactive file pages,
- * minus mapped file pages.
+ * and (3) inactive anonymous pages, (4) active and (5) inactive file pages.
  */
 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_INACTIVE_ANON)
                + global_node_page_state(NR_ACTIVE_FILE)
-               + global_node_page_state(NR_INACTIVE_FILE)
-               - global_node_page_state(NR_FILE_MAPPED);
+               + global_node_page_state(NR_INACTIVE_FILE);
 
        return saveable <= size ? 0 : saveable - size;
 }
index 293ead59ecccbab5c3013be15d5f4cbfbef2315f..a46be1261c095e74fa49f363b917ae7996a29cbd 100644 (file)
@@ -879,7 +879,7 @@ static int save_image_lzo(struct swap_map_handle *handle,
  *     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 required;
@@ -915,7 +915,7 @@ int swsusp_write(unsigned int flags)
                return error;
        }
        if (flags & SF_NOCOMPRESS_MODE) {
-               if (!enough_swap(pages, flags)) {
+               if (!enough_swap(pages)) {
                        pr_err("Not enough free swap\n");
                        error = -ENOSPC;
                        goto out_finish;