^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * kernel/power/hibernate.c - Hibernation (a.k.a suspend-to-disk) support.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 2003 Patrick Mochel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (c) 2003 Open Source Development Lab
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (c) 2004 Pavel Machek <pavel@ucw.cz>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright (c) 2009 Rafael J. Wysocki, Novell Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Copyright (C) 2012 Bojan Smojver <bojan@rexursive.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #define pr_fmt(fmt) "PM: hibernation: " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/suspend.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/reboot.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/async.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/mount.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/pm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/nmi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/console.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/cpu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/freezer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/gfp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/syscore_ops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/ctype.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/genhd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/ktime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/security.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <trace/events/power.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include "power.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) static int nocompress;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) static int noresume;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) static int nohibernate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) static int resume_wait;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) static unsigned int resume_delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) static char resume_file[256] = CONFIG_PM_STD_PARTITION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) dev_t swsusp_resume_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) sector_t swsusp_resume_block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) __visible int in_suspend __nosavedata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) HIBERNATION_INVALID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) HIBERNATION_PLATFORM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) HIBERNATION_SHUTDOWN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) HIBERNATION_REBOOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #ifdef CONFIG_SUSPEND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) HIBERNATION_SUSPEND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) HIBERNATION_TEST_RESUME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) /* keep last */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) __HIBERNATION_AFTER_LAST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define HIBERNATION_MAX (__HIBERNATION_AFTER_LAST-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define HIBERNATION_FIRST (HIBERNATION_INVALID + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) static int hibernation_mode = HIBERNATION_SHUTDOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) bool freezer_test_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) static const struct platform_hibernation_ops *hibernation_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) static atomic_t hibernate_atomic = ATOMIC_INIT(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) bool hibernate_acquire(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) return atomic_add_unless(&hibernate_atomic, -1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) void hibernate_release(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) atomic_inc(&hibernate_atomic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) bool hibernation_available(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) return nohibernate == 0 && !security_locked_down(LOCKDOWN_HIBERNATION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * hibernation_set_ops - Set the global hibernate operations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * @ops: Hibernation operations to use in subsequent hibernation transitions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) void hibernation_set_ops(const struct platform_hibernation_ops *ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) if (ops && !(ops->begin && ops->end && ops->pre_snapshot
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) && ops->prepare && ops->finish && ops->enter && ops->pre_restore
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) && ops->restore_cleanup && ops->leave)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) WARN_ON(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) lock_system_sleep();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) hibernation_ops = ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) if (ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) hibernation_mode = HIBERNATION_PLATFORM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) else if (hibernation_mode == HIBERNATION_PLATFORM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) hibernation_mode = HIBERNATION_SHUTDOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) unlock_system_sleep();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) EXPORT_SYMBOL_GPL(hibernation_set_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) static bool entering_platform_hibernation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) bool system_entering_hibernation(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) return entering_platform_hibernation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) EXPORT_SYMBOL(system_entering_hibernation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) #ifdef CONFIG_PM_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) static void hibernation_debug_sleep(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) pr_info("debug: Waiting for 5 seconds.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) mdelay(5000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) static int hibernation_test(int level)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) if (pm_test_level == level) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) hibernation_debug_sleep();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) #else /* !CONFIG_PM_DEBUG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) static int hibernation_test(int level) { return 0; }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) #endif /* !CONFIG_PM_DEBUG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) * platform_begin - Call platform to start hibernation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) * @platform_mode: Whether or not to use the platform driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) static int platform_begin(int platform_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) return (platform_mode && hibernation_ops) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) hibernation_ops->begin(PMSG_FREEZE) : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) * platform_end - Call platform to finish transition to the working state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) * @platform_mode: Whether or not to use the platform driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) static void platform_end(int platform_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) if (platform_mode && hibernation_ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) hibernation_ops->end();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) * platform_pre_snapshot - Call platform to prepare the machine for hibernation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) * @platform_mode: Whether or not to use the platform driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) * Use the platform driver to prepare the system for creating a hibernate image,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) * if so configured, and return an error code if that fails.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) static int platform_pre_snapshot(int platform_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) return (platform_mode && hibernation_ops) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) hibernation_ops->pre_snapshot() : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) * platform_leave - Call platform to prepare a transition to the working state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) * @platform_mode: Whether or not to use the platform driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) * Use the platform driver prepare to prepare the machine for switching to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) * normal mode of operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) * This routine is called on one CPU with interrupts disabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) static void platform_leave(int platform_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) if (platform_mode && hibernation_ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) hibernation_ops->leave();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) * platform_finish - Call platform to switch the system to the working state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) * @platform_mode: Whether or not to use the platform driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) * Use the platform driver to switch the machine to the normal mode of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) * operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) * This routine must be called after platform_prepare().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) static void platform_finish(int platform_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) if (platform_mode && hibernation_ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) hibernation_ops->finish();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) * platform_pre_restore - Prepare for hibernate image restoration.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) * @platform_mode: Whether or not to use the platform driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) * Use the platform driver to prepare the system for resume from a hibernation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) * image.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) * If the restore fails after this function has been called,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) * platform_restore_cleanup() must be called.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) static int platform_pre_restore(int platform_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) return (platform_mode && hibernation_ops) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) hibernation_ops->pre_restore() : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) * platform_restore_cleanup - Switch to the working state after failing restore.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) * @platform_mode: Whether or not to use the platform driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) * Use the platform driver to switch the system to the normal mode of operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) * after a failing restore.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) * If platform_pre_restore() has been called before the failing restore, this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) * function must be called too, regardless of the result of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) * platform_pre_restore().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) static void platform_restore_cleanup(int platform_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) if (platform_mode && hibernation_ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) hibernation_ops->restore_cleanup();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) * platform_recover - Recover from a failure to suspend devices.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) * @platform_mode: Whether or not to use the platform driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) static void platform_recover(int platform_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) if (platform_mode && hibernation_ops && hibernation_ops->recover)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) hibernation_ops->recover();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) * swsusp_show_speed - Print time elapsed between two events during hibernation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) * @start: Starting event.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) * @stop: Final event.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) * @nr_pages: Number of memory pages processed between @start and @stop.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) * @msg: Additional diagnostic message to print.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) void swsusp_show_speed(ktime_t start, ktime_t stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) unsigned nr_pages, char *msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) ktime_t diff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) u64 elapsed_centisecs64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) unsigned int centisecs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) unsigned int k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) unsigned int kps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) diff = ktime_sub(stop, start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) elapsed_centisecs64 = ktime_divns(diff, 10*NSEC_PER_MSEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) centisecs = elapsed_centisecs64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) if (centisecs == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) centisecs = 1; /* avoid div-by-zero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) k = nr_pages * (PAGE_SIZE / 1024);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) kps = (k * 100) / centisecs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) pr_info("%s %u kbytes in %u.%02u seconds (%u.%02u MB/s)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) msg, k, centisecs / 100, centisecs % 100, kps / 1000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) (kps % 1000) / 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) __weak int arch_resume_nosmt(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) * create_image - Create a hibernation image.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) * @platform_mode: Whether or not to use the platform driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) * Execute device drivers' "late" and "noirq" freeze callbacks, create a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) * hibernation image and run the drivers' "noirq" and "early" thaw callbacks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) * Control reappears in this routine after the subsequent restore.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) static int create_image(int platform_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) error = dpm_suspend_end(PMSG_FREEZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) pr_err("Some devices failed to power down, aborting\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) error = platform_pre_snapshot(platform_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) if (error || hibernation_test(TEST_PLATFORM))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) goto Platform_finish;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) error = suspend_disable_secondary_cpus();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) if (error || hibernation_test(TEST_CPUS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) goto Enable_cpus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) local_irq_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) system_state = SYSTEM_SUSPEND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) error = syscore_suspend();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) pr_err("Some system devices failed to power down, aborting\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) goto Enable_irqs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) if (hibernation_test(TEST_CORE) || pm_wakeup_pending())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) goto Power_up;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) in_suspend = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) save_processor_state();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) trace_suspend_resume(TPS("machine_suspend"), PM_EVENT_HIBERNATE, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) error = swsusp_arch_suspend();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) /* Restore control flow magically appears here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) restore_processor_state();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) trace_suspend_resume(TPS("machine_suspend"), PM_EVENT_HIBERNATE, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) pr_err("Error %d creating image\n", error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) if (!in_suspend) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) events_check_enabled = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) clear_or_poison_free_pages();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) platform_leave(platform_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) Power_up:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) syscore_resume();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) Enable_irqs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) system_state = SYSTEM_RUNNING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) local_irq_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) Enable_cpus:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) suspend_enable_secondary_cpus();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) /* Allow architectures to do nosmt-specific post-resume dances */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) if (!in_suspend)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) error = arch_resume_nosmt();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) Platform_finish:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) platform_finish(platform_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) dpm_resume_start(in_suspend ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) * hibernation_snapshot - Quiesce devices and create a hibernation image.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) * @platform_mode: If set, use platform driver to prepare for the transition.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) * This routine must be called with system_transition_mutex held.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) int hibernation_snapshot(int platform_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) pm_message_t msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) pm_suspend_clear_flags();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) error = platform_begin(platform_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) goto Close;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) /* Preallocate image memory before shutting down devices. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) error = hibernate_preallocate_memory();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) goto Close;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) error = freeze_kernel_threads();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) goto Cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) if (hibernation_test(TEST_FREEZER)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) * Indicate to the caller that we are returning due to a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) * successful freezer test.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) freezer_test_done = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) goto Thaw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) error = dpm_prepare(PMSG_FREEZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) dpm_complete(PMSG_RECOVER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) goto Thaw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) suspend_console();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) pm_restrict_gfp_mask();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) error = dpm_suspend(PMSG_FREEZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) if (error || hibernation_test(TEST_DEVICES))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) platform_recover(platform_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) error = create_image(platform_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) * In the case that we call create_image() above, the control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) * returns here (1) after the image has been created or the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) * image creation has failed and (2) after a successful restore.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) /* We may need to release the preallocated image pages here. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) if (error || !in_suspend)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) swsusp_free();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) msg = in_suspend ? (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) dpm_resume(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) if (error || !in_suspend)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) pm_restore_gfp_mask();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) resume_console();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) dpm_complete(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) Close:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) platform_end(platform_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) Thaw:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) thaw_kernel_threads();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) Cleanup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) swsusp_free();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) goto Close;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) int __weak hibernate_resume_nonboot_cpu_disable(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) return suspend_disable_secondary_cpus();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) * resume_target_kernel - Restore system state from a hibernation image.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) * @platform_mode: Whether or not to use the platform driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) * Execute device drivers' "noirq" and "late" freeze callbacks, restore the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) * contents of highmem that have not been restored yet from the image and run
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) * the low-level code that will restore the remaining contents of memory and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) * switch to the just restored target kernel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) static int resume_target_kernel(bool platform_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) error = dpm_suspend_end(PMSG_QUIESCE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) pr_err("Some devices failed to power down, aborting resume\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) error = platform_pre_restore(platform_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) goto Cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) error = hibernate_resume_nonboot_cpu_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) goto Enable_cpus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) local_irq_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) system_state = SYSTEM_SUSPEND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) error = syscore_suspend();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) goto Enable_irqs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) save_processor_state();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) error = restore_highmem();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) if (!error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) error = swsusp_arch_resume();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) * The code below is only ever reached in case of a failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) * Otherwise, execution continues at the place where
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) * swsusp_arch_suspend() was called.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) BUG_ON(!error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) * This call to restore_highmem() reverts the changes made by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) * the previous one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) restore_highmem();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) * The only reason why swsusp_arch_resume() can fail is memory being
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) * very tight, so we have to free it as soon as we can to avoid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) * subsequent failures.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) swsusp_free();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) restore_processor_state();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) touch_softlockup_watchdog();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) syscore_resume();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) Enable_irqs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) system_state = SYSTEM_RUNNING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) local_irq_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) Enable_cpus:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) suspend_enable_secondary_cpus();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) Cleanup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) platform_restore_cleanup(platform_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) dpm_resume_start(PMSG_RECOVER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) * hibernation_restore - Quiesce devices and restore from a hibernation image.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) * @platform_mode: If set, use platform driver to prepare for the transition.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) * This routine must be called with system_transition_mutex held. If it is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) * successful, control reappears in the restored target kernel in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) * hibernation_snapshot().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) int hibernation_restore(int platform_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) pm_prepare_console();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) suspend_console();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) pm_restrict_gfp_mask();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) error = dpm_suspend_start(PMSG_QUIESCE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) if (!error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) error = resume_target_kernel(platform_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) * The above should either succeed and jump to the new kernel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) * or return with an error. Otherwise things are just
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) * undefined, so let's be paranoid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) BUG_ON(!error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) dpm_resume_end(PMSG_RECOVER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) pm_restore_gfp_mask();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) resume_console();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) pm_restore_console();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) * hibernation_platform_enter - Power off the system using the platform driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) int hibernation_platform_enter(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) if (!hibernation_ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) return -ENOSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) * We have cancelled the power transition by running
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) * hibernation_ops->finish() before saving the image, so we should let
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) * the firmware know that we're going to enter the sleep state after all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) error = hibernation_ops->begin(PMSG_HIBERNATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) goto Close;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) entering_platform_hibernation = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) suspend_console();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) error = dpm_suspend_start(PMSG_HIBERNATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) if (hibernation_ops->recover)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) hibernation_ops->recover();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) goto Resume_devices;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) error = dpm_suspend_end(PMSG_HIBERNATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) goto Resume_devices;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) error = hibernation_ops->prepare();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) goto Platform_finish;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) error = suspend_disable_secondary_cpus();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) goto Enable_cpus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) local_irq_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) system_state = SYSTEM_SUSPEND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) syscore_suspend();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) if (pm_wakeup_pending()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) error = -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) goto Power_up;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) hibernation_ops->enter();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) /* We should never get here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) while (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) Power_up:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) syscore_resume();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) system_state = SYSTEM_RUNNING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) local_irq_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) Enable_cpus:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) suspend_enable_secondary_cpus();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) Platform_finish:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) hibernation_ops->finish();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) dpm_resume_start(PMSG_RESTORE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) Resume_devices:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) entering_platform_hibernation = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) dpm_resume_end(PMSG_RESTORE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) resume_console();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) Close:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) hibernation_ops->end();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) * power_down - Shut the machine down for hibernation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) * Use the platform driver, if configured, to put the system into the sleep
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) * state corresponding to hibernation, or try to power it off or reboot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) * depending on the value of hibernation_mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) static void power_down(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) #ifdef CONFIG_SUSPEND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) if (hibernation_mode == HIBERNATION_SUSPEND) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) error = suspend_devices_and_enter(PM_SUSPEND_MEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) hibernation_mode = hibernation_ops ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) HIBERNATION_PLATFORM :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) HIBERNATION_SHUTDOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) /* Restore swap signature. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) error = swsusp_unmark();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) pr_err("Swap will be unusable! Try swapon -a.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) switch (hibernation_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) case HIBERNATION_REBOOT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) kernel_restart(NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) case HIBERNATION_PLATFORM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) hibernation_platform_enter();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) case HIBERNATION_SHUTDOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) if (pm_power_off)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) kernel_power_off();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) kernel_halt();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) * Valid image is on the disk, if we continue we risk serious data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) * corruption after resume.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) pr_crit("Power down manually\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) while (1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) static int load_image_and_restore(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) unsigned int flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) pm_pr_dbg("Loading hibernation image.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) lock_device_hotplug();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) error = create_basic_memory_bitmaps();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) goto Unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) error = swsusp_read(&flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) swsusp_close(FMODE_READ | FMODE_EXCL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) if (!error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) error = hibernation_restore(flags & SF_PLATFORM_MODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) pr_err("Failed to load image, recovering.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) swsusp_free();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) free_basic_memory_bitmaps();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) Unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) unlock_device_hotplug();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) * hibernate - Carry out system hibernation, including saving the image.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) int hibernate(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) bool snapshot_test = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) if (!hibernation_available()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) pm_pr_dbg("Hibernation not available.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) lock_system_sleep();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) /* The snapshot device should not be opened while we're running */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) if (!hibernate_acquire()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) error = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) goto Unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) pr_info("hibernation entry\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) pm_prepare_console();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) error = pm_notifier_call_chain_robust(PM_HIBERNATION_PREPARE, PM_POST_HIBERNATION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) goto Restore;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) ksys_sync_helper();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) error = freeze_processes();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) goto Exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) lock_device_hotplug();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) /* Allocate memory management structures */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) error = create_basic_memory_bitmaps();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) goto Thaw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) error = hibernation_snapshot(hibernation_mode == HIBERNATION_PLATFORM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) if (error || freezer_test_done)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) goto Free_bitmaps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) if (in_suspend) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) unsigned int flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) if (hibernation_mode == HIBERNATION_PLATFORM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) flags |= SF_PLATFORM_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) if (nocompress)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) flags |= SF_NOCOMPRESS_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) flags |= SF_CRC32_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) pm_pr_dbg("Writing hibernation image.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) error = swsusp_write(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) swsusp_free();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) if (!error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) if (hibernation_mode == HIBERNATION_TEST_RESUME)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) snapshot_test = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) power_down();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) in_suspend = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) pm_restore_gfp_mask();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) pm_pr_dbg("Hibernation image restored successfully.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) Free_bitmaps:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) free_basic_memory_bitmaps();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) Thaw:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) unlock_device_hotplug();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) if (snapshot_test) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) pm_pr_dbg("Checking hibernation image\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) error = swsusp_check();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) if (!error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) error = load_image_and_restore();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) thaw_processes();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) /* Don't bother checking whether freezer_test_done is true */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) freezer_test_done = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) Exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) pm_notifier_call_chain(PM_POST_HIBERNATION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) Restore:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) pm_restore_console();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) hibernate_release();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) Unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) unlock_system_sleep();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) pr_info("hibernation exit\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) * hibernate_quiet_exec - Execute a function with all devices frozen.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) * @func: Function to execute.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) * @data: Data pointer to pass to @func.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) * Return the @func return value or an error code if it cannot be executed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) int hibernate_quiet_exec(int (*func)(void *data), void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) lock_system_sleep();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) if (!hibernate_acquire()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) error = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) pm_prepare_console();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) error = pm_notifier_call_chain_robust(PM_HIBERNATION_PREPARE, PM_POST_HIBERNATION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) goto restore;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) error = freeze_processes();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) lock_device_hotplug();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) pm_suspend_clear_flags();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) error = platform_begin(true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) goto thaw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) error = freeze_kernel_threads();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) goto thaw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) error = dpm_prepare(PMSG_FREEZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) goto dpm_complete;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) suspend_console();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) error = dpm_suspend(PMSG_FREEZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) goto dpm_resume;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) error = dpm_suspend_end(PMSG_FREEZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) goto dpm_resume;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) error = platform_pre_snapshot(true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) goto skip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) error = func(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) skip:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) platform_finish(true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) dpm_resume_start(PMSG_THAW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) dpm_resume:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) dpm_resume(PMSG_THAW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) resume_console();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) dpm_complete:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) dpm_complete(PMSG_THAW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) thaw_kernel_threads();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) thaw:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) platform_end(true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) unlock_device_hotplug();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) thaw_processes();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) pm_notifier_call_chain(PM_POST_HIBERNATION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) restore:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) pm_restore_console();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) hibernate_release();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) unlock_system_sleep();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) EXPORT_SYMBOL_GPL(hibernate_quiet_exec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) * software_resume - Resume from a saved hibernation image.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) * This routine is called as a late initcall, when all devices have been
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) * discovered and initialized already.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) * The image reading code is called to see if there is a hibernation image
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) * available for reading. If that is the case, devices are quiesced and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) * contents of memory is restored from the saved image.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) * If this is successful, control reappears in the restored target kernel in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) * hibernation_snapshot() which returns to hibernate(). Otherwise, the routine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) * attempts to recover gracefully and make the kernel return to the normal mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) * of operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) static int software_resume(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) * If the user said "noresume".. bail out early.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) if (noresume || !hibernation_available())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) * name_to_dev_t() below takes a sysfs buffer mutex when sysfs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) * is configured into the kernel. Since the regular hibernate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) * trigger path is via sysfs which takes a buffer mutex before
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) * calling hibernate functions (which take system_transition_mutex)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) * this can cause lockdep to complain about a possible ABBA deadlock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) * which cannot happen since we're in the boot code here and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) * sysfs can't be invoked yet. Therefore, we use a subclass
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) * here to avoid lockdep complaining.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) mutex_lock_nested(&system_transition_mutex, SINGLE_DEPTH_NESTING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) if (swsusp_resume_device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) goto Check_image;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) if (!strlen(resume_file)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) error = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) goto Unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) pm_pr_dbg("Checking hibernation image partition %s\n", resume_file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) if (resume_delay) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) pr_info("Waiting %dsec before reading resume device ...\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) resume_delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) ssleep(resume_delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) /* Check if the device is there */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) swsusp_resume_device = name_to_dev_t(resume_file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) if (!swsusp_resume_device) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) * Some device discovery might still be in progress; we need
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) * to wait for this to finish.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) wait_for_device_probe();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) if (resume_wait) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) while ((swsusp_resume_device = name_to_dev_t(resume_file)) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) msleep(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) async_synchronize_full();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) swsusp_resume_device = name_to_dev_t(resume_file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) if (!swsusp_resume_device) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) error = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) goto Unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) Check_image:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) pm_pr_dbg("Hibernation image partition %d:%d present\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) MAJOR(swsusp_resume_device), MINOR(swsusp_resume_device));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) pm_pr_dbg("Looking for hibernation image.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) error = swsusp_check();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) goto Unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) /* The snapshot device should not be opened while we're running */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) if (!hibernate_acquire()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) error = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) swsusp_close(FMODE_READ | FMODE_EXCL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) goto Unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) pr_info("resume from hibernation\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) pm_prepare_console();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) error = pm_notifier_call_chain_robust(PM_RESTORE_PREPARE, PM_POST_RESTORE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) goto Restore;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) pm_pr_dbg("Preparing processes for hibernation restore.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) error = freeze_processes();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) goto Close_Finish;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) error = freeze_kernel_threads();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) thaw_processes();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) goto Close_Finish;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) error = load_image_and_restore();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) thaw_processes();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) Finish:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) pm_notifier_call_chain(PM_POST_RESTORE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) Restore:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) pm_restore_console();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) pr_info("resume failed (%d)\n", error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) hibernate_release();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) /* For success case, the suspend path will release the lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) Unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) mutex_unlock(&system_transition_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) pm_pr_dbg("Hibernation image not present or could not be loaded.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) Close_Finish:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) swsusp_close(FMODE_READ | FMODE_EXCL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) goto Finish;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) late_initcall_sync(software_resume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) static const char * const hibernation_modes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) [HIBERNATION_PLATFORM] = "platform",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) [HIBERNATION_SHUTDOWN] = "shutdown",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) [HIBERNATION_REBOOT] = "reboot",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) #ifdef CONFIG_SUSPEND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) [HIBERNATION_SUSPEND] = "suspend",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) [HIBERNATION_TEST_RESUME] = "test_resume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) * /sys/power/disk - Control hibernation mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) * Hibernation can be handled in several ways. There are a few different ways
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) * to put the system into the sleep state: using the platform driver (e.g. ACPI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) * or other hibernation_ops), powering it off or rebooting it (for testing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) * mostly).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) * The sysfs file /sys/power/disk provides an interface for selecting the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) * hibernation mode to use. Reading from this file causes the available modes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) * to be printed. There are 3 modes that can be supported:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) * 'platform'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) * 'shutdown'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) * 'reboot'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) * If a platform hibernation driver is in use, 'platform' will be supported
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) * and will be used by default. Otherwise, 'shutdown' will be used by default.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) * The selected option (i.e. the one corresponding to the current value of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) * hibernation_mode) is enclosed by a square bracket.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) * To select a given hibernation mode it is necessary to write the mode's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) * string representation (as returned by reading from /sys/power/disk) back
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) * into /sys/power/disk.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) static ssize_t disk_show(struct kobject *kobj, struct kobj_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) char *start = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) if (!hibernation_available())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) return sprintf(buf, "[disabled]\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) for (i = HIBERNATION_FIRST; i <= HIBERNATION_MAX; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) if (!hibernation_modes[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) switch (i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) case HIBERNATION_SHUTDOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) case HIBERNATION_REBOOT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) #ifdef CONFIG_SUSPEND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) case HIBERNATION_SUSPEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) case HIBERNATION_TEST_RESUME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) case HIBERNATION_PLATFORM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) if (hibernation_ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) /* not a valid mode, continue with loop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) if (i == hibernation_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) buf += sprintf(buf, "[%s] ", hibernation_modes[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) buf += sprintf(buf, "%s ", hibernation_modes[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) buf += sprintf(buf, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) return buf-start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) static ssize_t disk_store(struct kobject *kobj, struct kobj_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) const char *buf, size_t n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) int error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) char *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) int mode = HIBERNATION_INVALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) if (!hibernation_available())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) p = memchr(buf, '\n', n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) len = p ? p - buf : n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) lock_system_sleep();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) for (i = HIBERNATION_FIRST; i <= HIBERNATION_MAX; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) if (len == strlen(hibernation_modes[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) && !strncmp(buf, hibernation_modes[i], len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) mode = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) if (mode != HIBERNATION_INVALID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) switch (mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) case HIBERNATION_SHUTDOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) case HIBERNATION_REBOOT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) #ifdef CONFIG_SUSPEND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) case HIBERNATION_SUSPEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) case HIBERNATION_TEST_RESUME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) hibernation_mode = mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) case HIBERNATION_PLATFORM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) if (hibernation_ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) hibernation_mode = mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) error = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) error = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) if (!error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) pm_pr_dbg("Hibernation mode set to '%s'\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) hibernation_modes[mode]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) unlock_system_sleep();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) return error ? error : n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) power_attr(disk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) static ssize_t resume_show(struct kobject *kobj, struct kobj_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) return sprintf(buf, "%d:%d\n", MAJOR(swsusp_resume_device),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) MINOR(swsusp_resume_device));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) static ssize_t resume_store(struct kobject *kobj, struct kobj_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) const char *buf, size_t n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) dev_t res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) int len = n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) if (len && buf[len-1] == '\n')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) len--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) name = kstrndup(buf, len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) if (!name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) res = name_to_dev_t(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) kfree(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) if (!res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) lock_system_sleep();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) swsusp_resume_device = res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) unlock_system_sleep();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) pm_pr_dbg("Configured hibernation resume from disk to %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) swsusp_resume_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) noresume = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) software_resume();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) return n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) power_attr(resume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) static ssize_t resume_offset_show(struct kobject *kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) struct kobj_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) return sprintf(buf, "%llu\n", (unsigned long long)swsusp_resume_block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) static ssize_t resume_offset_store(struct kobject *kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) struct kobj_attribute *attr, const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) size_t n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) unsigned long long offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) rc = kstrtoull(buf, 0, &offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) swsusp_resume_block = offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) return n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) power_attr(resume_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) static ssize_t image_size_show(struct kobject *kobj, struct kobj_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) return sprintf(buf, "%lu\n", image_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) static ssize_t image_size_store(struct kobject *kobj, struct kobj_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) const char *buf, size_t n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) unsigned long size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) if (sscanf(buf, "%lu", &size) == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) image_size = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) return n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) power_attr(image_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) static ssize_t reserved_size_show(struct kobject *kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) struct kobj_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) return sprintf(buf, "%lu\n", reserved_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) static ssize_t reserved_size_store(struct kobject *kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) struct kobj_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) const char *buf, size_t n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) unsigned long size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) if (sscanf(buf, "%lu", &size) == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) reserved_size = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) return n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) power_attr(reserved_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) static struct attribute *g[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) &disk_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) &resume_offset_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) &resume_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) &image_size_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) &reserved_size_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) static const struct attribute_group attr_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) .attrs = g,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) static int __init pm_disk_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) return sysfs_create_group(power_kobj, &attr_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) core_initcall(pm_disk_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) static int __init resume_setup(char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) if (noresume)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) strncpy(resume_file, str, 255);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) static int __init resume_offset_setup(char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) unsigned long long offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) if (noresume)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) if (sscanf(str, "%llu", &offset) == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) swsusp_resume_block = offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) static int __init hibernate_setup(char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) if (!strncmp(str, "noresume", 8)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) noresume = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) } else if (!strncmp(str, "nocompress", 10)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) nocompress = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) } else if (!strncmp(str, "no", 2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) noresume = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) nohibernate = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) } else if (IS_ENABLED(CONFIG_STRICT_KERNEL_RWX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) && !strncmp(str, "protect_image", 13)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) enable_restore_image_protection();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) static int __init noresume_setup(char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) noresume = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) static int __init resumewait_setup(char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) resume_wait = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) static int __init resumedelay_setup(char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) int rc = kstrtouint(str, 0, &resume_delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) pr_warn("resumedelay: bad option string '%s'\n", str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) static int __init nohibernate_setup(char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) noresume = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) nohibernate = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) __setup("noresume", noresume_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) __setup("resume_offset=", resume_offset_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) __setup("resume=", resume_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) __setup("hibernate=", hibernate_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) __setup("resumewait", resumewait_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) __setup("resumedelay=", resumedelay_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) __setup("nohibernate", nohibernate_setup);