aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/power/hibernate.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/power/hibernate.c')
-rw-r--r--kernel/power/hibernate.c49
1 files changed, 30 insertions, 19 deletions
diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
index 37170d4dd9a6..df88d55dc436 100644
--- a/kernel/power/hibernate.c
+++ b/kernel/power/hibernate.c
@@ -35,7 +35,7 @@
35static int nocompress; 35static int nocompress;
36static int noresume; 36static int noresume;
37static int resume_wait; 37static int resume_wait;
38static int resume_delay; 38static unsigned int resume_delay;
39static char resume_file[256] = CONFIG_PM_STD_PARTITION; 39static char resume_file[256] = CONFIG_PM_STD_PARTITION;
40dev_t swsusp_resume_device; 40dev_t swsusp_resume_device;
41sector_t swsusp_resume_block; 41sector_t swsusp_resume_block;
@@ -228,19 +228,23 @@ static void platform_recover(int platform_mode)
228void swsusp_show_speed(struct timeval *start, struct timeval *stop, 228void swsusp_show_speed(struct timeval *start, struct timeval *stop,
229 unsigned nr_pages, char *msg) 229 unsigned nr_pages, char *msg)
230{ 230{
231 s64 elapsed_centisecs64; 231 u64 elapsed_centisecs64;
232 int centisecs; 232 unsigned int centisecs;
233 int k; 233 unsigned int k;
234 int kps; 234 unsigned int kps;
235 235
236 elapsed_centisecs64 = timeval_to_ns(stop) - timeval_to_ns(start); 236 elapsed_centisecs64 = timeval_to_ns(stop) - timeval_to_ns(start);
237 /*
238 * If "(s64)elapsed_centisecs64 < 0", it will print long elapsed time,
239 * it is obvious enough for what went wrong.
240 */
237 do_div(elapsed_centisecs64, NSEC_PER_SEC / 100); 241 do_div(elapsed_centisecs64, NSEC_PER_SEC / 100);
238 centisecs = elapsed_centisecs64; 242 centisecs = elapsed_centisecs64;
239 if (centisecs == 0) 243 if (centisecs == 0)
240 centisecs = 1; /* avoid div-by-zero */ 244 centisecs = 1; /* avoid div-by-zero */
241 k = nr_pages * (PAGE_SIZE / 1024); 245 k = nr_pages * (PAGE_SIZE / 1024);
242 kps = (k * 100) / centisecs; 246 kps = (k * 100) / centisecs;
243 printk(KERN_INFO "PM: %s %d kbytes in %d.%02d seconds (%d.%02d MB/s)\n", 247 printk(KERN_INFO "PM: %s %u kbytes in %u.%02u seconds (%u.%02u MB/s)\n",
244 msg, k, 248 msg, k,
245 centisecs / 100, centisecs % 100, 249 centisecs / 100, centisecs % 100,
246 kps / 1000, (kps % 1000) / 10); 250 kps / 1000, (kps % 1000) / 10);
@@ -595,7 +599,8 @@ static void power_down(void)
595 case HIBERNATION_PLATFORM: 599 case HIBERNATION_PLATFORM:
596 hibernation_platform_enter(); 600 hibernation_platform_enter();
597 case HIBERNATION_SHUTDOWN: 601 case HIBERNATION_SHUTDOWN:
598 kernel_power_off(); 602 if (pm_power_off)
603 kernel_power_off();
599 break; 604 break;
600#ifdef CONFIG_SUSPEND 605#ifdef CONFIG_SUSPEND
601 case HIBERNATION_SUSPEND: 606 case HIBERNATION_SUSPEND:
@@ -623,7 +628,8 @@ static void power_down(void)
623 * corruption after resume. 628 * corruption after resume.
624 */ 629 */
625 printk(KERN_CRIT "PM: Please power down manually\n"); 630 printk(KERN_CRIT "PM: Please power down manually\n");
626 while(1); 631 while (1)
632 cpu_relax();
627} 633}
628 634
629/** 635/**
@@ -973,16 +979,20 @@ static ssize_t resume_show(struct kobject *kobj, struct kobj_attribute *attr,
973static ssize_t resume_store(struct kobject *kobj, struct kobj_attribute *attr, 979static ssize_t resume_store(struct kobject *kobj, struct kobj_attribute *attr,
974 const char *buf, size_t n) 980 const char *buf, size_t n)
975{ 981{
976 unsigned int maj, min;
977 dev_t res; 982 dev_t res;
978 int ret = -EINVAL; 983 int len = n;
984 char *name;
979 985
980 if (sscanf(buf, "%u:%u", &maj, &min) != 2) 986 if (len && buf[len-1] == '\n')
981 goto out; 987 len--;
988 name = kstrndup(buf, len, GFP_KERNEL);
989 if (!name)
990 return -ENOMEM;
982 991
983 res = MKDEV(maj,min); 992 res = name_to_dev_t(name);
984 if (maj != MAJOR(res) || min != MINOR(res)) 993 kfree(name);
985 goto out; 994 if (!res)
995 return -EINVAL;
986 996
987 lock_system_sleep(); 997 lock_system_sleep();
988 swsusp_resume_device = res; 998 swsusp_resume_device = res;
@@ -990,9 +1000,7 @@ static ssize_t resume_store(struct kobject *kobj, struct kobj_attribute *attr,
990 printk(KERN_INFO "PM: Starting manual resume from disk\n"); 1000 printk(KERN_INFO "PM: Starting manual resume from disk\n");
991 noresume = 0; 1001 noresume = 0;
992 software_resume(); 1002 software_resume();
993 ret = n; 1003 return n;
994 out:
995 return ret;
996} 1004}
997 1005
998power_attr(resume); 1006power_attr(resume);
@@ -1107,7 +1115,10 @@ static int __init resumewait_setup(char *str)
1107 1115
1108static int __init resumedelay_setup(char *str) 1116static int __init resumedelay_setup(char *str)
1109{ 1117{
1110 resume_delay = simple_strtoul(str, NULL, 0); 1118 int rc = kstrtouint(str, 0, &resume_delay);
1119
1120 if (rc)
1121 return rc;
1111 return 1; 1122 return 1;
1112} 1123}
1113 1124