aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/power/hibernate.c
diff options
context:
space:
mode:
authorcodeworkx <codeworkx@cyanogenmod.com>2012-09-22 09:48:20 +0200
committercodeworkx <codeworkx@cyanogenmod.com>2012-09-22 14:02:16 +0200
commit2489007e7d740ccbc3e0a202914e243ad5178787 (patch)
treeb8e6380ea7b1da63474ad68a5dba997e01146043 /kernel/power/hibernate.c
parent5f67568eb31e3a813c7c52461dcf66ade15fc2e7 (diff)
downloadkernel_samsung_smdk4412-2489007e7d740ccbc3e0a202914e243ad5178787.zip
kernel_samsung_smdk4412-2489007e7d740ccbc3e0a202914e243ad5178787.tar.gz
kernel_samsung_smdk4412-2489007e7d740ccbc3e0a202914e243ad5178787.tar.bz2
merge opensource jb u5
Change-Id: I1aaec157aa196f3448eff8636134fce89a814cf2
Diffstat (limited to 'kernel/power/hibernate.c')
-rw-r--r--kernel/power/hibernate.c66
1 files changed, 65 insertions, 1 deletions
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 <linux/reboot.h>
#include <linux/string.h>
#include <linux/device.h>
+#include <linux/async.h>
#include <linux/kmod.h>
#include <linux/delay.h>
#include <linux/fs.h>
@@ -24,13 +25,16 @@
#include <linux/freezer.h>
#include <linux/gfp.h>
#include <linux/syscore_ops.h>
+#include <linux/ctype.h>
+#include <linux/genhd.h>
#include <scsi/scsi_scan.h>
#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);