diff options
Diffstat (limited to 'meta-agl-bsp/meta-renesas/recipes-kernel/linux/linux/hibernation/0001-Add-Hibernation-kernel-base-code.patch')
-rwxr-xr-x | meta-agl-bsp/meta-renesas/recipes-kernel/linux/linux/hibernation/0001-Add-Hibernation-kernel-base-code.patch | 853 |
1 files changed, 0 insertions, 853 deletions
diff --git a/meta-agl-bsp/meta-renesas/recipes-kernel/linux/linux/hibernation/0001-Add-Hibernation-kernel-base-code.patch b/meta-agl-bsp/meta-renesas/recipes-kernel/linux/linux/hibernation/0001-Add-Hibernation-kernel-base-code.patch deleted file mode 100755 index 87cd2863a..000000000 --- a/meta-agl-bsp/meta-renesas/recipes-kernel/linux/linux/hibernation/0001-Add-Hibernation-kernel-base-code.patch +++ /dev/null @@ -1,853 +0,0 @@ -From 60123966221b74199e4cf0c18d43396b4f00a94a Mon Sep 17 00:00:00 2001 -From: Yuichi Kusakabe <yuichi.kusakabe@jp.fujitsu.com> -Date: Thu, 18 May 2017 16:44:34 +0900 -Subject: [PATCH 01/15] Add Hibernation kernel base code - -Signed-off-by: Yuichi Kusakabe <yuichi.kusakabe@jp.fujitsu.com> ---- - include/linux/sched.h | 1 + - include/linux/suspend.h | 2 + - kernel/auditfilter.c | 2 +- - kernel/power/console.c | 2 + - kernel/power/hibernate.c | 146 +++++++++++++++++++++++++++++++---------------- - kernel/power/main.c | 4 -- - kernel/power/power.h | 8 ++- - kernel/power/process.c | 35 ++++++++---- - kernel/power/snapshot.c | 33 +++++++---- - kernel/power/suspend.c | 4 +- - kernel/power/swap.c | 50 ++++++++++++++-- - 11 files changed, 201 insertions(+), 86 deletions(-) - -diff --git a/include/linux/sched.h b/include/linux/sched.h -index f87e9a8..8e3270c 100644 ---- a/include/linux/sched.h -+++ b/include/linux/sched.h -@@ -1644,6 +1644,7 @@ extern void thread_group_cputime_adjusted(struct task_struct *p, cputime_t *ut, - #define PF_MEMPOLICY 0x10000000 /* Non-default NUMA mempolicy */ - #define PF_MUTEX_TESTER 0x20000000 /* Thread belongs to the rt mutex tester */ - #define PF_FREEZER_SKIP 0x40000000 /* Freezer should not count it as freezable */ -+#define PF_SUSPEND_TASK 0x80000000 /* this thread called freeze_processes and should not be frozen */ - - /* - * Only the _current_ task can read/write to tsk->flags, but other -diff --git a/include/linux/suspend.h b/include/linux/suspend.h -index d4e3f16..243ff56 100644 ---- a/include/linux/suspend.h -+++ b/include/linux/suspend.h -@@ -320,6 +320,8 @@ extern unsigned long get_safe_page(gfp_t gfp_mask); - extern void hibernation_set_ops(const struct platform_hibernation_ops *ops); - extern int hibernate(void); - extern bool system_entering_hibernation(void); -+asmlinkage int swsusp_save(void); -+extern struct pbe *restore_pblist; - #else /* CONFIG_HIBERNATION */ - static inline void register_nosave_region(unsigned long b, unsigned long e) {} - static inline void register_nosave_region_late(unsigned long b, unsigned long e) {} -diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c -index 6bd4a90..ac08a9a 100644 ---- a/kernel/auditfilter.c -+++ b/kernel/auditfilter.c -@@ -423,7 +423,7 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, - f->lsm_rule = NULL; - - /* Support legacy tests for a valid loginuid */ -- if ((f->type == AUDIT_LOGINUID) && (f->val == 4294967295)) { -+ if ((f->type == AUDIT_LOGINUID) && (f->val == 0xFFFFFFFF)) { - f->type = AUDIT_LOGINUID_SET; - f->val = 0; - } -diff --git a/kernel/power/console.c b/kernel/power/console.c -index 463aa67..aba9c54 100644 ---- a/kernel/power/console.c -+++ b/kernel/power/console.c -@@ -9,6 +9,7 @@ - #include <linux/kbd_kern.h> - #include <linux/vt.h> - #include <linux/module.h> -+#include <linux/slab.h> - #include "power.h" - - #define SUSPEND_CONSOLE (MAX_NR_CONSOLES-1) -@@ -81,6 +82,7 @@ void pm_vt_switch_unregister(struct device *dev) - list_for_each_entry(tmp, &pm_vt_switch_list, head) { - if (tmp->dev == dev) { - list_del(&tmp->head); -+ kfree(tmp); - break; - } - } -diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c -index b26f5f1..524dcf5 100644 ---- a/kernel/power/hibernate.c -+++ b/kernel/power/hibernate.c -@@ -34,12 +34,13 @@ - - static int nocompress; - static int noresume; -+static int nohibernate; - static int resume_wait; --static int resume_delay; -+static unsigned int resume_delay; - static char resume_file[256] = CONFIG_PM_STD_PARTITION; - dev_t swsusp_resume_device; - sector_t swsusp_resume_block; --int in_suspend __nosavedata; -+__visible int in_suspend __nosavedata; - - enum { - HIBERNATION_INVALID, -@@ -61,6 +62,11 @@ bool freezer_test_done; - - static const struct platform_hibernation_ops *hibernation_ops; - -+bool hibernation_available(void) -+{ -+ return (nohibernate == 0); -+} -+ - /** - * hibernation_set_ops - Set the global hibernate operations. - * @ops: Hibernation operations to use in subsequent hibernation transitions. -@@ -82,6 +88,7 @@ void hibernation_set_ops(const struct platform_hibernation_ops *ops) - - unlock_system_sleep(); - } -+EXPORT_SYMBOL_GPL(hibernation_set_ops); - - static bool entering_platform_hibernation; - -@@ -227,19 +234,23 @@ static void platform_recover(int platform_mode) - void swsusp_show_speed(struct timeval *start, struct timeval *stop, - unsigned nr_pages, char *msg) - { -- s64 elapsed_centisecs64; -- int centisecs; -- int k; -- int kps; -+ u64 elapsed_centisecs64; -+ unsigned int centisecs; -+ unsigned int k; -+ unsigned int kps; - - elapsed_centisecs64 = timeval_to_ns(stop) - timeval_to_ns(start); -+ /* -+ * If "(s64)elapsed_centisecs64 < 0", it will print long elapsed time, -+ * it is obvious enough for what went wrong. -+ */ - do_div(elapsed_centisecs64, NSEC_PER_SEC / 100); - centisecs = elapsed_centisecs64; - if (centisecs == 0) - centisecs = 1; /* avoid div-by-zero */ - k = nr_pages * (PAGE_SIZE / 1024); - kps = (k * 100) / centisecs; -- printk(KERN_INFO "PM: %s %d kbytes in %d.%02d seconds (%d.%02d MB/s)\n", -+ pr_info("PM: %s %u kbytes in %u.%02u seconds (%u.%02u MB/s)\n", - msg, k, - centisecs / 100, centisecs % 100, - kps / 1000, (kps % 1000) / 10); -@@ -293,10 +304,10 @@ static int create_image(int platform_mode) - error); - /* Restore control flow magically appears here */ - restore_processor_state(); -- if (!in_suspend) { -+ if (!in_suspend) - events_check_enabled = false; -- platform_leave(platform_mode); -- } -+ -+ platform_leave(platform_mode); - - Power_up: - syscore_resume(); -@@ -594,7 +605,8 @@ static void power_down(void) - case HIBERNATION_PLATFORM: - hibernation_platform_enter(); - case HIBERNATION_SHUTDOWN: -- kernel_power_off(); -+ if (pm_power_off) -+ kernel_power_off(); - break; - #ifdef CONFIG_SUSPEND - case HIBERNATION_SUSPEND: -@@ -622,7 +634,8 @@ static void power_down(void) - * corruption after resume. - */ - printk(KERN_CRIT "PM: Please power down manually\n"); -- while(1); -+ while (1) -+ cpu_relax(); - } - - /** -@@ -632,6 +645,11 @@ int hibernate(void) - { - int error; - -+ if (!hibernation_available()) { -+ pr_debug("PM: Hibernation not available.\n"); -+ return -EPERM; -+ } -+ - lock_system_sleep(); - /* The snapshot device should not be opened while we're running */ - if (!atomic_add_unless(&snapshot_device_available, -1, 0)) { -@@ -644,22 +662,22 @@ int hibernate(void) - if (error) - goto Exit; - -- /* Allocate memory management structures */ -- error = create_basic_memory_bitmaps(); -- if (error) -- goto Exit; -- - printk(KERN_INFO "PM: Syncing filesystems ... "); - sys_sync(); - printk("done.\n"); - - error = freeze_processes(); - if (error) -- goto Free_bitmaps; -+ goto Exit; -+ -+ /* Allocate memory management structures */ -+ error = create_basic_memory_bitmaps(); -+ if (error) -+ goto Thaw; - - error = hibernation_snapshot(hibernation_mode == HIBERNATION_PLATFORM); - if (error || freezer_test_done) -- goto Thaw; -+ goto Free_bitmaps; - - if (in_suspend) { - unsigned int flags = 0; -@@ -682,14 +700,13 @@ int hibernate(void) - pr_debug("PM: Image restored successfully.\n"); - } - -+ Free_bitmaps: -+ free_basic_memory_bitmaps(); - Thaw: - thaw_processes(); - - /* Don't bother checking whether freezer_test_done is true */ - freezer_test_done = false; -- -- Free_bitmaps: -- free_basic_memory_bitmaps(); - Exit: - pm_notifier_call_chain(PM_POST_HIBERNATION); - pm_restore_console(); -@@ -723,7 +740,7 @@ static int software_resume(void) - /* - * If the user said "noresume".. bail out early. - */ -- if (noresume) -+ if (noresume || !hibernation_available()) - return 0; - - /* -@@ -806,21 +823,19 @@ static int software_resume(void) - pm_prepare_console(); - error = pm_notifier_call_chain(PM_RESTORE_PREPARE); - if (error) -- goto close_finish; -- -- error = create_basic_memory_bitmaps(); -- if (error) -- goto close_finish; -+ goto Close_Finish; - - pr_debug("PM: Preparing processes for restore.\n"); - error = freeze_processes(); -- if (error) { -- swsusp_close(FMODE_READ); -- goto Done; -- } -+ if (error) -+ goto Close_Finish; - - pr_debug("PM: Loading hibernation image.\n"); - -+ error = create_basic_memory_bitmaps(); -+ if (error) -+ goto Thaw; -+ - error = swsusp_read(&flags); - swsusp_close(FMODE_READ); - if (!error) -@@ -828,9 +843,9 @@ static int software_resume(void) - - printk(KERN_ERR "PM: Failed to load hibernation image, recovering.\n"); - swsusp_free(); -- thaw_processes(); -- Done: - free_basic_memory_bitmaps(); -+ Thaw: -+ thaw_processes(); - Finish: - pm_notifier_call_chain(PM_POST_RESTORE); - pm_restore_console(); -@@ -840,12 +855,12 @@ static int software_resume(void) - mutex_unlock(&pm_mutex); - pr_debug("PM: Hibernation image not present or could not be loaded.\n"); - return error; --close_finish: -+ Close_Finish: - swsusp_close(FMODE_READ); - goto Finish; - } - --late_initcall(software_resume); -+late_initcall_sync(software_resume); - - - static const char * const hibernation_modes[] = { -@@ -889,6 +904,9 @@ static ssize_t disk_show(struct kobject *kobj, struct kobj_attribute *attr, - int i; - char *start = buf; - -+ if (!hibernation_available()) -+ return sprintf(buf, "[disabled]\n"); -+ - for (i = HIBERNATION_FIRST; i <= HIBERNATION_MAX; i++) { - if (!hibernation_modes[i]) - continue; -@@ -923,6 +941,9 @@ static ssize_t disk_store(struct kobject *kobj, struct kobj_attribute *attr, - char *p; - int mode = HIBERNATION_INVALID; - -+ if (!hibernation_available()) -+ return -EPERM; -+ - p = memchr(buf, '\n', n); - len = p ? p - buf : n; - -@@ -971,16 +992,20 @@ static ssize_t resume_show(struct kobject *kobj, struct kobj_attribute *attr, - static ssize_t resume_store(struct kobject *kobj, struct kobj_attribute *attr, - const char *buf, size_t n) - { -- unsigned int maj, min; - dev_t res; -- int ret = -EINVAL; -+ int len = n; -+ char *name; - -- if (sscanf(buf, "%u:%u", &maj, &min) != 2) -- goto out; -+ if (len && buf[len-1] == '\n') -+ len--; -+ name = kstrndup(buf, len, GFP_KERNEL); -+ if (!name) -+ return -ENOMEM; - -- res = MKDEV(maj,min); -- if (maj != MAJOR(res) || min != MINOR(res)) -- goto out; -+ res = name_to_dev_t(name); -+ kfree(name); -+ if (!res) -+ return -EINVAL; - - lock_system_sleep(); - swsusp_resume_device = res; -@@ -988,20 +1013,20 @@ static ssize_t resume_store(struct kobject *kobj, struct kobj_attribute *attr, - printk(KERN_INFO "PM: Starting manual resume from disk\n"); - noresume = 0; - software_resume(); -- ret = n; -- out: -- return ret; -+ return n; - } - - power_attr(resume); - --static ssize_t image_size_show(struct kobject *kobj, struct kobj_attribute *attr, -+static ssize_t image_size_show(struct kobject *kobj, -+ struct kobj_attribute *attr, - char *buf) - { - return sprintf(buf, "%lu\n", image_size); - } - --static ssize_t image_size_store(struct kobject *kobj, struct kobj_attribute *attr, -+static ssize_t image_size_store(struct kobject *kobj, -+ struct kobj_attribute *attr, - const char *buf, size_t n) - { - unsigned long size; -@@ -1065,7 +1090,7 @@ static int __init resume_setup(char *str) - if (noresume) - return 1; - -- strncpy( resume_file, str, 255 ); -+ strncpy(resume_file, str, 255); - return 1; - } - -@@ -1088,6 +1113,10 @@ static int __init hibernate_setup(char *str) - noresume = 1; - else if (!strncmp(str, "nocompress", 10)) - nocompress = 1; -+ else if (!strncmp(str, "no", 2)) { -+ noresume = 1; -+ nohibernate = 1; -+ } - return 1; - } - -@@ -1105,13 +1134,30 @@ static int __init resumewait_setup(char *str) - - static int __init resumedelay_setup(char *str) - { -- resume_delay = simple_strtoul(str, NULL, 0); -+ int rc = kstrtouint(str, 0, &resume_delay); -+ -+ if (rc) -+ return rc; -+ return 1; -+} -+ -+static int __init nohibernate_setup(char *str) -+{ -+ noresume = 1; -+ nohibernate = 1; - return 1; - } - -+static int __init kaslr_nohibernate_setup(char *str) -+{ -+ return nohibernate_setup(str); -+} -+ - __setup("noresume", noresume_setup); - __setup("resume_offset=", resume_offset_setup); - __setup("resume=", resume_setup); - __setup("hibernate=", hibernate_setup); - __setup("resumewait", resumewait_setup); - __setup("resumedelay=", resumedelay_setup); -+__setup("nohibernate", nohibernate_setup); -+__setup("kaslr", kaslr_nohibernate_setup); -diff --git a/kernel/power/main.c b/kernel/power/main.c -index d77663b..ac615e4 100644 ---- a/kernel/power/main.c -+++ b/kernel/power/main.c -@@ -610,7 +610,6 @@ static struct attribute_group attr_group = { - .attrs = g, - }; - --#ifdef CONFIG_PM_RUNTIME - struct workqueue_struct *pm_wq; - EXPORT_SYMBOL_GPL(pm_wq); - -@@ -620,9 +619,6 @@ static int __init pm_start_workqueue(void) - - return pm_wq ? 0 : -ENOMEM; - } --#else --static inline int pm_start_workqueue(void) { return 0; } --#endif - - static int __init pm_init(void) - { -diff --git a/kernel/power/power.h b/kernel/power/power.h -index 7d4b7ff..c5821ca 100644 ---- a/kernel/power/power.h -+++ b/kernel/power/power.h -@@ -2,6 +2,7 @@ - #include <linux/suspend_ioctls.h> - #include <linux/utsname.h> - #include <linux/freezer.h> -+#include <linux/compiler.h> - - struct swsusp_info { - struct new_utsname uts; -@@ -11,7 +12,8 @@ struct swsusp_info { - unsigned long image_pages; - unsigned long pages; - unsigned long size; --} __attribute__((aligned(PAGE_SIZE))); -+ char archdata[1024]; -+} __aligned(PAGE_SIZE); - - #ifdef CONFIG_HIBERNATION - /* kernel/power/snapshot.c */ -@@ -37,6 +39,8 @@ static inline char *check_image_kernel(struct swsusp_info *info) - } - #endif /* CONFIG_ARCH_HIBERNATION_HEADER */ - -+extern void __weak swsusp_arch_add_info(char *archdata); -+ - /* - * Keep some memory free so that I/O operations can succeed without paging - * [Might this be more than 4 MB?] -@@ -49,6 +53,8 @@ static inline char *check_image_kernel(struct swsusp_info *info) - */ - #define SPARE_PAGES ((1024 * 1024) >> PAGE_SHIFT) - -+asmlinkage int swsusp_save(void); -+ - /* kernel/power/hibernate.c */ - extern bool freezer_test_done; - -diff --git a/kernel/power/process.c b/kernel/power/process.c -index 0695319..04559b4 100644 ---- a/kernel/power/process.c -+++ b/kernel/power/process.c -@@ -30,9 +30,10 @@ static int try_to_freeze_tasks(bool user_only) - unsigned int todo; - bool wq_busy = false; - struct timeval start, end; -- u64 elapsed_csecs64; -- unsigned int elapsed_csecs; -+ u64 elapsed_msecs64; -+ unsigned int elapsed_msecs; - bool wakeup = false; -+ int sleep_usecs = USEC_PER_MSEC; - - do_gettimeofday(&start); - -@@ -68,22 +69,25 @@ static int try_to_freeze_tasks(bool user_only) - - /* - * We need to retry, but first give the freezing tasks some -- * time to enter the refrigerator. -+ * time to enter the refrigerator. Start with an initial -+ * 1 ms sleep followed by exponential backoff until 8 ms. - */ -- msleep(10); -+ usleep_range(sleep_usecs / 2, sleep_usecs); -+ if (sleep_usecs < 8 * USEC_PER_MSEC) -+ sleep_usecs *= 2; - } - - do_gettimeofday(&end); -- elapsed_csecs64 = timeval_to_ns(&end) - timeval_to_ns(&start); -- do_div(elapsed_csecs64, NSEC_PER_SEC / 100); -- elapsed_csecs = elapsed_csecs64; -+ elapsed_msecs64 = timeval_to_ns(&end) - timeval_to_ns(&start); -+ do_div(elapsed_msecs64, NSEC_PER_MSEC); -+ elapsed_msecs = elapsed_msecs64; - - if (todo) { - printk("\n"); -- printk(KERN_ERR "Freezing of tasks %s after %d.%02d seconds " -+ printk(KERN_ERR "Freezing of tasks %s after %d.%03d seconds " - "(%d tasks refusing to freeze, wq_busy=%d):\n", - wakeup ? "aborted" : "failed", -- elapsed_csecs / 100, elapsed_csecs % 100, -+ elapsed_msecs / 1000, elapsed_msecs % 1000, - todo - wq_busy, wq_busy); - - if (!wakeup) { -@@ -96,8 +100,8 @@ static int try_to_freeze_tasks(bool user_only) - read_unlock(&tasklist_lock); - } - } else { -- printk("(elapsed %d.%02d seconds) ", elapsed_csecs / 100, -- elapsed_csecs % 100); -+ printk("(elapsed %d.%03d seconds) ", elapsed_msecs / 1000, -+ elapsed_msecs % 1000); - } - - return todo ? -EBUSY : 0; -@@ -139,6 +143,9 @@ int freeze_processes(void) - if (error) - return error; - -+ /* Make sure this task doesn't get frozen */ -+ current->flags |= PF_SUSPEND_TASK; -+ - if (!pm_freezing) - atomic_inc(&system_freezing_cnt); - -@@ -202,6 +209,7 @@ int freeze_kernel_threads(void) - void thaw_processes(void) - { - struct task_struct *g, *p; -+ struct task_struct *curr = current; - - if (pm_freezing) - atomic_dec(&system_freezing_cnt); -@@ -217,10 +225,15 @@ void thaw_processes(void) - - read_lock(&tasklist_lock); - do_each_thread(g, p) { -+ /* No other threads should have PF_SUSPEND_TASK set */ -+ WARN_ON((p != curr) && (p->flags & PF_SUSPEND_TASK)); - __thaw_task(p); - } while_each_thread(g, p); - read_unlock(&tasklist_lock); - -+ WARN_ON(!(curr->flags & PF_SUSPEND_TASK)); -+ curr->flags &= ~PF_SUSPEND_TASK; -+ - usermodehelper_enable(); - - schedule(); -diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c -index 91c04f1..a673f7b 100644 ---- a/kernel/power/snapshot.c -+++ b/kernel/power/snapshot.c -@@ -27,6 +27,7 @@ - #include <linux/highmem.h> - #include <linux/list.h> - #include <linux/slab.h> -+#include <linux/compiler.h> - - #include <asm/uaccess.h> - #include <asm/mmu_context.h> -@@ -155,7 +156,7 @@ static inline void free_image_page(void *addr, int clear_nosave_free) - struct linked_page { - struct linked_page *next; - char data[LINKED_PAGE_DATA_SIZE]; --} __attribute__((packed)); -+} __packed; - - static inline void - free_list_of_pages(struct linked_page *list, int clear_page_nosave) -@@ -352,7 +353,7 @@ static int create_mem_extents(struct list_head *list, gfp_t gfp_mask) - struct mem_extent *ext, *cur, *aux; - - zone_start = zone->zone_start_pfn; -- zone_end = zone->zone_start_pfn + zone->spanned_pages; -+ zone_end = zone_end_pfn(zone); - - list_for_each_entry(ext, list, hook) - if (zone_start <= ext->end) -@@ -642,8 +643,9 @@ __register_nosave_region(unsigned long start_pfn, unsigned long end_pfn, - region->end_pfn = end_pfn; - list_add_tail(®ion->list, &nosave_regions); - Report: -- printk(KERN_INFO "PM: Registered nosave memory: %016lx - %016lx\n", -- start_pfn << PAGE_SHIFT, end_pfn << PAGE_SHIFT); -+ printk(KERN_INFO "PM: Registered nosave memory: [mem %#010llx-%#010llx]\n", -+ (unsigned long long) start_pfn << PAGE_SHIFT, -+ ((unsigned long long) end_pfn << PAGE_SHIFT) - 1); - } - - /* -@@ -742,7 +744,10 @@ int create_basic_memory_bitmaps(void) - struct memory_bitmap *bm1, *bm2; - int error = 0; - -- BUG_ON(forbidden_pages_map || free_pages_map); -+ if (forbidden_pages_map && free_pages_map) -+ return 0; -+ else -+ BUG_ON(forbidden_pages_map || free_pages_map); - - bm1 = kzalloc(sizeof(struct memory_bitmap), GFP_KERNEL); - if (!bm1) -@@ -788,7 +793,8 @@ void free_basic_memory_bitmaps(void) - { - struct memory_bitmap *bm1, *bm2; - -- BUG_ON(!(forbidden_pages_map && free_pages_map)); -+ if (WARN_ON(!(forbidden_pages_map && free_pages_map))) -+ return; - - bm1 = forbidden_pages_map; - bm2 = free_pages_map; -@@ -883,7 +889,7 @@ static unsigned int count_highmem_pages(void) - continue; - - mark_free_pages(zone); -- max_zone_pfn = zone->zone_start_pfn + zone->spanned_pages; -+ max_zone_pfn = zone_end_pfn(zone); - for (pfn = zone->zone_start_pfn; pfn < max_zone_pfn; pfn++) - if (saveable_highmem_page(zone, pfn)) - n++; -@@ -947,7 +953,7 @@ static unsigned int count_data_pages(void) - continue; - - mark_free_pages(zone); -- max_zone_pfn = zone->zone_start_pfn + zone->spanned_pages; -+ max_zone_pfn = zone_end_pfn(zone); - for (pfn = zone->zone_start_pfn; pfn < max_zone_pfn; pfn++) - if (saveable_page(zone, pfn)) - n++; -@@ -1040,7 +1046,7 @@ copy_data_pages(struct memory_bitmap *copy_bm, struct memory_bitmap *orig_bm) - unsigned long max_zone_pfn; - - mark_free_pages(zone); -- max_zone_pfn = zone->zone_start_pfn + zone->spanned_pages; -+ max_zone_pfn = zone_end_pfn(zone); - for (pfn = zone->zone_start_pfn; pfn < max_zone_pfn; pfn++) - if (page_is_saveable(zone, pfn)) - memory_bm_set_bit(orig_bm, pfn); -@@ -1092,7 +1098,7 @@ void swsusp_free(void) - unsigned long pfn, max_zone_pfn; - - for_each_populated_zone(zone) { -- max_zone_pfn = zone->zone_start_pfn + zone->spanned_pages; -+ max_zone_pfn = zone_end_pfn(zone); - for (pfn = zone->zone_start_pfn; pfn < max_zone_pfn; pfn++) - if (pfn_valid(pfn)) { - struct page *page = pfn_to_page(pfn); -@@ -1580,7 +1586,7 @@ swsusp_alloc(struct memory_bitmap *orig_bm, struct memory_bitmap *copy_bm, - return -ENOMEM; - } - --asmlinkage int swsusp_save(void) -+asmlinkage __visible int swsusp_save(void) - { - unsigned int nr_pages, nr_highmem; - -@@ -1628,6 +1634,7 @@ static int init_header_complete(struct swsusp_info *info) - { - memcpy(&info->uts, init_utsname(), sizeof(struct new_utsname)); - info->version_code = LINUX_VERSION_CODE; -+ swsusp_arch_add_info(info->archdata); - return 0; - } - -@@ -1647,6 +1654,8 @@ static char *check_image_kernel(struct swsusp_info *info) - } - #endif /* CONFIG_ARCH_HIBERNATION_HEADER */ - -+void __weak swsusp_arch_add_info(char *archdata) {} -+ - unsigned long snapshot_get_image_size(void) - { - return nr_copy_pages + nr_meta_pages + 1; -@@ -1758,7 +1767,7 @@ static int mark_unsafe_pages(struct memory_bitmap *bm) - - /* Clear page flags */ - for_each_populated_zone(zone) { -- max_zone_pfn = zone->zone_start_pfn + zone->spanned_pages; -+ max_zone_pfn = zone_end_pfn(zone); - for (pfn = zone->zone_start_pfn; pfn < max_zone_pfn; pfn++) - if (pfn_valid(pfn)) - swsusp_unset_page_free(pfn_to_page(pfn)); -diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c -index bef86d1..deec937 100644 ---- a/kernel/power/suspend.c -+++ b/kernel/power/suspend.c -@@ -156,13 +156,13 @@ static int suspend_prepare(suspend_state_t state) - } - - /* default implementation */ --void __attribute__ ((weak)) arch_suspend_disable_irqs(void) -+void __weak arch_suspend_disable_irqs(void) - { - local_irq_disable(); - } - - /* default implementation */ --void __attribute__ ((weak)) arch_suspend_enable_irqs(void) -+void __weak arch_suspend_enable_irqs(void) - { - local_irq_enable(); - } -diff --git a/kernel/power/swap.c b/kernel/power/swap.c -index 7c33ed2..a6a1c55 100644 ---- a/kernel/power/swap.c -+++ b/kernel/power/swap.c -@@ -91,17 +91,28 @@ struct swap_map_handle { - unsigned int k; - unsigned long reqd_free_pages; - u32 crc32; -+#ifdef CONFIG_ARCH_SHMOBILE -+ unsigned int img_size; /* add */ -+#endif - }; - - struct swsusp_header { -+#ifdef CONFIG_ARCH_SHMOBILE -+ char reserved[PAGE_SIZE - 20 - sizeof(sector_t) - sizeof(int) - -+ sizeof(u32) - (sizeof(unsigned int)*4) - sizeof(u32)]; -+ unsigned int comp_crc32[4]; -+ u32 img_size; -+#else - char reserved[PAGE_SIZE - 20 - sizeof(sector_t) - sizeof(int) - -- sizeof(u32)]; -+ sizeof(u32) - sizeof(u32)]; -+ u32 comp_crc32; -+#endif - u32 crc32; - sector_t image; - unsigned int flags; /* Flags to pass to the "boot" kernel */ - char orig_sig[10]; - char sig[10]; --} __attribute__((packed)); -+} __packed; - - static struct swsusp_header *swsusp_header; - -@@ -230,6 +241,11 @@ static int mark_swapfiles(struct swap_map_handle *handle, unsigned int flags) - swsusp_header->flags = flags; - if (flags & SF_CRC32_MODE) - swsusp_header->crc32 = handle->crc32; -+ -+#ifdef CONFIG_ARCH_SHMOBILE -+ swsusp_header->img_size = handle->img_size; -+#endif -+ - error = hib_bio_write_page(swsusp_resume_block, - swsusp_header, NULL); - } else { -@@ -587,7 +603,11 @@ static int save_image_lzo(struct swap_map_handle *handle, - unsigned char *page = NULL; - struct cmp_data *data = NULL; - struct crc_data *crc = NULL; -+ int compr = 0; - -+#ifdef CONFIG_ARCH_SHMOBILE -+ unsigned int comp_imgtotal = 0; -+#endif - /* - * We'll limit the number of threads for compression to limit memory - * footprint. -@@ -733,7 +753,12 @@ static int save_image_lzo(struct swap_map_handle *handle, - } - - *(size_t *)data[thr].cmp = data[thr].cmp_len; -- -+ compr += data[thr].cmp_len; -+#ifdef CONFIG_ARCH_SHMOBILE -+ comp_imgtotal += (data[thr].cmp_len -+ + LZO_HEADER + (PAGE_SIZE - 1)) -+ & ~(PAGE_SIZE - 1); -+#endif - /* - * Given we are writing one page at a time to disk, we - * copy that much from the buffer, although the last -@@ -746,7 +771,6 @@ static int save_image_lzo(struct swap_map_handle *handle, - off < LZO_HEADER + data[thr].cmp_len; - off += PAGE_SIZE) { - memcpy(page, data[thr].cmp + off, PAGE_SIZE); -- - ret = swap_write_page(handle, page, &bio); - if (ret) - goto out_finish; -@@ -762,8 +786,24 @@ out_finish: - do_gettimeofday(&stop); - if (!ret) - ret = err2; -- if (!ret) -+ if (!ret) { -+#ifdef CONFIG_ARCH_SHMOBILE -+ const unsigned int ds = comp_imgtotal + -+ ((comp_imgtotal -+ / ((2 * 1024 * 1024) -+ - PAGE_SIZE)) * PAGE_SIZE); -+ const unsigned int swaped = -+ (swp_offset(get_swap_page_of_type(root_swap)) -+ - 2) * PAGE_SIZE; -+ if (ds < swaped) -+ handle->img_size = swaped; -+ else -+ handle->img_size = ds; -+#endif - printk(KERN_INFO "PM: Image saving done.\n"); -+ printk(KERN_INFO "PM: Compressed output size: %d [%d] (imgsize=%d/swaped size=%d)\n", -+ compr, handle->img_size, ds, swaped); -+ } - swsusp_show_speed(&start, &stop, nr_to_write, "Wrote"); - out_clean: - if (crc) { --- -1.8.3.1 - |