Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
hibernate.c
Go to the documentation of this file.
1 /*
2  * kernel/power/hibernate.c - Hibernation (a.k.a suspend-to-disk) support.
3  *
4  * Copyright (c) 2003 Patrick Mochel
5  * Copyright (c) 2003 Open Source Development Lab
6  * Copyright (c) 2004 Pavel Machek <[email protected]>
7  * Copyright (c) 2009 Rafael J. Wysocki, Novell Inc.
8  * Copyright (C) 2012 Bojan Smojver <[email protected]>
9  *
10  * This file is released under the GPLv2.
11  */
12 
13 #include <linux/export.h>
14 #include <linux/suspend.h>
15 #include <linux/syscalls.h>
16 #include <linux/reboot.h>
17 #include <linux/string.h>
18 #include <linux/device.h>
19 #include <linux/async.h>
20 #include <linux/delay.h>
21 #include <linux/fs.h>
22 #include <linux/mount.h>
23 #include <linux/pm.h>
24 #include <linux/console.h>
25 #include <linux/cpu.h>
26 #include <linux/freezer.h>
27 #include <linux/gfp.h>
28 #include <linux/syscore_ops.h>
29 #include <linux/ctype.h>
30 #include <linux/genhd.h>
31 
32 #include "power.h"
33 
34 
35 static int nocompress;
36 static int noresume;
37 static int resume_wait;
38 static int resume_delay;
39 static char resume_file[256] = CONFIG_PM_STD_PARTITION;
43 
44 enum {
49 #ifdef CONFIG_SUSPEND
50  HIBERNATION_SUSPEND,
51 #endif
52  /* keep last */
54 };
55 #define HIBERNATION_MAX (__HIBERNATION_AFTER_LAST-1)
56 #define HIBERNATION_FIRST (HIBERNATION_INVALID + 1)
57 
58 static int hibernation_mode = HIBERNATION_SHUTDOWN;
59 
61 
62 static const struct platform_hibernation_ops *hibernation_ops;
63 
69 {
70  if (ops && !(ops->begin && ops->end && ops->pre_snapshot
71  && ops->prepare && ops->finish && ops->enter && ops->pre_restore
72  && ops->restore_cleanup && ops->leave)) {
73  WARN_ON(1);
74  return;
75  }
76  lock_system_sleep();
77  hibernation_ops = ops;
78  if (ops)
79  hibernation_mode = HIBERNATION_PLATFORM;
80  else if (hibernation_mode == HIBERNATION_PLATFORM)
81  hibernation_mode = HIBERNATION_SHUTDOWN;
82 
83  unlock_system_sleep();
84 }
85 
86 static bool entering_platform_hibernation;
87 
89 {
90  return entering_platform_hibernation;
91 }
93 
94 #ifdef CONFIG_PM_DEBUG
95 static void hibernation_debug_sleep(void)
96 {
97  printk(KERN_INFO "hibernation debug: Waiting for 5 seconds.\n");
98  mdelay(5000);
99 }
100 
101 static int hibernation_test(int level)
102 {
103  if (pm_test_level == level) {
104  hibernation_debug_sleep();
105  return 1;
106  }
107  return 0;
108 }
109 #else /* !CONFIG_PM_DEBUG */
110 static int hibernation_test(int level) { return 0; }
111 #endif /* !CONFIG_PM_DEBUG */
112 
117 static int platform_begin(int platform_mode)
118 {
119  return (platform_mode && hibernation_ops) ?
120  hibernation_ops->begin() : 0;
121 }
122 
127 static void platform_end(int platform_mode)
128 {
129  if (platform_mode && hibernation_ops)
130  hibernation_ops->end();
131 }
132 
141 static int platform_pre_snapshot(int platform_mode)
142 {
143  return (platform_mode && hibernation_ops) ?
144  hibernation_ops->pre_snapshot() : 0;
145 }
146 
156 static void platform_leave(int platform_mode)
157 {
158  if (platform_mode && hibernation_ops)
159  hibernation_ops->leave();
160 }
161 
171 static void platform_finish(int platform_mode)
172 {
173  if (platform_mode && hibernation_ops)
174  hibernation_ops->finish();
175 }
176 
187 static int platform_pre_restore(int platform_mode)
188 {
189  return (platform_mode && hibernation_ops) ?
190  hibernation_ops->pre_restore() : 0;
191 }
192 
204 static void platform_restore_cleanup(int platform_mode)
205 {
206  if (platform_mode && hibernation_ops)
207  hibernation_ops->restore_cleanup();
208 }
209 
214 static void platform_recover(int platform_mode)
215 {
216  if (platform_mode && hibernation_ops && hibernation_ops->recover)
217  hibernation_ops->recover();
218 }
219 
228  unsigned nr_pages, char *msg)
229 {
230  s64 elapsed_centisecs64;
231  int centisecs;
232  int k;
233  int kps;
234 
235  elapsed_centisecs64 = timeval_to_ns(stop) - timeval_to_ns(start);
236  do_div(elapsed_centisecs64, NSEC_PER_SEC / 100);
237  centisecs = elapsed_centisecs64;
238  if (centisecs == 0)
239  centisecs = 1; /* avoid div-by-zero */
240  k = nr_pages * (PAGE_SIZE / 1024);
241  kps = (k * 100) / centisecs;
242  printk(KERN_INFO "PM: %s %d kbytes in %d.%02d seconds (%d.%02d MB/s)\n",
243  msg, k,
244  centisecs / 100, centisecs % 100,
245  kps / 1000, (kps % 1000) / 10);
246 }
247 
257 static int create_image(int platform_mode)
258 {
259  int error;
260 
261  error = dpm_suspend_end(PMSG_FREEZE);
262  if (error) {
263  printk(KERN_ERR "PM: Some devices failed to power down, "
264  "aborting hibernation\n");
265  return error;
266  }
267 
268  error = platform_pre_snapshot(platform_mode);
269  if (error || hibernation_test(TEST_PLATFORM))
270  goto Platform_finish;
271 
272  error = disable_nonboot_cpus();
273  if (error || hibernation_test(TEST_CPUS))
274  goto Enable_cpus;
275 
277 
278  error = syscore_suspend();
279  if (error) {
280  printk(KERN_ERR "PM: Some system devices failed to power down, "
281  "aborting hibernation\n");
282  goto Enable_irqs;
283  }
284 
285  if (hibernation_test(TEST_CORE) || pm_wakeup_pending())
286  goto Power_up;
287 
288  in_suspend = 1;
290  error = swsusp_arch_suspend();
291  if (error)
292  printk(KERN_ERR "PM: Error %d creating hibernation image\n",
293  error);
294  /* Restore control flow magically appears here */
296  if (!in_suspend) {
297  events_check_enabled = false;
298  platform_leave(platform_mode);
299  }
300 
301  Power_up:
302  syscore_resume();
303 
304  Enable_irqs:
306 
307  Enable_cpus:
308  enable_nonboot_cpus();
309 
310  Platform_finish:
311  platform_finish(platform_mode);
312 
313  dpm_resume_start(in_suspend ?
314  (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE);
315 
316  return error;
317 }
318 
325 int hibernation_snapshot(int platform_mode)
326 {
328  int error;
329 
330  error = platform_begin(platform_mode);
331  if (error)
332  goto Close;
333 
334  /* Preallocate image memory before shutting down devices. */
336  if (error)
337  goto Close;
338 
339  error = freeze_kernel_threads();
340  if (error)
341  goto Cleanup;
342 
343  if (hibernation_test(TEST_FREEZER)) {
344 
345  /*
346  * Indicate to the caller that we are returning due to a
347  * successful freezer test.
348  */
349  freezer_test_done = true;
350  goto Thaw;
351  }
352 
353  error = dpm_prepare(PMSG_FREEZE);
354  if (error) {
356  goto Thaw;
357  }
358 
359  suspend_console();
360  ftrace_stop();
362 
363  error = dpm_suspend(PMSG_FREEZE);
364 
365  if (error || hibernation_test(TEST_DEVICES))
366  platform_recover(platform_mode);
367  else
368  error = create_image(platform_mode);
369 
370  /*
371  * In the case that we call create_image() above, the control
372  * returns here (1) after the image has been created or the
373  * image creation has failed and (2) after a successful restore.
374  */
375 
376  /* We may need to release the preallocated image pages here. */
377  if (error || !in_suspend)
378  swsusp_free();
379 
380  msg = in_suspend ? (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE;
381  dpm_resume(msg);
382 
383  if (error || !in_suspend)
385 
386  ftrace_start();
387  resume_console();
388  dpm_complete(msg);
389 
390  Close:
391  platform_end(platform_mode);
392  return error;
393 
394  Thaw:
396  Cleanup:
397  swsusp_free();
398  goto Close;
399 }
400 
410 static int resume_target_kernel(bool platform_mode)
411 {
412  int error;
413 
414  error = dpm_suspend_end(PMSG_QUIESCE);
415  if (error) {
416  printk(KERN_ERR "PM: Some devices failed to power down, "
417  "aborting resume\n");
418  return error;
419  }
420 
421  error = platform_pre_restore(platform_mode);
422  if (error)
423  goto Cleanup;
424 
425  error = disable_nonboot_cpus();
426  if (error)
427  goto Enable_cpus;
428 
430 
431  error = syscore_suspend();
432  if (error)
433  goto Enable_irqs;
434 
436  error = restore_highmem();
437  if (!error) {
438  error = swsusp_arch_resume();
439  /*
440  * The code below is only ever reached in case of a failure.
441  * Otherwise, execution continues at the place where
442  * swsusp_arch_suspend() was called.
443  */
444  BUG_ON(!error);
445  /*
446  * This call to restore_highmem() reverts the changes made by
447  * the previous one.
448  */
449  restore_highmem();
450  }
451  /*
452  * The only reason why swsusp_arch_resume() can fail is memory being
453  * very tight, so we have to free it as soon as we can to avoid
454  * subsequent failures.
455  */
456  swsusp_free();
459 
460  syscore_resume();
461 
462  Enable_irqs:
464 
465  Enable_cpus:
466  enable_nonboot_cpus();
467 
468  Cleanup:
469  platform_restore_cleanup(platform_mode);
470 
472 
473  return error;
474 }
475 
483 int hibernation_restore(int platform_mode)
484 {
485  int error;
486 
488  suspend_console();
489  ftrace_stop();
492  if (!error) {
493  error = resume_target_kernel(platform_mode);
495  }
497  ftrace_start();
498  resume_console();
500  return error;
501 }
502 
507 {
508  int error;
509 
510  if (!hibernation_ops)
511  return -ENOSYS;
512 
513  /*
514  * We have cancelled the power transition by running
515  * hibernation_ops->finish() before saving the image, so we should let
516  * the firmware know that we're going to enter the sleep state after all
517  */
518  error = hibernation_ops->begin();
519  if (error)
520  goto Close;
521 
522  entering_platform_hibernation = true;
523  suspend_console();
524  ftrace_stop();
526  if (error) {
527  if (hibernation_ops->recover)
528  hibernation_ops->recover();
529  goto Resume_devices;
530  }
531 
533  if (error)
534  goto Resume_devices;
535 
536  error = hibernation_ops->prepare();
537  if (error)
538  goto Platform_finish;
539 
540  error = disable_nonboot_cpus();
541  if (error)
542  goto Platform_finish;
543 
545  syscore_suspend();
546  if (pm_wakeup_pending()) {
547  error = -EAGAIN;
548  goto Power_up;
549  }
550 
551  hibernation_ops->enter();
552  /* We should never get here */
553  while (1);
554 
555  Power_up:
556  syscore_resume();
558  enable_nonboot_cpus();
559 
560  Platform_finish:
561  hibernation_ops->finish();
562 
564 
565  Resume_devices:
566  entering_platform_hibernation = false;
568  ftrace_start();
569  resume_console();
570 
571  Close:
572  hibernation_ops->end();
573 
574  return error;
575 }
576 
584 static void power_down(void)
585 {
586 #ifdef CONFIG_SUSPEND
587  int error;
588 #endif
589 
590  switch (hibernation_mode) {
591  case HIBERNATION_REBOOT:
593  break;
598  break;
599 #ifdef CONFIG_SUSPEND
600  case HIBERNATION_SUSPEND:
602  if (error) {
603  if (hibernation_ops)
604  hibernation_mode = HIBERNATION_PLATFORM;
605  else
606  hibernation_mode = HIBERNATION_SHUTDOWN;
607  power_down();
608  }
609  /*
610  * Restore swap signature.
611  */
612  error = swsusp_unmark();
613  if (error)
614  printk(KERN_ERR "PM: Swap will be unusable! "
615  "Try swapon -a.\n");
616  return;
617 #endif
618  }
619  kernel_halt();
620  /*
621  * Valid image is on the disk, if we continue we risk serious data
622  * corruption after resume.
623  */
624  printk(KERN_CRIT "PM: Please power down manually\n");
625  while(1);
626 }
627 
631 int hibernate(void)
632 {
633  int error;
634 
635  lock_system_sleep();
636  /* The snapshot device should not be opened while we're running */
637  if (!atomic_add_unless(&snapshot_device_available, -1, 0)) {
638  error = -EBUSY;
639  goto Unlock;
640  }
641 
643  error = pm_notifier_call_chain(PM_HIBERNATION_PREPARE);
644  if (error)
645  goto Exit;
646 
647  /* Allocate memory management structures */
648  error = create_basic_memory_bitmaps();
649  if (error)
650  goto Exit;
651 
652  printk(KERN_INFO "PM: Syncing filesystems ... ");
653  sys_sync();
654  printk("done.\n");
655 
656  error = freeze_processes();
657  if (error)
658  goto Free_bitmaps;
659 
660  error = hibernation_snapshot(hibernation_mode == HIBERNATION_PLATFORM);
661  if (error || freezer_test_done)
662  goto Thaw;
663 
664  if (in_suspend) {
665  unsigned int flags = 0;
666 
667  if (hibernation_mode == HIBERNATION_PLATFORM)
668  flags |= SF_PLATFORM_MODE;
669  if (nocompress)
670  flags |= SF_NOCOMPRESS_MODE;
671  else
672  flags |= SF_CRC32_MODE;
673 
674  pr_debug("PM: writing image.\n");
675  error = swsusp_write(flags);
676  swsusp_free();
677  if (!error)
678  power_down();
679  in_suspend = 0;
681  } else {
682  pr_debug("PM: Image restored successfully.\n");
683  }
684 
685  Thaw:
686  thaw_processes();
687 
688  /* Don't bother checking whether freezer_test_done is true */
689  freezer_test_done = false;
690 
691  Free_bitmaps:
693  Exit:
694  pm_notifier_call_chain(PM_POST_HIBERNATION);
697  Unlock:
698  unlock_system_sleep();
699  return error;
700 }
701 
702 
718 static int software_resume(void)
719 {
720  int error;
721  unsigned int flags;
722 
723  /*
724  * If the user said "noresume".. bail out early.
725  */
726  if (noresume)
727  return 0;
728 
729  /*
730  * name_to_dev_t() below takes a sysfs buffer mutex when sysfs
731  * is configured into the kernel. Since the regular hibernate
732  * trigger path is via sysfs which takes a buffer mutex before
733  * calling hibernate functions (which take pm_mutex) this can
734  * cause lockdep to complain about a possible ABBA deadlock
735  * which cannot happen since we're in the boot code here and
736  * sysfs can't be invoked yet. Therefore, we use a subclass
737  * here to avoid lockdep complaining.
738  */
740 
742  goto Check_image;
743 
744  if (!strlen(resume_file)) {
745  error = -ENOENT;
746  goto Unlock;
747  }
748 
749  pr_debug("PM: Checking hibernation image partition %s\n", resume_file);
750 
751  if (resume_delay) {
752  printk(KERN_INFO "Waiting %dsec before reading resume device...\n",
753  resume_delay);
754  ssleep(resume_delay);
755  }
756 
757  /* Check if the device is there */
758  swsusp_resume_device = name_to_dev_t(resume_file);
759 
760  /*
761  * name_to_dev_t is ineffective to verify parition if resume_file is in
762  * integer format. (e.g. major:minor)
763  */
764  if (isdigit(resume_file[0]) && resume_wait) {
765  int partno;
766  while (!get_gendisk(swsusp_resume_device, &partno))
767  msleep(10);
768  }
769 
770  if (!swsusp_resume_device) {
771  /*
772  * Some device discovery might still be in progress; we need
773  * to wait for this to finish.
774  */
776 
777  if (resume_wait) {
778  while ((swsusp_resume_device = name_to_dev_t(resume_file)) == 0)
779  msleep(10);
781  }
782 
783  swsusp_resume_device = name_to_dev_t(resume_file);
784  if (!swsusp_resume_device) {
785  error = -ENODEV;
786  goto Unlock;
787  }
788  }
789 
790  Check_image:
791  pr_debug("PM: Hibernation image partition %d:%d present\n",
793 
794  pr_debug("PM: Looking for hibernation image.\n");
795  error = swsusp_check();
796  if (error)
797  goto Unlock;
798 
799  /* The snapshot device should not be opened while we're running */
800  if (!atomic_add_unless(&snapshot_device_available, -1, 0)) {
801  error = -EBUSY;
803  goto Unlock;
804  }
805 
807  error = pm_notifier_call_chain(PM_RESTORE_PREPARE);
808  if (error)
809  goto close_finish;
810 
811  error = create_basic_memory_bitmaps();
812  if (error)
813  goto close_finish;
814 
815  pr_debug("PM: Preparing processes for restore.\n");
816  error = freeze_processes();
817  if (error) {
819  goto Done;
820  }
821 
822  pr_debug("PM: Loading hibernation image.\n");
823 
824  error = swsusp_read(&flags);
826  if (!error)
828 
829  printk(KERN_ERR "PM: Failed to load hibernation image, recovering.\n");
830  swsusp_free();
831  thaw_processes();
832  Done:
834  Finish:
835  pm_notifier_call_chain(PM_POST_RESTORE);
838  /* For success case, the suspend path will release the lock */
839  Unlock:
840  mutex_unlock(&pm_mutex);
841  pr_debug("PM: Hibernation image not present or could not be loaded.\n");
842  return error;
843 close_finish:
845  goto Finish;
846 }
847 
848 late_initcall(software_resume);
849 
850 
851 static const char * const hibernation_modes[] = {
852  [HIBERNATION_PLATFORM] = "platform",
853  [HIBERNATION_SHUTDOWN] = "shutdown",
854  [HIBERNATION_REBOOT] = "reboot",
855 #ifdef CONFIG_SUSPEND
856  [HIBERNATION_SUSPEND] = "suspend",
857 #endif
858 };
859 
860 /*
861  * /sys/power/disk - Control hibernation mode.
862  *
863  * Hibernation can be handled in several ways. There are a few different ways
864  * to put the system into the sleep state: using the platform driver (e.g. ACPI
865  * or other hibernation_ops), powering it off or rebooting it (for testing
866  * mostly).
867  *
868  * The sysfs file /sys/power/disk provides an interface for selecting the
869  * hibernation mode to use. Reading from this file causes the available modes
870  * to be printed. There are 3 modes that can be supported:
871  *
872  * 'platform'
873  * 'shutdown'
874  * 'reboot'
875  *
876  * If a platform hibernation driver is in use, 'platform' will be supported
877  * and will be used by default. Otherwise, 'shutdown' will be used by default.
878  * The selected option (i.e. the one corresponding to the current value of
879  * hibernation_mode) is enclosed by a square bracket.
880  *
881  * To select a given hibernation mode it is necessary to write the mode's
882  * string representation (as returned by reading from /sys/power/disk) back
883  * into /sys/power/disk.
884  */
885 
886 static ssize_t disk_show(struct kobject *kobj, struct kobj_attribute *attr,
887  char *buf)
888 {
889  int i;
890  char *start = buf;
891 
892  for (i = HIBERNATION_FIRST; i <= HIBERNATION_MAX; i++) {
893  if (!hibernation_modes[i])
894  continue;
895  switch (i) {
897  case HIBERNATION_REBOOT:
898 #ifdef CONFIG_SUSPEND
899  case HIBERNATION_SUSPEND:
900 #endif
901  break;
903  if (hibernation_ops)
904  break;
905  /* not a valid mode, continue with loop */
906  continue;
907  }
908  if (i == hibernation_mode)
909  buf += sprintf(buf, "[%s] ", hibernation_modes[i]);
910  else
911  buf += sprintf(buf, "%s ", hibernation_modes[i]);
912  }
913  buf += sprintf(buf, "\n");
914  return buf-start;
915 }
916 
917 static ssize_t disk_store(struct kobject *kobj, struct kobj_attribute *attr,
918  const char *buf, size_t n)
919 {
920  int error = 0;
921  int i;
922  int len;
923  char *p;
925 
926  p = memchr(buf, '\n', n);
927  len = p ? p - buf : n;
928 
929  lock_system_sleep();
930  for (i = HIBERNATION_FIRST; i <= HIBERNATION_MAX; i++) {
931  if (len == strlen(hibernation_modes[i])
932  && !strncmp(buf, hibernation_modes[i], len)) {
933  mode = i;
934  break;
935  }
936  }
937  if (mode != HIBERNATION_INVALID) {
938  switch (mode) {
940  case HIBERNATION_REBOOT:
941 #ifdef CONFIG_SUSPEND
942  case HIBERNATION_SUSPEND:
943 #endif
944  hibernation_mode = mode;
945  break;
947  if (hibernation_ops)
948  hibernation_mode = mode;
949  else
950  error = -EINVAL;
951  }
952  } else
953  error = -EINVAL;
954 
955  if (!error)
956  pr_debug("PM: Hibernation mode set to '%s'\n",
957  hibernation_modes[mode]);
958  unlock_system_sleep();
959  return error ? error : n;
960 }
961 
962 power_attr(disk);
963 
964 static ssize_t resume_show(struct kobject *kobj, struct kobj_attribute *attr,
965  char *buf)
966 {
967  return sprintf(buf,"%d:%d\n", MAJOR(swsusp_resume_device),
969 }
970 
971 static ssize_t resume_store(struct kobject *kobj, struct kobj_attribute *attr,
972  const char *buf, size_t n)
973 {
974  unsigned int maj, min;
975  dev_t res;
976  int ret = -EINVAL;
977 
978  if (sscanf(buf, "%u:%u", &maj, &min) != 2)
979  goto out;
980 
981  res = MKDEV(maj,min);
982  if (maj != MAJOR(res) || min != MINOR(res))
983  goto out;
984 
985  lock_system_sleep();
987  unlock_system_sleep();
988  printk(KERN_INFO "PM: Starting manual resume from disk\n");
989  noresume = 0;
990  software_resume();
991  ret = n;
992  out:
993  return ret;
994 }
995 
997 
998 static ssize_t image_size_show(struct kobject *kobj, struct kobj_attribute *attr,
999  char *buf)
1000 {
1001  return sprintf(buf, "%lu\n", image_size);
1002 }
1003 
1004 static ssize_t image_size_store(struct kobject *kobj, struct kobj_attribute *attr,
1005  const char *buf, size_t n)
1006 {
1007  unsigned long size;
1008 
1009  if (sscanf(buf, "%lu", &size) == 1) {
1010  image_size = size;
1011  return n;
1012  }
1013 
1014  return -EINVAL;
1015 }
1016 
1018 
1019 static ssize_t reserved_size_show(struct kobject *kobj,
1020  struct kobj_attribute *attr, char *buf)
1021 {
1022  return sprintf(buf, "%lu\n", reserved_size);
1023 }
1024 
1025 static ssize_t reserved_size_store(struct kobject *kobj,
1026  struct kobj_attribute *attr,
1027  const char *buf, size_t n)
1028 {
1029  unsigned long size;
1030 
1031  if (sscanf(buf, "%lu", &size) == 1) {
1032  reserved_size = size;
1033  return n;
1034  }
1035 
1036  return -EINVAL;
1037 }
1038 
1040 
1041 static struct attribute * g[] = {
1042  &disk_attr.attr,
1043  &resume_attr.attr,
1044  &image_size_attr.attr,
1045  &reserved_size_attr.attr,
1046  NULL,
1047 };
1048 
1049 
1050 static struct attribute_group attr_group = {
1051  .attrs = g,
1052 };
1053 
1054 
1055 static int __init pm_disk_init(void)
1056 {
1057  return sysfs_create_group(power_kobj, &attr_group);
1058 }
1059 
1060 core_initcall(pm_disk_init);
1061 
1062 
1063 static int __init resume_setup(char *str)
1064 {
1065  if (noresume)
1066  return 1;
1067 
1068  strncpy( resume_file, str, 255 );
1069  return 1;
1070 }
1071 
1072 static int __init resume_offset_setup(char *str)
1073 {
1074  unsigned long long offset;
1075 
1076  if (noresume)
1077  return 1;
1078 
1079  if (sscanf(str, "%llu", &offset) == 1)
1081 
1082  return 1;
1083 }
1084 
1085 static int __init hibernate_setup(char *str)
1086 {
1087  if (!strncmp(str, "noresume", 8))
1088  noresume = 1;
1089  else if (!strncmp(str, "nocompress", 10))
1090  nocompress = 1;
1091  return 1;
1092 }
1093 
1094 static int __init noresume_setup(char *str)
1095 {
1096  noresume = 1;
1097  return 1;
1098 }
1099 
1100 static int __init resumewait_setup(char *str)
1101 {
1102  resume_wait = 1;
1103  return 1;
1104 }
1105 
1106 static int __init resumedelay_setup(char *str)
1107 {
1108  resume_delay = simple_strtoul(str, NULL, 0);
1109  return 1;
1110 }
1111 
1112 __setup("noresume", noresume_setup);
1113 __setup("resume_offset=", resume_offset_setup);
1114 __setup("resume=", resume_setup);
1115 __setup("hibernate=", hibernate_setup);
1116 __setup("resumewait", resumewait_setup);
1117 __setup("resumedelay=", resumedelay_setup);