From 2489007e7d740ccbc3e0a202914e243ad5178787 Mon Sep 17 00:00:00 2001 From: codeworkx Date: Sat, 22 Sep 2012 09:48:20 +0200 Subject: merge opensource jb u5 Change-Id: I1aaec157aa196f3448eff8636134fce89a814cf2 --- kernel/power/hibernate.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-) (limited to 'kernel/power/hibernate.c') diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c index 8884c27..c260280 100644 --- a/kernel/power/hibernate.c +++ b/kernel/power/hibernate.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -24,13 +25,16 @@ #include #include #include +#include +#include #include #include "power.h" static int nocompress = 0; -static int noresume = 0; +int noresume; +static int resume_wait = 0; static char resume_file[256] = CONFIG_PM_STD_PARTITION; dev_t swsusp_resume_device; sector_t swsusp_resume_block; @@ -727,12 +731,30 @@ static int software_resume(void) /* Check if the device is there */ swsusp_resume_device = name_to_dev_t(resume_file); + + /* + * name_to_dev_t is ineffective to verify parition if resume_file is in + * integer format. (e.g. major:minor) + */ + if (isdigit(resume_file[0]) && resume_wait) { + int partno; + while (!get_gendisk(swsusp_resume_device, &partno)) + msleep(10); + } + if (!swsusp_resume_device) { /* * Some device discovery might still be in progress; we need * to wait for this to finish. */ wait_for_device_probe(); + + if (resume_wait) { + while ((swsusp_resume_device = name_to_dev_t(resume_file)) == 0) + msleep(10); + async_synchronize_full(); + } + /* * We can't depend on SCSI devices being available after loading * one of their modules until scsi_complete_async_scans() is @@ -810,7 +832,11 @@ close_finish: goto Finish; } +#ifdef CONFIG_FAST_RESUME +resume_initcall(software_resume); +#else late_initcall(software_resume); +#endif static const char * const hibernation_modes[] = { @@ -1002,11 +1028,42 @@ static ssize_t reserved_size_store(struct kobject *kobj, power_attr(reserved_size); +#ifdef CONFIG_FAST_RESUME +static ssize_t noresume_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", noresume); +} + +static ssize_t noresume_store(struct kobject *kobj, + struct kobj_attribute *attr, const char *buf, size_t n) +{ + if (sscanf(buf, "%d", &noresume) == 1) { + noresume = !!noresume; + if (noresume) { + if (!swsusp_resume_device) + swsusp_resume_device = + name_to_dev_t(resume_file); + swsusp_check(); + swsusp_close(FMODE_READ); + } + return n; + } + + return -EINVAL; +} + +power_attr(noresume); +#endif + static struct attribute * g[] = { &disk_attr.attr, &resume_attr.attr, &image_size_attr.attr, &reserved_size_attr.attr, +#ifdef CONFIG_FAST_RESUME + &noresume_attr.attr, +#endif NULL, }; @@ -1061,7 +1118,14 @@ static int __init noresume_setup(char *str) return 1; } +static int __init resumewait_setup(char *str) +{ + resume_wait = 1; + return 1; +} + __setup("noresume", noresume_setup); __setup("resume_offset=", resume_offset_setup); __setup("resume=", resume_setup); __setup("hibernate=", hibernate_setup); +__setup("resumewait=", resumewait_setup); -- cgit v1.1