PM / sleep: System sleep state selection interface rework
[linux-2.6-microblaze.git] / kernel / power / suspend.c
index 1e7f5da..15e6bae 100644 (file)
 
 #include "power.h"
 
-const char *pm_labels[] = { "mem", "standby", "freeze", NULL };
+const char * const pm_labels[] = {
+       [PM_SUSPEND_FREEZE] = "freeze",
+       [PM_SUSPEND_STANDBY] = "standby",
+       [PM_SUSPEND_MEM] = "mem",
+};
 const char *pm_states[PM_SUSPEND_MAX];
+static const char * const mem_sleep_labels[] = {
+       [PM_SUSPEND_FREEZE] = "s2idle",
+       [PM_SUSPEND_STANDBY] = "shallow",
+       [PM_SUSPEND_MEM] = "deep",
+};
+const char *mem_sleep_states[PM_SUSPEND_MAX];
+
+suspend_state_t mem_sleep_current = PM_SUSPEND_FREEZE;
+static suspend_state_t mem_sleep_default = PM_SUSPEND_MEM;
 
 unsigned int pm_suspend_global_flags;
 EXPORT_SYMBOL_GPL(pm_suspend_global_flags);
@@ -110,30 +123,32 @@ static bool valid_state(suspend_state_t state)
        return suspend_ops && suspend_ops->valid && suspend_ops->valid(state);
 }
 
-/*
- * If this is set, the "mem" label always corresponds to the deepest sleep state
- * available, the "standby" label corresponds to the second deepest sleep state
- * available (if any), and the "freeze" label corresponds to the remaining
- * available sleep state (if there is one).
- */
-static bool relative_states;
-
 void __init pm_states_init(void)
 {
+       /* "mem" and "freeze" are always present in /sys/power/state. */
+       pm_states[PM_SUSPEND_MEM] = pm_labels[PM_SUSPEND_MEM];
+       pm_states[PM_SUSPEND_FREEZE] = pm_labels[PM_SUSPEND_FREEZE];
        /*
-        * freeze state should be supported even without any suspend_ops,
-        * initialize pm_states accordingly here
+        * Suspend-to-idle should be supported even without any suspend_ops,
+        * initialize mem_sleep_states[] accordingly here.
         */
-       pm_states[PM_SUSPEND_FREEZE] = pm_labels[relative_states ? 0 : 2];
+       mem_sleep_states[PM_SUSPEND_FREEZE] = mem_sleep_labels[PM_SUSPEND_FREEZE];
 }
 
-static int __init sleep_states_setup(char *str)
+static int __init mem_sleep_default_setup(char *str)
 {
-       relative_states = !strncmp(str, "1", 1);
+       suspend_state_t state;
+
+       for (state = PM_SUSPEND_FREEZE; state <= PM_SUSPEND_MEM; state++)
+               if (mem_sleep_labels[state] &&
+                   !strcmp(str, mem_sleep_labels[state])) {
+                       mem_sleep_default = state;
+                       break;
+               }
+
        return 1;
 }
-
-__setup("relative_sleep_states=", sleep_states_setup);
+__setup("mem_sleep_default=", mem_sleep_default_setup);
 
 /**
  * suspend_set_ops - Set the global suspend method table.
@@ -141,21 +156,21 @@ __setup("relative_sleep_states=", sleep_states_setup);
  */
 void suspend_set_ops(const struct platform_suspend_ops *ops)
 {
-       suspend_state_t i;
-       int j = 0;
-
        lock_system_sleep();
 
        suspend_ops = ops;
-       for (i = PM_SUSPEND_MEM; i >= PM_SUSPEND_STANDBY; i--)
-               if (valid_state(i)) {
-                       pm_states[i] = pm_labels[j++];
-               } else if (!relative_states) {
-                       pm_states[i] = NULL;
-                       j++;
-               }
 
-       pm_states[PM_SUSPEND_FREEZE] = pm_labels[j];
+       if (valid_state(PM_SUSPEND_STANDBY)) {
+               mem_sleep_states[PM_SUSPEND_STANDBY] = mem_sleep_labels[PM_SUSPEND_STANDBY];
+               pm_states[PM_SUSPEND_STANDBY] = pm_labels[PM_SUSPEND_STANDBY];
+               if (mem_sleep_default == PM_SUSPEND_STANDBY)
+                       mem_sleep_current = PM_SUSPEND_STANDBY;
+       }
+       if (valid_state(PM_SUSPEND_MEM)) {
+               mem_sleep_states[PM_SUSPEND_MEM] = mem_sleep_labels[PM_SUSPEND_MEM];
+               if (mem_sleep_default == PM_SUSPEND_MEM)
+                       mem_sleep_current = PM_SUSPEND_MEM;
+       }
 
        unlock_system_sleep();
 }
@@ -498,9 +513,9 @@ static int enter_state(suspend_state_t state)
 
 #ifndef CONFIG_SUSPEND_SKIP_SYNC
        trace_suspend_resume(TPS("sync_filesystems"), 0, true);
-       printk(KERN_INFO "PM: Syncing filesystems ... ");
+       pr_info("PM: Syncing filesystems ... ");
        sys_sync();
-       printk("done.\n");
+       pr_cont("done.\n");
        trace_suspend_resume(TPS("sync_filesystems"), 0, false);
 #endif