| From 954a3028e5ffd52c14190a8cbb06948b0d6cbb83 Mon Sep 17 00:00:00 2001 |
| From: Barry Song <baohua.song@csr.com> |
| Date: Thu, 6 Oct 2011 20:34:46 +0200 |
| Subject: PM / Hibernate: Add resumewait param to support MMC-like devices as |
| resume file |
| |
| Some devices like MMC are async detected very slow. For example, |
| drivers/mmc/host/sdhci.c launches a 200ms delayed work to detect |
| MMC partitions then add disk. |
| |
| We have wait_for_device_probe() and scsi_complete_async_scans() |
| before calling swsusp_check(), but it is not enough to wait for MMC. |
| |
| This patch adds resumewait kernel param just like rootwait so |
| that we have enough time to wait until MMC is ready. The difference is |
| that we wait for resume partition whereas rootwait waits for rootfs |
| partition (which may be on a different device). |
| |
| This patch will make hibernation support many embedded products |
| without SCSI devices, but with devices like MMC. |
| |
| [rjw: Modified the changelog slightly.] |
| |
| Signed-off-by: Barry Song <Baohua.Song@csr.com> |
| Reviewed-by: Valdis Kletnieks <valdis.kletnieks@vt.edu> |
| Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> |
| (cherry picked from commit 6f8d7022a842809aeb24db1d15669198ef02c131) |
| |
| Signed-off-by: Simon Horman <horms@verge.net.au> |
| --- |
| Documentation/kernel-parameters.txt | 4 ++++ |
| kernel/power/hibernate.c | 16 ++++++++++++++++ |
| 2 files changed, 20 insertions(+) |
| |
| --- a/Documentation/kernel-parameters.txt |
| +++ b/Documentation/kernel-parameters.txt |
| @@ -2230,6 +2230,10 @@ bytes respectively. Such letter suffixes |
| in <PAGE_SIZE> units (needed only for swap files). |
| See Documentation/power/swsusp-and-swap-files.txt |
| |
| + resumewait [HIBERNATION] Wait (indefinitely) for resume device to show up. |
| + Useful for devices that are detected asynchronously |
| + (e.g. USB and MMC devices). |
| + |
| hibernate= [HIBERNATION] |
| noresume Don't check if there's a hibernation image |
| present during boot. |
| --- 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> |
| @@ -31,6 +32,7 @@ |
| |
| static int nocompress = 0; |
| static int noresume = 0; |
| +static int resume_wait = 0; |
| static char resume_file[256] = CONFIG_PM_STD_PARTITION; |
| dev_t swsusp_resume_device; |
| sector_t swsusp_resume_block; |
| @@ -743,6 +745,13 @@ static int software_resume(void) |
| * 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 |
| @@ -1071,7 +1080,14 @@ static int __init noresume_setup(char *s |
| 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); |